All Downloads are FREE. Search and download functionalities are using the official Maven repository.

xdev.ui.XdevIntelliHints Maven / Gradle / Ivy

There is a newer version: 6.0.2
Show newest version
package xdev.ui;

/*-
 * #%L
 * XDEV Component Suite
 * %%
 * Copyright (C) 2011 - 2021 XDEV Software
 * %%
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of the
 * License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public
 * License along with this program.  If not, see
 * .
 * #L%
 */


import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.JTextComponent;

import xdev.util.StringUtils;
import xdev.util.logging.LoggerFactory;
import xdev.util.logging.XdevLogger;
import xdev.vt.VirtualTable;
import xdev.vt.VirtualTableColumn;
import xdev.vt.VirtualTableEvent;
import xdev.vt.VirtualTableListener;

import com.jidesoft.hints.ListDataIntelliHints;


/**
 * XdevIntelliHint can be used as an decorator on other components.
 * 

* It enhances the functionality of the decorated component by displaying a * popup dialog with a list of hints for the currently typed text. The list gets * automatically updated while the user types. *

* * @author XDEV Software * */ public class XdevIntelliHints extends ListDataIntelliHints { /** * Logger instance for this class. */ private static final XdevLogger log = LoggerFactory .getLogger(XdevIntelliHints.class); /** * The default number of visible entries in the hints popup. */ private static final int DEFAULT_NR_OF_HINT_ENTRIES = 3; /** * The default key stroke to display the hints popup (Ctrl + Space). */ private static final KeyStroke DEFAULT_HINT_KEYSTROKE = KeyStroke.getKeyStroke( KeyEvent.VK_SPACE, KeyEvent.CTRL_MASK); /** * the {@link VirtualTable} used to fill the hints popup. */ private VirtualTable hintsTable; /** * A {@link VirtualTableListener} used to sync changes the * {@link XdevIntelliHints} with changes on the model. */ private VirtualTableListener hintsTableListener; /** * the currently visible number of rows in the hints popup. */ private int visibleRowCount = DEFAULT_NR_OF_HINT_ENTRIES; /** * the {@link JTextComponent} that is connected to this instance. */ private JTextComponent textComponent; /** * Initializes a new instance of {@link XdevIntelliHints}. * * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsList * an List of Objects containing the hints * */ public XdevIntelliHints(JTextComponent comp, List hintsList) { super(comp,hintsList); this.textComponent = comp; this.setFollowCaret(false); this.setShowHintsKeyStroke(DEFAULT_HINT_KEYSTROKE); } /** * Initializes a new instance of {@link XdevIntelliHints}. * * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsArray * an Array of objects containing the hints */ public XdevIntelliHints(JTextComponent comp, String[] hintsArray) { super(comp,hintsArray); this.textComponent = comp; this.setFollowCaret(false); this.setShowHintsKeyStroke(DEFAULT_HINT_KEYSTROKE); } /** * Initializes a new instance of {@link XdevIntelliHints}. *

* The values of this {@code hintsColumn} get automatically converted to * type String. *

* * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsTable * a {@link VirtualTable} of which a column should be used for * hints * @param hintsColumnIndex * the index of the column to use for the hints */ public XdevIntelliHints(JTextComponent comp, VirtualTable hintsTable, int hintsColumnIndex) { this(comp,hintsTable,hintsColumnIndex,false); } /** * Initializes a new instance of {@link XdevIntelliHints}. *

* The values of this {@code hintsColumn} get automatically converted to * type String. *

* * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsTable * a {@link VirtualTable} of which a column should be used for * hints * @param hintsColumnIndex * the index of the column to use for the hints * @param queryData * if {@code true} a query on the {@code hintsTable} gets * performed. */ public XdevIntelliHints(JTextComponent comp, VirtualTable hintsTable, int hintsColumnIndex, boolean queryData) { this(comp,hintsTable,hintsTable.getColumnAt(hintsColumnIndex).getName(),queryData); } /** * Initializes a new instance of {@link XdevIntelliHints}. *

* The values of the specified {@code hintsColumn} get automatically * converted to type String. *

* * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsColumn * a {@link VirtualTableColumn} containing the hints */ @SuppressWarnings({"unchecked"}) public XdevIntelliHints(JTextComponent comp, final VirtualTableColumn hintsColumn) { this(comp,hintsColumn,false); } /** * Initializes a new instance of {@link XdevIntelliHints}. *

* The values of the specified {@code hintsColumn} get automatically * converted to type String. *

* * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsColumn * a {@link VirtualTableColumn} containing the hints * @param queryData * if {@code true} a query on the {@code hintsTable} gets * performed. */ @SuppressWarnings({"unchecked"}) public XdevIntelliHints(JTextComponent comp, final VirtualTableColumn hintsColumn, boolean queryData) { this(comp,hintsColumn.getVirtualTable(),hintsColumn.getName(),queryData); } /** * Initializes a new instance of {@link XdevIntelliHints}. *

* The values of the specified hintsColumn} get automatically converted to * type String. *

* * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsTable * a {@link VirtualTable} of which a column should be used for * hints * @param columns * the columns to use for the hints, for format description see * {@link StringUtils#format(String, xdev.util.StringUtils.ParameterProvider)} */ public XdevIntelliHints(JTextComponent comp, final VirtualTable hintsTable, final String columns) { this(comp,hintsTable,columns,false); } /** * Initializes a new instance of {@link XdevIntelliHints}. *

* The values of the specified hintsColumn} get automatically converted to * type String. *

* * @param comp * the {@link JTextComponent} to be decorated with this * {@link XdevIntelliHints} * @param hintsTable * a {@link VirtualTable} of which a column should be used for * hints * @param columns * the columns to use for the hints, for format description see * {@link StringUtils#format(String, xdev.util.StringUtils.ParameterProvider)} * @param queryData * if {@code true} a query on the {@code hintsTable} gets * performed. */ public XdevIntelliHints(JTextComponent comp, final VirtualTable hintsTable, final String columns, boolean queryData) { super(comp,new String[0]); if(hintsTable != null) { this.textComponent = comp; if(queryData) { try { hintsTable.queryAndFill(); } catch(Exception e) { log.error(e); } } setCompletionList(hintsTable,columns); this.hintsTable = hintsTable; this.hintsTableListener = new VirtualTableListener() { @Override public void virtualTableDataChanged(VirtualTableEvent event) { sync(); } @Override public void virtualTableRowDeleted(VirtualTableEvent event) { sync(); } @Override public void virtualTableRowInserted(VirtualTableEvent event) { sync(); } @Override public void virtualTableRowUpdated(VirtualTableEvent event) { sync(); } @Override public void virtualTableStructureChanged(VirtualTableEvent event) { sync(); } void sync() { setCompletionList(hintsTable,columns); } }; hintsTable.addVirtualTableListener(hintsTableListener); this.setShowHintsKeyStroke(DEFAULT_HINT_KEYSTROKE); } } /** * Sets a custom KeyStroke to be used for showing the hints popup. * * @param keyStroke * a {@link KeyStroke} * @see XdevIntelliHints#DEFAULT_HINT_KEYSTROKE */ public void setShowHintsKeyStroke(KeyStroke keyStroke) { KeyStroke[] all = getAllShowHintsKeyStrokes(); if(all != null) { for(KeyStroke ks : all) { removeShowHintsKeyStroke(ks); } } addShowHintsKeyStroke(keyStroke); } /** * Sets the hints of this {@link XdevIntelliHints}. *

* The values of the specified {@code hintsColumn} get automatically * converted to type String. *

* * @param hintsColumn * a {@link VirtualTableColumn} containing the hints */ @SuppressWarnings({"rawtypes"}) public void setCompletionList(VirtualTableColumn hintsColumn) { this.setCompletionList(hintsColumn.getVirtualTable(),hintsColumn.getName()); } /** * Sets the hints of this {@link XdevIntelliHints}. * * @param hintsTable * a {@link VirtualTable} of which a column should be used for * hints * @param hintsColumnIndex * the index of the column to use for the hints */ public void setCompletionList(VirtualTable hintsTable, int hintsColumnIndex) { this.setCompletionList(hintsTable,hintsTable.getColumnAt(hintsColumnIndex).getName()); } /** * Sets the hints of this {@link XdevIntelliHints}. * * @param hintsTable * a {@link VirtualTable} of which a column should be used for * hints * @param columns * the columns to use for the hints, for format description see * {@link StringUtils#format(String, xdev.util.StringUtils.ParameterProvider)} */ public void setCompletionList(VirtualTable hintsTable, String columns) { super.setCompletionList(getHints(hintsTable,columns)); } /** * Sorts the underlying hint list, if possible. */ public void sortCompletionList() { try { Collections.sort(this.getCompletionList()); } catch(Exception e) { // fail silently, if sorting is not possible, e.g. because of // unmodifiable list } } /** * Returns a {@code List} of {@code Strings} for the values of all rows of a * specified column. * * @param vt * a {@link VirtualTable} to get the values from * @param column * the column name * @return a {@code List} of {@code Strings} */ private static List getHints(VirtualTable vt, String column) { Set hints = new LinkedHashSet(); int columnIndex = vt.getColumnIndex(column); int rowCount = vt.getRowCount(); for(int row = 0; row < rowCount; row++) { if(columnIndex >= 0) { hints.add(vt.getFormattedValueAt(row,columnIndex)); } else { hints.add(vt.format(row,column)); } } return new ArrayList(hints); } /** * {@inheritDoc} */ @Override protected Rectangle getCaretRectangleForPopup(int caretPosition) throws BadLocationException { Rectangle r = super.getCaretRectangleForPopup(caretPosition); // align the x coordinate of the hints popup with the text component r.x = 0; return r; } /** * {@inheritDoc} */ @Override public JComponent createHintsComponent() { JComponent hintsComponent = super.createHintsComponent(); // Customize hints component to have the same width as the related // textfield and have configurable nr of entries (#11992) getList().setVisibleRowCount(visibleRowCount); @SuppressWarnings("serial") JPanel pnl = new JPanel(new BorderLayout()) { @Override public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); d.width = Math.max(d.width,textComponent.getWidth() - 2); return d; } }; pnl.add(hintsComponent,BorderLayout.CENTER); return pnl; } /** * @return the count of concurrently visual entries in the hints popup */ public int getVisibleRowCount() { return visibleRowCount; } /** * Sets the number of concurrently visible entries in the hints popup. * * @param visibleRowCount * an int value */ public void setVisibleRowCount(int visibleRowCount) { this.visibleRowCount = visibleRowCount; } /** * {@inheritDoc} */ @Override protected void finalize() throws Throwable { if(hintsTable != null && hintsTableListener != null) { hintsTable.removeVirtualTableListener(hintsTableListener); } super.finalize(); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy