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

org.openbp.swing.components.popupfield.JSelectionField Maven / Gradle / Ivy

/*
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package org.openbp.swing.components.popupfield;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.swing.JTextField;

import org.openbp.common.CommonUtil;
import org.openbp.common.util.iterator.EmptyIterator;
import org.openbp.swing.components.treetable.JTreeTable;

/**
 * Selection field component.
 * This component works similar to a JComboBox.
 * However, it's ui is a little different and it has much less overhead than
 * the JComboBox (well, it doesn't support all that model and ui stuff the combo box does).
 * In contrast to the JComboBox, it can also be used as cell component of a {@link JTreeTable}
 * (well, the reason why a JComboBox doesn't work - the focus gets lost when leaving the combo
 * box, also the selection of the first item does not always work - is undetermined).
 *
 * The selection box support localization in that way that it's item list
 * may optionally contain a display name beside the actual item value.
 *
 * Same as the combo box, the selection field can be editable (which allows text input by
 * the user) or a simple list selection field (which provides the values in the item list
 * only).
 *
 * @author Heiko Erhardt
 */
public class JSelectionField extends JPopupField
{
	/** Item list (contains objects) */
	private List itemList;

	/** Maximum row count to display in the popup */
	private int maximumRowCount = 10;

	/** Status flag: Popup closed */
	// private boolean popupClosed;

	/** Popup menu containing the selection list */
	protected JSelectionPopup popup;

	/**
	 * Default constructor.
	 */
	public JSelectionField()
	{
		super();

		add(textField, BorderLayout.CENTER);
	}

	/**
	 * Creates the text field.
	 */
	protected JTextField createTextField()
	{
		JTextField tf = super.createTextField();

		tf.addMouseListener(new SelectionMouseListener());

		return tf;
	}

	/**
	 * Adjusts the preferred size of the selection text field according to the length of the selection list texts.
	 */
	public void adjustPreferredSize()
	{
		int n = getNumberOfItems();
		if (n > 0)
		{
			Dimension size = textField.getMinimumSize();
			int max = size.width;

			Font font = getFont();
			FontMetrics fm = getFontMetrics(font);

			for (int i = 0; i < n; ++i)
			{
				Object o = itemList.get(i);
				String s = o != null ? o.toString() : null;
				if (s != null)
				{
					int w = fm.stringWidth(s);
					if (w > max)
						max = w;
				}
			}

			Dimension prefSize = arrowButton.getPreferredSize();
			max += prefSize.width;
			if (label != null)
			{
				prefSize = label.getPreferredSize();
				max += prefSize.width;
			}
			max += 8;

			size = getMaximumSize();
			size.width = max;
			setMaximumSize(size);
		}
	}

	//////////////////////////////////////////////////
	// @@ JComponent overrides
	//////////////////////////////////////////////////

