aboutsummaryrefslogtreecommitdiff
path: root/libjava/javax/swing/JComboBox.java
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/javax/swing/JComboBox.java')
-rw-r--r--libjava/javax/swing/JComboBox.java247
1 files changed, 145 insertions, 102 deletions
diff --git a/libjava/javax/swing/JComboBox.java b/libjava/javax/swing/JComboBox.java
index 86f20b099eb..4e2a88110fc 100644
--- a/libjava/javax/swing/JComboBox.java
+++ b/libjava/javax/swing/JComboBox.java
@@ -1,5 +1,5 @@
/* JComboBox.java --
- Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -60,7 +60,6 @@ import javax.swing.event.ListDataListener;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.ComboBoxUI;
-
/**
* JComboBox. JComboBox is a container, that keeps track of elements added to
* it by the user. JComboBox allows user to select any item in its list and
@@ -69,12 +68,14 @@ import javax.swing.plaf.ComboBoxUI;
*
* @author Andrew Selkirk
* @author Olga Rodimina
+ * @author Robert Schuster
*/
public class JComboBox extends JComponent implements ItemSelectable,
ListDataListener,
ActionListener,
Accessible
{
+
private static final long serialVersionUID = 5654585963292734470L;
/**
@@ -91,43 +92,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
* Maximum number of rows that should be visible by default in the
* JComboBox's popup
*/
- public static final int DEFAULT_MAXIMUM_ROW_COUNT = 8;
-
- /**
- * Fired in a PropertyChangeEvent when the 'editable' property changes.
- */
- public static final String EDITABLE_CHANGED_PROPERTY = "editable";
-
- /**
- * Fired in a PropertyChangeEvent when the 'maximumRowCount' property
- * changes.
- */
- public static final String MAXIMUM_ROW_COUNT_CHANGED_PROPERTY = "maximumRowCount";
-
- /**
- * Fired in a PropertyChangeEvent when the 'enabled' property changes.
- */
- public static final String ENABLED_CHANGED_PROPERTY = "enabled";
-
- /**
- * Fired in a PropertyChangeEvent when the 'renderer' property changes.
- */
- public static final String RENDERER_CHANGED_PROPERTY = "renderer";
-
- /**
- * Fired in a PropertyChangeEvent when the 'editor' property changes.
- */
- public static final String EDITOR_CHANGED_PROPERTY = "editor";
-
- /**
- * Fired in a PropertyChangeEvent when the 'dataModel' property changes.
- */
- public static final String MODEL_CHANGED_PROPERTY = "dataModel";
-
- /**
- * name for the UI delegate for this combo box.
- */
- private static final String uiClassID = "ComboBoxUI";
+ private static final int DEFAULT_MAXIMUM_ROW_COUNT = 8;
/**
* dataModel used by JComboBox to keep track of its list data and currently
@@ -143,7 +108,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
protected ListCellRenderer renderer;
/**
- * editor that is responsible for editting an object in a combo box list
+ * Editor that is responsible for editing an object in a combo box list.
*/
protected ComboBoxEditor editor;
@@ -191,8 +156,9 @@ public class JComboBox extends JComponent implements ItemSelectable,
private Object prototypeDisplayValue;
/**
- * Constructs JComboBox object with specified data model for it. The first
- * item in the specified data model is selected by default.
+ * Constructs JComboBox object with specified data model for it.
+ * <p>Note that the JComboBox will not change the value that
+ * is preselected by your ComboBoxModel implementation.</p>
*
* @param model Data model that will be used by this JComboBox to keep track
* of its list of items.
@@ -205,10 +171,6 @@ public class JComboBox extends JComponent implements ItemSelectable,
setModel(model);
setActionCommand("comboBoxChanged");
- // by default set selected item to the first element in the combo box
- if (getItemCount() != 0)
- setSelectedItem(getItemAt(0));
-
lightWeightPopupEnabled = true;
isEditable = false;
@@ -300,7 +262,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public String getUIClassID()
{
- return uiClassID;
+ return "ComboBoxUI";
}
/**
@@ -322,21 +284,29 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public void setModel(ComboBoxModel newDataModel)
{
- if (this.dataModel == newDataModel)
- return;
- if (this.dataModel != null)
- // remove all listeners currently registered with the model.
- dataModel.removeListDataListener(this);
+ // dataModel is null if it this method is called from inside the constructors.
+ if(dataModel != null) {
+ // Prevents unneccessary updates.
+ if (dataModel == newDataModel)
+ return;
- ComboBoxModel oldDataModel = this.dataModel;
- this.dataModel = newDataModel;
+ // Removes itself (as DataListener) from the to-be-replaced model.
+ dataModel.removeListDataListener(this);
+ }
+
+ /* Adds itself as a DataListener to the new model.
+ * It is intentioned that this operation will fail with a NullPointerException if the
+ * caller delivered a null argument.
+ */
+ newDataModel.addListDataListener(this);
- if (this.dataModel != null)
- // register all listeners with the new data model
- dataModel.addListDataListener(this);
+ // Stores old data model for event notification.
+ ComboBoxModel oldDataModel = dataModel;
+ dataModel = newDataModel;
- firePropertyChange(MODEL_CHANGED_PROPERTY, oldDataModel, this.dataModel);
+ // Notifies the listeners of the model change.
+ firePropertyChange("model", oldDataModel, dataModel);
}
/**
@@ -351,8 +321,8 @@ public class JComboBox extends JComponent implements ItemSelectable,
/**
* This method sets JComboBox's popup to be either lightweight or
- * heavyweight. If 'enabled' is true then lightweight popup is used and
- * heavyweight otherwise. By default lightweight popup is used to display
+ * heavyweight. If 'enabled' is true then lightweight popup is used and
+ * heavyweight otherwise. By default lightweight popup is used to display
* this JComboBox's elements.
*
* @param enabled indicates if lightweight popup or heavyweight popup should
@@ -360,7 +330,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public void setLightWeightPopupEnabled(boolean enabled)
{
- this.lightWeightPopupEnabled = enabled;
+ lightWeightPopupEnabled = enabled;
}
/**
@@ -388,10 +358,10 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public void setEditable(boolean editable)
{
- if (this.isEditable != editable)
+ if (isEditable != editable)
{
- this.isEditable = editable;
- firePropertyChange(EDITABLE_CHANGED_PROPERTY, ! isEditable, isEditable);
+ isEditable = editable;
+ firePropertyChange("editable", ! isEditable, isEditable);
}
}
@@ -407,10 +377,10 @@ public class JComboBox extends JComponent implements ItemSelectable,
{
if (maximumRowCount != rowCount)
{
- int oldMaximumRowCount = this.maximumRowCount;
- this.maximumRowCount = rowCount;
- firePropertyChange(MAXIMUM_ROW_COUNT_CHANGED_PROPERTY,
- oldMaximumRowCount, this.maximumRowCount);
+ int oldMaximumRowCount = maximumRowCount;
+ maximumRowCount = rowCount;
+ firePropertyChange("maximumRowCount",
+ oldMaximumRowCount, maximumRowCount);
}
}
@@ -437,12 +407,12 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public void setRenderer(ListCellRenderer aRenderer)
{
- if (this.renderer != aRenderer)
+ if (renderer != aRenderer)
{
- ListCellRenderer oldRenderer = this.renderer;
- this.renderer = aRenderer;
- firePropertyChange(RENDERER_CHANGED_PROPERTY, oldRenderer,
- this.renderer);
+ ListCellRenderer oldRenderer = renderer;
+ renderer = aRenderer;
+ firePropertyChange("renderer", oldRenderer,
+ renderer);
}
}
@@ -477,11 +447,11 @@ public class JComboBox extends JComponent implements ItemSelectable,
if (editor != null)
editor.addActionListener(this);
- firePropertyChange(EDITOR_CHANGED_PROPERTY, oldEditor, editor);
+ firePropertyChange("editor", oldEditor, editor);
}
/**
- * Returns editor component that is responsible for displaying/editting
+ * Returns editor component that is responsible for displaying/editing
* selected item in the combo box.
*
* @return ComboBoxEditor
@@ -503,45 +473,76 @@ public class JComboBox extends JComponent implements ItemSelectable,
/**
* Returns currently selected item in the combo box.
+ * The result may be <code>null</code> to indicate that nothing is
+ * currently selected.
*
* @return element that is currently selected in this combo box.
*/
public Object getSelectedItem()
{
- Object item = dataModel.getSelectedItem();
-
- if (item == null && getItemCount() != 0)
- item = getItemAt(0);
-
- return item;
+ return dataModel.getSelectedItem();
}
/**
- * Forces JComboBox to select component located in the given index in the
+ * Forces JComboBox to select component located in the given index in the
* combo box.
+ * <p>If the index is below -1 or exceeds the upper bound an
+ * <code>IllegalArgumentException</code> is thrown.<p/>
+ * <p>If the index is -1 then no item gets selected.</p>
*
* @param index index specifying location of the component that should be
* selected.
*/
public void setSelectedIndex(int index)
{
- // FIXME: if index == -1 then nothing should be selected
- setSelectedItem(dataModel.getElementAt(index));
+ if(index < -1 || index >= dataModel.getSize()) {
+ // Fails because index is out of bounds.
+ throw new IllegalArgumentException("illegal index: " + index);
+ } else {
+ /* Selects the item at the given index or clears the selection if the
+ * index value is -1.
+ */
+ setSelectedItem((index == -1) ? null : dataModel.getElementAt(index));
+ }
}
/**
* Returns index of the item that is currently selected in the combo box.
* If no item is currently selected, then -1 is returned.
+ *
+ * <p>Note: For performance reasons you should minimize invocation of this
+ * method. If the data model is not an instance of
+ * <code>DefaultComboBoxModel</code> the complexity is O(n) where
+ * n is the number of elements in the combo box.</p>
*
- * @return int index specifying location of the currently selected item in
+ * @return int Index specifying location of the currently selected item in
* the combo box or -1 if nothing is selected in the combo box.
*/
public int getSelectedIndex()
{
Object selectedItem = getSelectedItem();
- if (selectedItem != null && (dataModel instanceof DefaultComboBoxModel))
- return ((DefaultComboBoxModel) dataModel).getIndexOf(selectedItem);
+
+ if (selectedItem != null) {
+
+ if(dataModel instanceof DefaultComboBoxModel) {
+ // Uses special method of DefaultComboBoxModel to retrieve the index.
+ return ((DefaultComboBoxModel) dataModel).getIndexOf(selectedItem);
+ } else {
+ // Iterates over all items to retrieve the index.
+ int size = dataModel.getSize();
+
+ for(int i=0; i < size; i++) {
+ Object o = dataModel.getElementAt(i);
+
+ // XXX: Is special handling of ComparableS neccessary?
+ if((selectedItem != null) ? selectedItem.equals(o) : o == null) {
+ return i;
+ }
+ }
+ }
+ }
+ // returns that no item is currently selected
return -1;
}
@@ -550,60 +551,104 @@ public class JComboBox extends JComponent implements ItemSelectable,
return prototypeDisplayValue;
}
- public void setPrototypeDisplayValue(Object prototypeDisplayValue)
+ public void setPrototypeDisplayValue(Object newPrototypeDisplayValue)
{
- this.prototypeDisplayValue = prototypeDisplayValue;
+ prototypeDisplayValue = newPrototypeDisplayValue;
}
/**
* This method adds given element to this JComboBox.
+ * <p>A <code>RuntimeException</code> is thrown if the data model is not
+ * an instance of {@link MutableComboBoxModel}.</p>
*
* @param element element to add
*/
public void addItem(Object element)
{
- ((MutableComboBoxModel) dataModel).addElement(element);
+ if(dataModel instanceof MutableComboBoxModel) {
+ ((MutableComboBoxModel) dataModel).addElement(element);
+ } else {
+ throw new RuntimeException("Unable to add the item because the data model it is not an instance of MutableComboBoxModel.");
+ }
}
/**
- * Inserts given element at the specified index to this JComboBox
+ * Inserts given element at the specified index to this JComboBox.
+ * <p>A <code>RuntimeException</code> is thrown if the data model is not
+ * an instance of {@link MutableComboBoxModel}.</p>
*
* @param element element to insert
* @param index position where to insert the element
*/
public void insertItemAt(Object element, int index)
{
- ((MutableComboBoxModel) dataModel).insertElementAt(element, index);
+ if(dataModel instanceof MutableComboBoxModel) {
+ ((MutableComboBoxModel) dataModel).insertElementAt(element, index);
+ } else {
+ throw new RuntimeException("Unable to insert the item because the data model it is not an instance of MutableComboBoxModel.");
+ }
}
/**
* This method removes given element from this JComboBox.
+ * <p>A <code>RuntimeException</code> is thrown if the data model is not
+ * an instance of {@link MutableComboBoxModel}.</p>
*
* @param element element to remove
*/
public void removeItem(Object element)
{
- ((MutableComboBoxModel) dataModel).removeElement(element);
+ if(dataModel instanceof MutableComboBoxModel) {
+ ((MutableComboBoxModel) dataModel).removeElement(element);
+ } else {
+ throw new RuntimeException("Unable to remove the item because the data model it is not an instance of MutableComboBoxModel.");
+ }
}
/**
* This method remove element location in the specified index in the
* JComboBox.
+ * <p>A <code>RuntimeException</code> is thrown if the data model is not
+ * an instance of {@link MutableComboBoxModel}.</p>
*
* @param index index specifying position of the element to remove
*/
public void removeItemAt(int index)
{
- ((MutableComboBoxModel) dataModel).removeElementAt(index);
+ if(dataModel instanceof MutableComboBoxModel) {
+ ((MutableComboBoxModel) dataModel).removeElementAt(index);
+ } else {
+ throw new RuntimeException("Unable to remove the item because the data model it is not an instance of MutableComboBoxModel.");
+ }
}
/**
* This method removes all elements from this JComboBox.
+ * <p>A <code>RuntimeException</code> is thrown if the data model is not
+ * an instance of {@link MutableComboBoxModel}.</p>
+ *
*/
public void removeAllItems()
{
- if (dataModel instanceof DefaultComboBoxModel)
- ((DefaultComboBoxModel) dataModel).removeAllElements();
+ if (dataModel instanceof DefaultComboBoxModel) {
+ // Uses special method if we have a DefaultComboBoxModel.
+ ((DefaultComboBoxModel) dataModel).removeAllElements();
+ } else if(dataModel instanceof MutableComboBoxModel){
+ // Iterates over all items and removes each.
+ MutableComboBoxModel mcbm = (MutableComboBoxModel) dataModel;
+
+ /* We intentionally remove the items backwards to support
+ * models which shift their content to the beginning (e.g.
+ * linked lists)
+ */
+ for(int i=mcbm.getSize()-1; i >= 0; i--) {
+ mcbm.removeElementAt(i);
+ }
+
+ } else {
+ throw new RuntimeException("Unable to remove the items because the data model it is not an instance of MutableComboBoxModel.");
+ }
+
}
/**
@@ -801,8 +846,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public Object[] getSelectedObjects()
{
- Object selectedObject = getSelectedItem();
- return new Object[] { selectedObject };
+ return new Object[] { getSelectedItem() };
}
/**
@@ -887,8 +931,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
if (enabled != oldEnabled)
{
super.setEnabled(enabled);
- firePropertyChange(ENABLED_CHANGED_PROPERTY, oldEnabled,
- (boolean) enabled);
+ firePropertyChange("enabled", oldEnabled, enabled);
}
}
@@ -951,7 +994,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public int getItemCount()
{
- return ((DefaultComboBoxModel) dataModel).getSize();
+ return dataModel.getSize();
}
/**
@@ -963,7 +1006,7 @@ public class JComboBox extends JComponent implements ItemSelectable,
*/
public Object getItemAt(int index)
{
- return ((MutableComboBoxModel) dataModel).getElementAt(index);
+ return dataModel.getElementAt(index);
}
/**