This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gui][PATCH] JComboBox - mouse drag events
- From: Olga Rodimina <rodimina at redhat dot com>
- To: java-patches at gcc dot gnu dot org
- Date: 28 Sep 2004 13:59:08 -0400
- Subject: [gui][PATCH] JComboBox - mouse drag events
- Organization:
Hi,
I've cleaned up changes from previous week that handle dragging events
in JComboBox. I will be committing this patch to java-gui-branch.
Olga.
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/libjava/ChangeLog,v
retrieving revision 1.2660.2.428
diff -u -r1.2660.2.428 ChangeLog
--- ChangeLog 28 Sep 2004 05:05:09 -0000 1.2660.2.428
+++ ChangeLog 28 Sep 2004 17:28:26 -0000
@@ -1,3 +1,16 @@
+2004-09-28 Olga Rodimina <rodimina@redhat.com>
+
+ * javax/swing/plaf/basic/BasicComboPopup.java:
+ Added javadocs for undocumented fields.
+ (show): scroll down to the selected item and
+ highlight selected item.
+ (startAutoScrolling): Implemented.
+ (stopAutoScrolling): Implemented.
+ (autoScrollUp): Implemented.
+ (autoScrollDown): Implemented.
+ (InvocationMouseHandler.mouseReleased): Implemented.
+ (InvocationMouseMotionHandler.mouseDragged): Implemented.
+
2004-09-28 Jerry Quinn <jlquinn@optonline.net>
* java/awt/image/RescaleOp.java: Implement.
Index: javax/swing/plaf/basic/BasicComboPopup.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/javax/swing/plaf/basic/BasicComboPopup.java,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 BasicComboPopup.java
--- javax/swing/plaf/basic/BasicComboPopup.java 14 Sep 2004 19:47:54 -0000 1.1.2.2
+++ javax/swing/plaf/basic/BasicComboPopup.java 28 Sep 2004 17:28:27 -0000
@@ -39,6 +39,7 @@
import java.awt.Component;
import java.awt.Dimension;
+import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
@@ -58,10 +59,12 @@
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPopupMenu;
+import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
@@ -78,37 +81,32 @@
*/
public class BasicComboPopup extends JPopupMenu implements ComboPopup
{
+ /* Timer for autoscrolling */
protected Timer autoscrollTimer;
- /**
- * ComboBox associated with this popup
- */
+ /** ComboBox associated with this popup */
protected JComboBox comboBox;
- /*
- * FIXME: Document fields below
- */
+ /** FIXME: Need to document */
protected boolean hasEntered;
- protected boolean isAutoScrolling;
/**
- * ItemListener listening to the selection changes in the combo box
+ * Indicates whether the scroll bar located in popup menu with comboBox's
+ * list of items is currently autoscrolling. This happens when mouse event
+ * originated in the combo box and is dragged outside of its bounds
*/
+ protected boolean isAutoScrolling;
+
+ /** ItemListener listening to the selection changes in the combo box */
protected ItemListener itemListener;
- /**
- * This listener is not used
- */
+ /** This listener is not used */
protected KeyListener keyListener;
- /**
- * JList which is used to display item is the combo box
- */
+ /** JList which is used to display item is the combo box */
protected JList list;
- /**
- * This listener is not used
- */
+ /** This listener is not used */
protected ListDataListener listDataListener;
/**
@@ -123,14 +121,10 @@
*/
protected MouseMotionListener listMouseMotionListener;
- /**
- * This listener is not used
- */
+ /** This listener is not used */
protected ListSelectionListener listSelectionListener;
- /**
- * MouseListener listening to mouse events occuring in the combo box
- */
+ /** MouseListener listening to mouse events occuring in the combo box */
protected MouseListener mouseListener;
/**
@@ -145,21 +139,19 @@
*/
protected PropertyChangeListener propertyChangeListener;
- /*
- * FIXME: Document fields below
- */
+ /** direction for scrolling down list of combo box's items */
protected static int SCROLL_DOWN = 1;
+
+ /** direction for scrolling up list of combo box's items */
protected static int SCROLL_UP = 0;
+
+ /** Indicates auto scrolling direction */
protected int scrollDirection;
- /**
- * JScrollPane that contains list portion of the combo box
- */
+ /** JScrollPane that contains list portion of the combo box */
protected JScrollPane scroller;
- /**
- * This field is not used
- */
+ /** This field is not used */
protected boolean valueIsAdjusting;
/**
@@ -184,13 +176,21 @@
// popup should have same width as the comboBox and should be hight anough
// to display number of rows equal to 'maximumRowCount' property
- int popupHeight = getPopupHeightForRowCount(comboBox.getMaximumRowCount())
- + 4;
+ int popupHeight = getPopupHeightForRowCount(comboBox.getMaximumRowCount());
- // FIXME: Uncomment this out once preferred size of JList will be working
- // list.setPreferredSize(new Dimension(cbBounds.width, popupHeight));
+ list.setPreferredSize(new Dimension(cbBounds.width, popupHeight));
super.setPopupSize(cbBounds.width, popupHeight);
+ // Highlight selected item in the combo box's drop down list
+ if (comboBox.getSelectedIndex() != -1)
+ list.setSelectedIndex(comboBox.getSelectedIndex());
+
+ //scroll scrollbar s.t. selected item is visible
+ JScrollBar scrollbar = scroller.getVerticalScrollBar();
+ int selectedIndex = comboBox.getSelectedIndex();
+ if (selectedIndex > comboBox.getMaximumRowCount())
+ scrollbar.setValue(getPopupHeightForRowCount(selectedIndex));
+
// location specified is relative to comboBox
super.show(comboBox, 0, cbBounds.height);
}
@@ -557,37 +557,68 @@
}
/**
- * DOCUMENT ME!
+ * This method start scrolling combo box's list of items either up or down
+ * depending on the specified 'direction'
*
- * @param direction DOCUMENT ME!
+ * @param direction of the scrolling.
*/
protected void startAutoScrolling(int direction)
{
- // FIXME: Need to implement
+ // FIXME: add timer
+ isAutoScrolling = true;
+
+ if (direction == SCROLL_UP)
+ autoScrollUp();
+ else
+ autoScrollDown();
}
/**
- * DOCUMENT ME!
+ * This method stops scrolling the combo box's list of items
*/
protected void stopAutoScrolling()
{
- // FIXME: Need to implement
+ // FIXME: add timer
+ isAutoScrolling = false;
}
/**
- * DOCUMENT ME!
+ * This method scrolls up list of combo box's items up and highlights that
+ * just became visible.
*/
protected void autoScrollUp()
{
- // FIXME: Need to implement
+ // scroll up the scroll bar to make the item above visible
+ JScrollBar scrollbar = scroller.getVerticalScrollBar();
+ int scrollToNext = list.getScrollableUnitIncrement(super.getBounds(),
+ SwingConstants.VERTICAL,
+ SCROLL_UP);
+
+ scrollbar.setValue(scrollbar.getValue() - scrollToNext);
+
+ // If we haven't reached the begging of the combo box's list of items,
+ // then highlight next element above currently highlighted element
+ if (list.getSelectedIndex() != 0)
+ list.setSelectedIndex(list.getSelectedIndex() - 1);
}
/**
- * DOCUMENT ME!
+ * This method scrolls down list of combo box's and highlights item in the
+ * list that just became visible.
*/
protected void autoScrollDown()
{
- // FIXME: Need to implement
+ // scroll scrollbar down to make next item visible
+ JScrollBar scrollbar = scroller.getVerticalScrollBar();
+ int scrollToNext = list.getScrollableUnitIncrement(super.getBounds(),
+ SwingConstants.VERTICAL,
+ SCROLL_DOWN);
+ scrollbar.setValue(scrollbar.getValue() + scrollToNext);
+
+ // If we haven't reached the end of the combo box's list of items
+ // then highlight next element below currently highlighted element
+ if (list.getSelectedIndex() + 1 != comboBox.getItemCount())
+ list.setSelectedIndex(list.getSelectedIndex() + 1);
}
/**
@@ -717,15 +748,36 @@
}
/**
- * This method is invoked whenever mouse is released
+ * This method is invoked whenever mouse event was originated in the combo
+ * box and released either in the combBox list of items or in the combo
+ * box itself.
*
* @param e MouseEvent that should be handled
*/
public void mouseReleased(MouseEvent e)
{
- // FIXME: should handle dragging events here, if
- // mouse was dragged and released over the list of combobox's items,
- // then item over which it was released should be selected.
+ // Get component over which mouse was released
+ Component src = (Component) e.getSource();
+ int x = e.getX();
+ int y = e.getY();
+ Component releasedComponent = SwingUtilities.getDeepestComponentAt(src,
+ x, y);
+
+ // if mouse was released inside the bounds of combo box then do nothing,
+ // Otherwise if mouse was released inside the list of combo box items
+ // then change selection and close popup
+ if (! (releasedComponent instanceof JComboBox))
+ {
+ // List model contains the item over which mouse is released,
+ // since it is updated every time the mouse is moved over a different
+ // item in the list. Now that the mouse is released we need to
+ // update model of the combo box as well.
+ comboBox.setSelectedIndex(list.getSelectedIndex());
+
+ if (isAutoScrolling)
+ stopAutoScrolling();
+ hide();
+ }
}
}
@@ -742,13 +794,70 @@
{
}
+ /**
+ * This method is responsible for highlighting item in the drop down list
+ * over which the mouse is currently being dragged.
+ */
public void mouseDragged(MouseEvent e)
{
+ // convert point of the drag event relative to combo box list component
+ // figure out over which list cell the mouse is currently being dragged
+ // and highlight the cell. The list model is changed but the change has
+ // no effect on combo box's data model. The list model is changed so
+ // that the appropriate item would be highlighted in the combo box's
+ // list.
+ if (BasicComboPopup.this.isVisible())
+ {
+ int cbHeight = (int) comboBox.getPreferredSize().getHeight();
+ int popupHeight = BasicComboPopup.this.getSize().height;
+
+ // if mouse is dragged inside the the combo box's items list.
+ if (e.getY() > cbHeight && ! (e.getY() - cbHeight >= popupHeight))
+ {
+ int index = list.locationToIndex(new Point(e.getX(),
+ (int) (e.getY()
+ - cbHeight)));
+
+ int firstVisibleIndex = list.getFirstVisibleIndex();
+
+ // list.locationToIndex returns item's index that would
+ // be located at the specified point if the first item that
+ // is visible is item 0. However in the JComboBox it is not
+ // necessarily the case since list is contained in the
+ // JScrollPane so we need to adjust the index returned.
+ if (firstVisibleIndex != 0)
+ // FIXME: adjusted index here is off by one. I am adding one
+ // here to compensate for that. This should be
+ // index += firstVisibleIndex. Remove +1 once the bug is fixed.
+ index += firstVisibleIndex + 1;
+
+ list.setSelectedIndex(index);
+ }
+ else
+ {
+ // if mouse is being dragged at the bottom of combo box's list
+ // of items or at the very top then scroll the list in the
+ // desired direction.
+ boolean movingUP = e.getY() < cbHeight;
+ boolean movingDown = e.getY() > cbHeight;
+
+ if (movingUP)
+ {
+ scrollDirection = SCROLL_UP;
+ startAutoScrolling(SCROLL_UP);
+ }
+ else if (movingDown)
+ {
+ scrollDirection = SCROLL_DOWN;
+ startAutoScrolling(SCROLL_DOWN);
+ }
+ }
+ }
}
}
/**
- * ItemHandler is an item listener that listens to selection event occuring
+ * ItemHandler is an item listener that listens to selection events occuring
* in the combo box. FIXME: should specify here what it does when item is
* selected or deselected in the combo box list.
*/