	/**
	 * Selects an item using a key character.
	 * This will select the next item that starts with the given character from the item list,
	 * wrapping around if the item cannot be found from the current position downwards.
	 *
	 * @param selectionChar Selection character
	 * @return
	 *		true	An item was selected.
* false No item was found that begins with the specified character. */ protected boolean selectWithKeyChar(char selectionChar) { int n = getNumberOfItems(); if (n == 0) return false; int index = getSelectedIndex(); // Start from current position for (int i = index + 1; i < n; ++i) { Object o = itemList.get(i); String s = o != null ? o.toString() : null; if (s != null && s.length() > 0) { char c = Character.toLowerCase(s.charAt(0)); if (c == selectionChar) { setSelectedIndex(i); fireActionPerformed(); return true; } } } // Wrap around for (int i = 0; i < index; ++i) { Object o = itemList.get(i); String s = o != null ? o.toString() : null; if (s != null && s.length() > 0) { char c = Character.toLowerCase(s.charAt(0)); if (c == selectionChar) { setSelectedIndex(i); fireActionPerformed(); return true; } } } return false; } ////////////////////////////////////////////////// // @@ Popup operations ////////////////////////////////////////////////// /** * Gets the popup visibility. * @return * true The popup is shown.
* false The popup is hidden. */ public boolean isPopupVisible() { return popup != null && popup.isVisible(); } /** * Sets the popup visibility. * @param popupVisible * true Shows the popup.
* false Hides the popup. */ public void setPopupVisible(boolean popupVisible) { if (popupVisible) { if (popup == null) { popup = new JSelectionPopup(this); } // popupClosed = false; popup.showPopup(); } else { if (popup != null) { popup.hidePopup(); } } } void notifyPopupClosed() { // popupClosed = true; } ////////////////////////////////////////////////// // @@ Selection/text access ////////////////////////////////////////////////// /** * Gets the selected item. * @return The selected item or null if no item of the item list has been selected. * In the latter case, use the getText method to retrieve the text the user has entered in * the selection field if the selection field is editable. */ public Object getSelectedItem() { if (itemList != null) { String text = getText(); if (text != null) { // Check if the field text matches the display text of an item in the list int n = itemList.size(); for (int i = 0; i < n; ++i) { Object o = itemList.get(i); if (o == null) continue; String s = o.toString(); if (CommonUtil.equalsNull(s, text)) { if (o instanceof DisplayableObject) { // Return the associated item return ((DisplayableObject) o).getItem(); } // Return the object itself as item return o; } } } } return null; } /** * Sets the selected item. * @param selectedItem Item to select.
* The item must have been added to the field using the {@link #addItem(Object)} method. */ public void setSelectedItem(Object selectedItem) { if (itemList != null) { // Check if the field text matches the display text of an item in the list int n = itemList.size(); for (int i = 0; i < n; ++i) { Object o = itemList.get(i); if (o instanceof DisplayableObject) { // Return the associated item DisplayableObject dobj = (DisplayableObject) o; if (CommonUtil.equalsNull(selectedItem, dobj.getItem())) { setText(dobj.toString()); return; } } } } setText(selectedItem != null ? selectedItem.toString() : null); } /** * Gets the index of the selected item in the item list. * @return The index or -1 if no item of the item list is currently selected */ public int getSelectedIndex() { if (itemList != null) { String text = getText(); // Check if the field text matches the display text of an item in the list int n = itemList.size(); for (int i = 0; i < n; ++i) { Object o = itemList.get(i); String s = o != null ? o.toString() : null; if (CommonUtil.equalsNull(s, text)) { return i; } } } return -1; } /** * Sets the index of the selected item in the item list. * @param selectedIndex The index or -1 to clear the selection field */ public void setSelectedIndex(int selectedIndex) { if (selectedIndex < 0 || selectedIndex >= getNumberOfItems()) { setText(null); return; } Object o = itemList.get(selectedIndex); setText(o != null ? o.toString() : null); } ////////////////////////////////////////////////// // @@ Item list access ////////////////////////////////////////////////// /** * Gets the item list. * @return An iterator of objects */ public Iterator getItems() { if (itemList == null) return EmptyIterator.getInstance(); return itemList.iterator(); } /** * Gets the number of items. * @return The number of items in the collection */ public int getNumberOfItems() { return itemList != null ? itemList.size() : 0; } /** * Gets an item by its collection index. * * @param index Collection index (must be in the range [0..{@link #getNumberOfItems}] * @return The item */ public String getItemTextAt(int index) { Object o = itemList.get(index); return o != null ? o.toString() : null; } /** * Gets an item by its collection index. * * @param index Collection index (must be in the range [0..{@link #getNumberOfItems}] * @return The item */ public Object getItemAt(int index) { return itemList.get(index); } /** * Adds an item. * @param item The item to add */ public void addItem(Object item) { if (item != null && item.equals("")) item = null; if (itemList == null) itemList = new ArrayList(); itemList.add(item); } /** * Adds an item. * Constructs a helper object that holds the item and the text and adds * it to the item list. * @param text Text to display for the item * @param item The item to add */ public void addItem(String text, Object item) { if (text != null && text.equals("")) text = null; if (item != null && item.equals("")) item = null; if (itemList == null) itemList = new ArrayList(); itemList.add(new DisplayableObject(text, item)); } /** * Clears the item list. */ public void clearItems() { itemList = null; } /** * Gets the item list. * @return A list of objects */ public List getItemList() { return itemList; } /** * Sets the item list. * @param itemList A list of objects */ public void setItemList(List itemList) { this.itemList = itemList; } ////////////////////////////////////////////////// // @@ Property access ////////////////////////////////////////////////// /** * Gets the maximum row count to display in the popup. * @return The row count (default: 10) */ public int getMaximumRowCount() { return maximumRowCount; } /** * Sets the maximum row count to display in the popup. */ public void setMaximumRowCount(int maximumRowCount) { this.maximumRowCount = maximumRowCount; } ////////////////////////////////////////////////// // @@ Helper classes ////////////////////////////////////////////////// /** * This class holds an arbitrary object (i\.e\. the item) and a display name that should * be displayed in the selection field for this item. */ private static class DisplayableObject { /** Item held by the object */ private Object item; /** Text to display for the item */ private String text; /** * Constructor. * * @param text Text to display for the item * @param item Item held by the object */ public DisplayableObject(String text, Object item) { this.text = text; this.item = item; } /** * Gets a string representation of this object. * * @return The text */ public String toString() { return text; } /** * Gets the item held by the object. */ public Object getItem() { return item; } } /** * Mouse listener for the selection field. */ private class SelectionMouseListener extends MouseAdapter { /** * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) */ public void mouseClicked(MouseEvent e) { // Show the popup immediately on click if the field is not editable if (!isPopupVisible()) { if (!isEditable() && isEnabled()) { showPopup(); } /* if (! isEditable () && ! popupClosed) { showPopup (); } */ // popupClosed = false; } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy