[kaffe] CVS kaffe (robilad): Resynced with GNU Classpath: various
Swing bug fixes
Kaffe CVS
cvs-commits at kaffe.org
Mon Dec 20 19:23:28 PST 2004
PatchSet 5689
Date: 2004/12/21 03:18:54
Author: robilad
Branch: HEAD
Tag: (none)
Log:
Resynced with GNU Classpath: various Swing bug fixes
2004-12-21 Dalibor Topic <robilad at kaffe.org>
* libraries/javalib/javax/swing/JComboBox.java,
libraries/javalib/javax/swing/DefaultComboBoxModel.java,
libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java:
Resynced with GNU Classpath.
2004-12-18 Robert Schuster <thebohemian at gmx.net>
* javax/swing/JComboBox.java
added support for no item being selected
(JComboBox): select first or nothing depending on element
count
(setModel): cleaned up unneeded this. usage, added more
docs, made exception behavior match that of the JDK
(setLighWeightPopupEnabled): removed unneeded this. usage
(setEditable): dito
(setMaximumRowCount): dito
(setRenderer): dito
(setPrototypeDisplayValue): dito
(getSelectedItem): simplified, added more user doc
(setSelectedIndex): corrected exception behavior, added more user
doc
(getSelectedIndex): fixed hardcoded dependency on DefaultComboBoxModel
(see bug #11255), added performance warning to user doc
(addItem): fixed exception behavior, added user doc
(insertItemAt): dito
(removeItem): dito
(removeItemAt): dito
(removeAll): fixed exception behavior, added user doc, added support
for model not being instance of DefaultComboBoxModel (see bug #11255)
(getSelectedItemObjects): simplified
(getItemCount): fixed dependency on DefaultComboBoxModel (see bug #11255)
(getItemAt): fixed dependency on MutableComboBoxModel (see bug #11255)
* javax/swing/DefaultComboBoxModel.java:
(setSelectedItem): updates selected item only if new
value is null or known (match JDK behavior)
* javax/swing/plaf/basic/BasicComboBoxUI.java:
(paintCurrentValue): renders if no item is selected
Members:
ChangeLog:1.3235->1.3236
libraries/javalib/javax/swing/DefaultComboBoxModel.java:1.2->1.3
libraries/javalib/javax/swing/JComboBox.java:1.3->1.4
libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java:1.3->1.4
Index: kaffe/ChangeLog
diff -u kaffe/ChangeLog:1.3235 kaffe/ChangeLog:1.3236
--- kaffe/ChangeLog:1.3235 Tue Dec 21 02:43:00 2004
+++ kaffe/ChangeLog Tue Dec 21 03:18:54 2004
@@ -1,3 +1,43 @@
+2004-12-21 Dalibor Topic <robilad at kaffe.org>
+
+ * libraries/javalib/javax/swing/JComboBox.java,
+ libraries/javalib/javax/swing/DefaultComboBoxModel.java,
+ libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java:
+ Resynced with GNU Classpath.
+
+ 2004-12-18 Robert Schuster <thebohemian at gmx.net>
+
+ * javax/swing/JComboBox.java
+ added support for no item being selected
+ (JComboBox): select first or nothing depending on element
+ count
+ (setModel): cleaned up unneeded "this." usage, added more
+ docs, made exception behavior match that of the JDK
+ (setLighWeightPopupEnabled): removed unneeded "this." usage
+ (setEditable): dito
+ (setMaximumRowCount): dito
+ (setRenderer): dito
+ (setPrototypeDisplayValue): dito
+ (getSelectedItem): simplified, added more user doc
+ (setSelectedIndex): corrected exception behavior, added more user
+ doc
+ (getSelectedIndex): fixed hardcoded dependency on DefaultComboBoxModel
+ (see bug #11255), added performance warning to user doc
+ (addItem): fixed exception behavior, added user doc
+ (insertItemAt): dito
+ (removeItem): dito
+ (removeItemAt): dito
+ (removeAll): fixed exception behavior, added user doc, added support
+ for model not being instance of DefaultComboBoxModel (see bug #11255)
+ (getSelectedItemObjects): simplified
+ (getItemCount): fixed dependency on DefaultComboBoxModel (see bug #11255)
+ (getItemAt): fixed dependency on MutableComboBoxModel (see bug #11255)
+ * javax/swing/DefaultComboBoxModel.java:
+ (setSelectedItem): updates selected item only if new
+ value is null or known (match JDK behavior)
+ * javax/swing/plaf/basic/BasicComboBoxUI.java:
+ (paintCurrentValue): renders "" if no item is selected
+
2004-12-20 Adam Heath <doogie at brainfood.com>
* kaffe/kaffevm/systems/unix-jthreads/jthread.c:
Index: kaffe/libraries/javalib/javax/swing/DefaultComboBoxModel.java
diff -u kaffe/libraries/javalib/javax/swing/DefaultComboBoxModel.java:1.2 kaffe/libraries/javalib/javax/swing/DefaultComboBoxModel.java:1.3
--- kaffe/libraries/javalib/javax/swing/DefaultComboBoxModel.java:1.2 Sun Sep 12 15:11:06 2004
+++ kaffe/libraries/javalib/javax/swing/DefaultComboBoxModel.java Tue Dec 21 03:18:57 2004
@@ -50,6 +50,7 @@
*
* @author Andrew Selkirk
* @author Olga Rodimina
+ * @author Robert Schuster
* @version 1.0
*/
public class DefaultComboBoxModel extends AbstractListModel
@@ -182,13 +183,23 @@
* ListDataEvent to all registered ListDataListeners of the JComboBox. The
* start and end index of the event is set to -1 to indicate combo box's
* selection has changed, and not its contents.
+ *
+ * <p>If the given object is not contained in the combo box list then nothing
+ * happens.</p>
*
* @param object item to select in the JComboBox
*/
public void setSelectedItem(Object object)
{
- selectedItem = object;
- fireContentsChanged(this, -1, -1);
+
+ /* Updates the selected item only if the given object
+ * is null or in the list (this is how the JDK behaves).
+ */
+ if(object == null || list.contains(object)) {
+ selectedItem = object;
+ fireContentsChanged(this, -1, -1);
+ }
+
}
/**
Index: kaffe/libraries/javalib/javax/swing/JComboBox.java
diff -u kaffe/libraries/javalib/javax/swing/JComboBox.java:1.3 kaffe/libraries/javalib/javax/swing/JComboBox.java:1.4
--- kaffe/libraries/javalib/javax/swing/JComboBox.java:1.3 Sun Oct 24 13:39:11 2004
+++ kaffe/libraries/javalib/javax/swing/JComboBox.java Tue Dec 21 03:18:57 2004
@@ -60,7 +60,6 @@
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 @@
*
* @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;
/**
@@ -143,7 +144,7 @@
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;
@@ -205,9 +206,10 @@
setModel(model);
setActionCommand("comboBoxChanged");
- // by default set selected item to the first element in the combo box
- if (getItemCount() != 0)
- setSelectedItem(getItemAt(0));
+ /* By default set selected item to the first element in the combo box
+ * or select nothing if there are no elements.
+ */
+ setSelectedIndex(getItemCount() != 0 ? 0 : -1);
lightWeightPopupEnabled = true;
isEditable = false;
@@ -322,21 +324,29 @@
*/
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);
-
- ComboBoxModel oldDataModel = this.dataModel;
- this.dataModel = newDataModel;
-
- if (this.dataModel != null)
- // register all listeners with the new data model
- dataModel.addListDataListener(this);
+ // dataModel is null if it this method is called from inside the constructors.
+ if(dataModel != null) {
+ // Prevents unneccessary updates.
+ if (dataModel == newDataModel)
+ return;
+
+ // 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);
+
+ // 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_CHANGED_PROPERTY, oldDataModel, dataModel);
}
/**
@@ -351,8 +361,8 @@
/**
* 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 +370,7 @@
*/
public void setLightWeightPopupEnabled(boolean enabled)
{
- this.lightWeightPopupEnabled = enabled;
+ lightWeightPopupEnabled = enabled;
}
/**
@@ -388,9 +398,9 @@
*/
public void setEditable(boolean editable)
{
- if (this.isEditable != editable)
+ if (isEditable != editable)
{
- this.isEditable = editable;
+ isEditable = editable;
firePropertyChange(EDITABLE_CHANGED_PROPERTY, ! isEditable, isEditable);
}
}
@@ -407,10 +417,10 @@
{
if (maximumRowCount != rowCount)
{
- int oldMaximumRowCount = this.maximumRowCount;
- this.maximumRowCount = rowCount;
+ int oldMaximumRowCount = maximumRowCount;
+ maximumRowCount = rowCount;
firePropertyChange(MAXIMUM_ROW_COUNT_CHANGED_PROPERTY,
- oldMaximumRowCount, this.maximumRowCount);
+ oldMaximumRowCount, maximumRowCount);
}
}
@@ -437,12 +447,12 @@
*/
public void setRenderer(ListCellRenderer aRenderer)
{
- if (this.renderer != aRenderer)
+ if (renderer != aRenderer)
{
- ListCellRenderer oldRenderer = this.renderer;
- this.renderer = aRenderer;
+ ListCellRenderer oldRenderer = renderer;
+ renderer = aRenderer;
firePropertyChange(RENDERER_CHANGED_PROPERTY, oldRenderer,
- this.renderer);
+ renderer);
}
}
@@ -481,7 +491,7 @@
}
/**
- * 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 +513,76 @@
/**
* 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 +591,104 @@
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 +886,7 @@
*/
public Object[] getSelectedObjects()
{
- Object selectedObject = getSelectedItem();
- return new Object[] { selectedObject };
+ return new Object[] { getSelectedItem() };
}
/**
@@ -951,7 +1035,7 @@
*/
public int getItemCount()
{
- return ((DefaultComboBoxModel) dataModel).getSize();
+ return dataModel.getSize();
}
/**
@@ -963,7 +1047,7 @@
*/
public Object getItemAt(int index)
{
- return ((MutableComboBoxModel) dataModel).getElementAt(index);
+ return dataModel.getElementAt(index);
}
/**
Index: kaffe/libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java
diff -u kaffe/libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java:1.3 kaffe/libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java:1.4
--- kaffe/libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java:1.3 Sun Oct 24 13:39:19 2004
+++ kaffe/libraries/javalib/javax/swing/plaf/basic/BasicComboBoxUI.java Tue Dec 21 03:18:57 2004
@@ -80,6 +80,7 @@
* UI Delegate for JComboBox
*
* @author Olga Rodimina
+ * @author Robert Schuster
*/
public class BasicComboBoxUI extends ComboBoxUI
{
@@ -783,22 +784,25 @@
{
Object currentValue = comboBox.getSelectedItem();
boolean isPressed = arrowButton.getModel().isPressed();
- if (currentValue != null)
- {
- Component comp = comboBox.getRenderer()
+
+ /* Gets the component to be drawn for the current value.
+ * If there is currently no selected item we will take an empty
+ * String as replacement.
+ */
+ Component comp = comboBox.getRenderer()
.getListCellRendererComponent(listBox,
- currentValue,
+ (currentValue != null ? currentValue : ""),
-1,
isPressed,
hasFocus);
- if (! comboBox.isEnabled())
+ if (! comboBox.isEnabled())
comp.setEnabled(false);
- g.translate(borderInsets.left, borderInsets.top);
+ g.translate(borderInsets.left, borderInsets.top);
comp.setBounds(0, 0, bounds.width, bounds.height);
comp.paint(g);
g.translate(-borderInsets.left, -borderInsets.top);
- }
+
comboBox.revalidate();
}
else
More information about the kaffe
mailing list