OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [plaf/] [basic/] [BasicComboPopup.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* BasicComboPopup.java --
2
   Copyright (C) 2004, 2005  Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing.plaf.basic;
40
 
41
import java.awt.Color;
42
import java.awt.Component;
43
import java.awt.Dimension;
44
import java.awt.Insets;
45
import java.awt.Point;
46
import java.awt.Rectangle;
47
import java.awt.event.ItemEvent;
48
import java.awt.event.ItemListener;
49
import java.awt.event.KeyAdapter;
50
import java.awt.event.KeyEvent;
51
import java.awt.event.KeyListener;
52
import java.awt.event.MouseAdapter;
53
import java.awt.event.MouseEvent;
54
import java.awt.event.MouseListener;
55
import java.awt.event.MouseMotionAdapter;
56
import java.awt.event.MouseMotionListener;
57
import java.beans.PropertyChangeEvent;
58
import java.beans.PropertyChangeListener;
59
 
60
import javax.swing.BorderFactory;
61
import javax.swing.ComboBoxModel;
62
import javax.swing.JComboBox;
63
import javax.swing.JList;
64
import javax.swing.JPopupMenu;
65
import javax.swing.JScrollBar;
66
import javax.swing.JScrollPane;
67
import javax.swing.ListCellRenderer;
68
import javax.swing.ListSelectionModel;
69
import javax.swing.MenuSelectionManager;
70
import javax.swing.SwingConstants;
71
import javax.swing.SwingUtilities;
72
import javax.swing.Timer;
73
import javax.swing.UIManager;
74
import javax.swing.event.ListDataEvent;
75
import javax.swing.event.ListDataListener;
76
import javax.swing.event.ListSelectionEvent;
77
import javax.swing.event.ListSelectionListener;
78
import javax.swing.event.PopupMenuEvent;
79
import javax.swing.event.PopupMenuListener;
80
 
81
/**
82
 * UI Delegate for ComboPopup
83
 *
84
 * @author Olga Rodimina
85
 */
86
public class BasicComboPopup extends JPopupMenu implements ComboPopup
87
{
88
  /* Timer for autoscrolling */
89
  protected Timer autoscrollTimer;
90
 
91
  /** ComboBox associated with this popup */
92
  protected JComboBox comboBox;
93
 
94
  /** FIXME: Need to document */
95
  protected boolean hasEntered;
96
 
97
  /**
98
   * Indicates whether the scroll bar located in popup menu with comboBox's
99
   * list of items is currently autoscrolling. This happens when mouse event
100
   * originated in the combo box and is dragged outside of its bounds
101
   */
102
  protected boolean isAutoScrolling;
103
 
104
  /** ItemListener listening to the selection changes in the combo box */
105
  protected ItemListener itemListener;
106
 
107
  /** This listener is not used */
108
  protected KeyListener keyListener;
109
 
110
  /** JList which is used to display item is the combo box */
111
  protected JList list;
112
 
113
  /** This listener is not used */
114
  protected ListDataListener listDataListener;
115
 
116
  /**
117
   * MouseListener listening to mouse events occuring in the  combo box's
118
   * list.
119
   */
120
  protected MouseListener listMouseListener;
121
 
122
  /**
123
   * MouseMotionListener listening to mouse motion events occuring  in the
124
   * combo box's list
125
   */
126
  protected MouseMotionListener listMouseMotionListener;
127
 
128
  /** This listener is not used */
129
  protected ListSelectionListener listSelectionListener;
130
 
131
  /** MouseListener listening to mouse events occuring in the combo box */
132
  protected MouseListener mouseListener;
133
 
134
  /**
135
   * MouseMotionListener listening to mouse motion events occuring in the
136
   * combo box
137
   */
138
  protected MouseMotionListener mouseMotionListener;
139
 
140
  /**
141
   * PropertyChangeListener listening to changes occuring in the bound
142
   * properties of the combo box
143
   */
144
  protected PropertyChangeListener propertyChangeListener;
145
 
146
  /** direction for scrolling down list of combo box's items */
147
  protected static final int SCROLL_DOWN = 1;
148
 
149
  /** direction for scrolling up list of combo box's items */
150
  protected static final int SCROLL_UP = 0;
151
 
152
  /** Indicates auto scrolling direction */
153
  protected int scrollDirection;
154
 
155
  /** JScrollPane that contains list portion of the combo box */
156
  protected JScrollPane scroller;
157
 
158
  /** This field is not used */
159
  protected boolean valueIsAdjusting;
160
 
161
  /**
162
   * Creates a new BasicComboPopup object.
163
   *
164
   * @param comboBox the combo box with which this popup should be associated
165
   */
166
  public BasicComboPopup(JComboBox comboBox)
167
  {
168
    this.comboBox = comboBox;
169
    mouseListener = createMouseListener();
170
    mouseMotionListener = createMouseMotionListener();
171
    keyListener = createKeyListener();
172
 
173
    list = createList();
174
    configureList();
175
    scroller = createScroller();
176
    configureScroller();
177
    configurePopup();
178
    installComboBoxListeners();
179
    installKeyboardActions();
180
  }
181
 
182
  /**
183
   * This method displays drow down list of combo box items on the screen.
184
   */
185
  public void show()
186
  {
187
    Dimension size = comboBox.getSize();
188
    size.height = getPopupHeightForRowCount(comboBox.getMaximumRowCount());
189
    Insets i = getInsets();
190
    size.width -= i.left + i.right;
191
    Rectangle bounds = computePopupBounds(0, comboBox.getBounds().height,
192
                                          size.width, size.height);
193
 
194
    scroller.setMaximumSize(bounds.getSize());
195
    scroller.setPreferredSize(bounds.getSize());
196
    scroller.setMinimumSize(bounds.getSize());
197
    list.invalidate();
198
 
199
    syncListSelection();
200
 
201
    list.ensureIndexIsVisible(list.getSelectedIndex());
202
    setLightWeightPopupEnabled(comboBox.isLightWeightPopupEnabled());
203
    show(comboBox, bounds.x, bounds.y);
204
  }
205
 
206
  /**
207
   * This method hides drop down list of items
208
   */
209
  public void hide()
210
  {
211
    MenuSelectionManager menuSelectionManager =
212
      MenuSelectionManager.defaultManager();
213
    javax.swing.MenuElement[] menuElements =
214
      menuSelectionManager.getSelectedPath();
215
    for (int i = 0; i < menuElements.length; i++)
216
      {
217
        if (menuElements[i] == this)
218
          {
219
            menuSelectionManager.clearSelectedPath();
220
            break;
221
          }
222
      }
223
    comboBox.repaint();
224
  }
225
 
226
  /**
227
   * Return list cointaining JComboBox's items
228
   *
229
   * @return list cointaining JComboBox's items
230
   */
231
  public JList getList()
232
  {
233
    return list;
234
  }
235
 
236
  /**
237
   * Returns MouseListener that is listening to mouse events occuring in the
238
   * combo box.
239
   *
240
   * @return MouseListener
241
   */
242
  public MouseListener getMouseListener()
243
  {
244
    return mouseListener;
245
  }
246
 
247
  /**
248
   * Returns MouseMotionListener that is listening to mouse  motion events
249
   * occuring in the combo box.
250
   *
251
   * @return MouseMotionListener
252
   */
253
  public MouseMotionListener getMouseMotionListener()
254
  {
255
    return mouseMotionListener;
256
  }
257
 
258
  /**
259
   * Returns KeyListener listening to key events occuring in the combo box.
260
   * This method returns null because KeyHandler is not longer used.
261
   *
262
   * @return KeyListener
263
   */
264
  public KeyListener getKeyListener()
265
  {
266
    return keyListener;
267
  }
268
 
269
  /**
270
   * This method uninstalls the UI for the  given JComponent.
271
   */
272
  public void uninstallingUI()
273
  {
274
    if (propertyChangeListener != null)
275
      {
276
        comboBox.removePropertyChangeListener(propertyChangeListener);
277
      }
278
    if (itemListener != null)
279
      {
280
        comboBox.removeItemListener(itemListener);
281
      }
282
    uninstallComboBoxModelListeners(comboBox.getModel());
283
    uninstallKeyboardActions();
284
    uninstallListListeners();
285
  }
286
 
287
  /**
288
   * This method uninstalls listeners that were listening to changes occuring
289
   * in the comb box's data model
290
   *
291
   * @param model data model for the combo box from which to uninstall
292
   *        listeners
293
   */
294
  protected void uninstallComboBoxModelListeners(ComboBoxModel model)
295
  {
296
    model.removeListDataListener(listDataListener);
297
  }
298
 
299
  /**
300
   * This method uninstalls keyboard actions installed by the UI.
301
   */
302
  protected void uninstallKeyboardActions()
303
  {
304
    // Nothing to do here.
305
  }
306
 
307
  /**
308
   * This method fires PopupMenuEvent indicating that combo box's popup list
309
   * of items will become visible
310
   */
311
  protected void firePopupMenuWillBecomeVisible()
312
  {
313
    PopupMenuListener[] ll = comboBox.getPopupMenuListeners();
314
 
315
    for (int i = 0; i < ll.length; i++)
316
      ll[i].popupMenuWillBecomeVisible(new PopupMenuEvent(comboBox));
317
  }
318
 
319
  /**
320
   * This method fires PopupMenuEvent indicating that combo box's popup list
321
   * of items will become invisible.
322
   */
323
  protected void firePopupMenuWillBecomeInvisible()
324
  {
325
    PopupMenuListener[] ll = comboBox.getPopupMenuListeners();
326
 
327
    for (int i = 0; i < ll.length; i++)
328
      ll[i].popupMenuWillBecomeInvisible(new PopupMenuEvent(comboBox));
329
  }
330
 
331
  /**
332
   * This method fires PopupMenuEvent indicating that combo box's popup list
333
   * of items was closed without selection.
334
   */
335
  protected void firePopupMenuCanceled()
336
  {
337
    PopupMenuListener[] ll = comboBox.getPopupMenuListeners();
338
 
339
    for (int i = 0; i < ll.length; i++)
340
      ll[i].popupMenuCanceled(new PopupMenuEvent(comboBox));
341
  }
342
 
343
  /**
344
   * Creates MouseListener to listen to mouse events occuring in the combo
345
   * box. Note that this listener doesn't listen to mouse events occuring in
346
   * the popup portion of the combo box, it only listens to main combo box
347
   * part.
348
   *
349
   * @return new MouseMotionListener that listens to mouse events occuring in
350
   *         the combo box
351
   */
352
  protected MouseListener createMouseListener()
353
  {
354
    return new InvocationMouseHandler();
355
  }
356
 
357
  /**
358
   * Create Mouse listener that listens to mouse dragging events occuring in
359
   * the combo box. This listener is responsible for changing the selection
360
   * in the combo box list to the component over which mouse is being
361
   * currently dragged
362
   *
363
   * @return new MouseMotionListener that listens to mouse dragging events
364
   *         occuring in the combo box
365
   */
366
  protected MouseMotionListener createMouseMotionListener()
367
  {
368
    return new InvocationMouseMotionHandler();
369
  }
370
 
371
  /**
372
   * KeyListener created in this method is not used anymore.
373
   *
374
   * @return KeyListener that does nothing
375
   */
376
  protected KeyListener createKeyListener()
377
  {
378
    return new InvocationKeyHandler();
379
  }
380
 
381
  /**
382
   * ListSelectionListener created in this method is not used anymore
383
   *
384
   * @return ListSelectionListener that does nothing
385
   */
386
  protected ListSelectionListener createListSelectionListener()
387
  {
388
    return new ListSelectionHandler();
389
  }
390
 
391
  /**
392
   * Creates ListDataListener. This method returns null, because
393
   * ListDataHandler class is obsolete and is no longer used.
394
   *
395
   * @return null
396
   */
397
  protected ListDataListener createListDataListener()
398
  {
399
    return null;
400
  }
401
 
402
  /**
403
   * This method creates ListMouseListener to listen to mouse events occuring
404
   * in the combo box's item list.
405
   *
406
   * @return MouseListener to listen to mouse events occuring in the combo
407
   *         box's items list.
408
   */
409
  protected MouseListener createListMouseListener()
410
  {
411
    return new ListMouseHandler();
412
  }
413
 
414
  /**
415
   * Creates ListMouseMotionlistener to listen to mouse motion events occuring
416
   * in the combo box's list. This listener is responsible for highlighting
417
   * items in the list when mouse is moved over them.
418
   *
419
   * @return MouseMotionListener that handles mouse motion events occuring in
420
   *         the list of the combo box.
421
   */
422
  protected MouseMotionListener createListMouseMotionListener()
423
  {
424
    return new ListMouseMotionHandler();
425
  }
426
 
427
  /**
428
   * Creates PropertyChangeListener to handle changes in the JComboBox's bound
429
   * properties.
430
   *
431
   * @return PropertyChangeListener to handle changes in the JComboBox's bound
432
   *         properties.
433
   */
434
  protected PropertyChangeListener createPropertyChangeListener()
435
  {
436
    return new PropertyChangeHandler();
437
  }
438
 
439
  /**
440
   * Creates new ItemListener that will listen to ItemEvents occuring in the
441
   * combo box.
442
   *
443
   * @return ItemListener to listen to ItemEvents occuring in the combo box.
444
   */
445
  protected ItemListener createItemListener()
446
  {
447
    return new ItemHandler();
448
  }
449
 
450
  /**
451
   * Creates JList that will be used to display items in the combo box.
452
   *
453
   * @return JList that will be used to display items in the combo box.
454
   */
455
  protected JList createList()
456
  {
457
    JList l = new JList(comboBox.getModel());
458
    return l;
459
  }
460
 
461
  /**
462
   * This method configures the list of comboBox's items by setting  default
463
   * properties and installing listeners.
464
   */
465
  protected void configureList()
466
  {
467
    list.setFont(comboBox.getFont());
468
    list.setForeground(comboBox.getForeground());
469
    list.setBackground(comboBox.getBackground());
470
    Color sfg = UIManager.getColor("ComboBox.selectionForeground");
471
    list.setSelectionForeground(sfg);
472
    Color sbg = UIManager.getColor("ComboBox.selectionBackground");
473
    list.setSelectionBackground(sbg);
474
    list.setBorder(null);
475
    list.setCellRenderer(comboBox.getRenderer());
476
    list.setFocusable(false);
477
    list.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
478
    installListListeners();
479
  }
480
 
481
  /**
482
   * This method installs list listeners.
483
   */
484
  protected void installListListeners()
485
  {
486
    // mouse listener listening to mouse events occuring in the
487
    // combo box's list of items.
488
    listMouseListener = createListMouseListener();
489
    list.addMouseListener(listMouseListener);
490
 
491
    // mouse listener listening to mouse motion events occuring in the
492
    // combo box's list of items
493
    listMouseMotionListener = createListMouseMotionListener();
494
    list.addMouseMotionListener(listMouseMotionListener);
495
 
496
    listSelectionListener = createListSelectionListener();
497
    list.addListSelectionListener(listSelectionListener);
498
  }
499
 
500
  /**
501
   * This method creates scroll pane that will contain the list of comboBox's
502
   * items inside of it.
503
   *
504
   * @return JScrollPane
505
   */
506
  protected JScrollPane createScroller()
507
  {
508
    return new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
509
                           JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
510
  }
511
 
512
  /**
513
   * This method configures scroll pane to contain list of comboBox's  items
514
   */
515
  protected void configureScroller()
516
  {
517
    scroller.setBorder(null);
518
    scroller.setFocusable(false);
519
    scroller.getVerticalScrollBar().setFocusable(false);
520
  }
521
 
522
  /**
523
   * This method configures popup menu that will be used to display Scrollpane
524
   * with list of items inside of it.
525
   */
526
  protected void configurePopup()
527
  {
528
    setBorderPainted(true);
529
    setBorder(BorderFactory.createLineBorder(Color.BLACK));
530
    setOpaque(false);
531
    add(scroller);
532
    setFocusable(false);
533
  }
534
 
535
  /*
536
   * This method installs listeners that will listen to changes occuring
537
   * in the combo box.
538
   */
539
  protected void installComboBoxListeners()
540
  {
541
    // item listener listenening to selection events in the combo box
542
    itemListener = createItemListener();
543
    comboBox.addItemListener(itemListener);
544
 
545
    propertyChangeListener = createPropertyChangeListener();
546
    comboBox.addPropertyChangeListener(propertyChangeListener);
547
 
548
    installComboBoxModelListeners(comboBox.getModel());
549
  }
550
 
551
  /**
552
   * This method installs listeners that will listen to changes occuring in
553
   * the comb box's data model
554
   *
555
   * @param model data model for the combo box for which to install listeners
556
   */
557
  protected void installComboBoxModelListeners(ComboBoxModel model)
558
  {
559
    // list data listener to listen for ListDataEvents in combo box.
560
    // This listener is now obsolete and nothing is done here
561
    listDataListener = createListDataListener();
562
    comboBox.getModel().addListDataListener(listDataListener);
563
  }
564
 
565
  /**
566
   * Installs the keyboard actions.
567
   */
568
  protected void installKeyboardActions()
569
  {
570
    // Nothing to do here
571
  }
572
 
573
  /**
574
   * This method always returns false to indicate that  items in the combo box
575
   * list are not focus traversable.
576
   *
577
   * @return false
578
   */
579
  public boolean isFocusTraversable()
580
  {
581
    return false;
582
  }
583
 
584
  /**
585
   * This method start scrolling combo box's list of items  either up or down
586
   * depending on the specified 'direction'
587
   *
588
   * @param direction of the scrolling.
589
   */
590
  protected void startAutoScrolling(int direction)
591
  {
592
    // FIXME: add timer
593
    isAutoScrolling = true;
594
 
595
    if (direction == SCROLL_UP)
596
      autoScrollUp();
597
    else
598
      autoScrollDown();
599
  }
600
 
601
  /**
602
   * This method stops scrolling the combo box's list of items
603
   */
604
  protected void stopAutoScrolling()
605
  {
606
    // FIXME: add timer
607
    isAutoScrolling = false;
608
  }
609
 
610
  /**
611
   * This method scrolls up list of combo box's items up and highlights that
612
   * just became visible.
613
   */
614
  protected void autoScrollUp()
615
  {
616
    // scroll up the scroll bar to make the item above visible
617
    JScrollBar scrollbar = scroller.getVerticalScrollBar();
618
    int scrollToNext = list.getScrollableUnitIncrement(super.getBounds(),
619
                                                       SwingConstants.VERTICAL,
620
                                                       SCROLL_UP);
621
 
622
    scrollbar.setValue(scrollbar.getValue() - scrollToNext);
623
 
624
    // If we haven't reached the begging of the combo box's list of items,
625
    // then highlight next element above currently highlighted element
626
    if (list.getSelectedIndex() != 0)
627
      list.setSelectedIndex(list.getSelectedIndex() - 1);
628
  }
629
 
630
  /**
631
   * This method scrolls down list of combo box's and highlights item in the
632
   * list that just became visible.
633
   */
634
  protected void autoScrollDown()
635
  {
636
    // scroll scrollbar down to make next item visible
637
    JScrollBar scrollbar = scroller.getVerticalScrollBar();
638
    int scrollToNext = list.getScrollableUnitIncrement(super.getBounds(),
639
                                                       SwingConstants.VERTICAL,
640
                                                       SCROLL_DOWN);
641
    scrollbar.setValue(scrollbar.getValue() + scrollToNext);
642
 
643
    // If we haven't reached the end of the combo box's list of items
644
    // then highlight next element below currently highlighted element
645
    if (list.getSelectedIndex() + 1 != comboBox.getItemCount())
646
      list.setSelectedIndex(list.getSelectedIndex() + 1);
647
  }
648
 
649
  /**
650
   * This method helps to delegate focus to the right component in the
651
   * JComboBox. If the comboBox is editable then focus is sent to
652
   * ComboBoxEditor, otherwise it is delegated to JComboBox.
653
   *
654
   * @param e MouseEvent
655
   */
656
  protected void delegateFocus(MouseEvent e)
657
  {
658
    if (comboBox.isEditable())
659
      comboBox.getEditor().getEditorComponent().requestFocus();
660
    else
661
      comboBox.requestFocus();
662
  }
663
 
664
  /**
665
   * This method displays combo box popup if the popup is  not currently shown
666
   * on the screen and hides it if it is  currently visible
667
   */
668
  protected void togglePopup()
669
  {
670
    if (isVisible())
671
      hide();
672
    else
673
      show();
674
  }
675
 
676
  /**
677
   * DOCUMENT ME!
678
   *
679
   * @param e DOCUMENT ME!
680
   *
681
   * @return DOCUMENT ME!
682
   */
683
  protected MouseEvent convertMouseEvent(MouseEvent e)
684
  {
685
    Point point = SwingUtilities.convertPoint((Component) e.getSource(),
686
                                              e.getPoint(), list);
687
    MouseEvent newEvent = new MouseEvent((Component) e.getSource(),
688
                                        e.getID(), e.getWhen(),
689
                                        e.getModifiers(), point.x, point.y,
690
                                        e.getModifiers(),
691
                                        e.isPopupTrigger());
692
    return newEvent;
693
  }
694
 
695
  /**
696
   * Returns required height of the popup such that number of items visible in
697
   * it are equal to the maximum row count.  By default
698
   * comboBox.maximumRowCount=8
699
   *
700
   * @param maxRowCount number of maximum visible rows in the  combo box's
701
   *        popup list of items
702
   *
703
   * @return height of the popup required to fit number of items  equal to
704
   *         JComboBox.maximumRowCount.
705
   */
706
  protected int getPopupHeightForRowCount(int maxRowCount)
707
  {
708
    int totalHeight = 0;
709
    ListCellRenderer rend = list.getCellRenderer();
710
 
711
    if (comboBox.getItemCount() < maxRowCount)
712
      maxRowCount = comboBox.getItemCount();
713
 
714
    for (int i = 0; i < maxRowCount; i++)
715
      {
716
        Component comp = rend.getListCellRendererComponent(list,
717
                                                           comboBox.getModel()
718
                                                                   .getElementAt(i),
719
                                                           -1, false, false);
720
        Dimension dim = comp.getPreferredSize();
721
        totalHeight += dim.height;
722
      }
723
 
724
    return totalHeight == 0 ? 100 : totalHeight;
725
  }
726
 
727
  /**
728
   * DOCUMENT ME!
729
   *
730
   * @param px DOCUMENT ME!
731
   * @param py DOCUMENT ME!
732
   * @param pw DOCUMENT ME!
733
   * @param ph DOCUMENT ME!
734
   *
735
   * @return DOCUMENT ME!
736
   */
737
  protected Rectangle computePopupBounds(int px, int py, int pw, int ph)
738
  {
739
    return new Rectangle(px, py, pw, ph);
740
  }
741
 
742
  /**
743
   * This method changes the selection in the list to the item over which  the
744
   * mouse is currently located.
745
   *
746
   * @param anEvent MouseEvent
747
   * @param shouldScroll DOCUMENT ME!
748
   */
749
  protected void updateListBoxSelectionForEvent(MouseEvent anEvent,
750
                                                boolean shouldScroll)
751
  {
752
    Point point = anEvent.getPoint();
753
    if (list != null)
754
      {
755
        int index = list.locationToIndex(point);
756
        if (index == -1)
757
          {
758
            if (point.y < 0)
759
              index = 0;
760
            else
761
              index = comboBox.getModel().getSize() - 1;
762
          }
763
        if (list.getSelectedIndex() != index)
764
          {
765
            list.setSelectedIndex(index);
766
            if (shouldScroll)
767
              list.ensureIndexIsVisible(index);
768
          }
769
      }
770
  }
771
 
772
  /**
773
   * InvocationMouseHandler is a listener that listens to mouse events
774
   * occuring in the combo box. Note that this listener doesn't listen to
775
   * mouse events occuring in the popup portion of the combo box, it only
776
   * listens to main combo box part(area that displays selected item).  This
777
   * listener is responsible for showing and hiding popup portion  of the
778
   * combo box.
779
   */
780
  protected class InvocationMouseHandler extends MouseAdapter
781
  {
782
    /**
783
     * Creates a new InvocationMouseHandler object.
784
     */
785
    protected InvocationMouseHandler()
786
    {
787
      // Nothing to do here.
788
    }
789
 
790
    /**
791
     * This method is invoked whenever mouse is being pressed over the main
792
     * part of the combo box. This method will show popup if  the popup is
793
     * not shown on the screen right now, and it will hide popup otherwise.
794
     *
795
     * @param e MouseEvent that should be handled
796
     */
797
    public void mousePressed(MouseEvent e)
798
    {
799
      if (SwingUtilities.isLeftMouseButton(e) && comboBox.isEnabled())
800
        {
801
          delegateFocus(e);
802
          togglePopup();
803
        }
804
    }
805
 
806
    /**
807
     * This method is invoked whenever mouse event was originated in the combo
808
     * box and released either in the combBox list of items or in the combo
809
     * box itself.
810
     *
811
     * @param e MouseEvent that should be handled
812
     */
813
    public void mouseReleased(MouseEvent e)
814
    {
815
      Component component = (Component) e.getSource();
816
      Dimension size = component.getSize();
817
      Rectangle bounds = new Rectangle(0, 0, size.width - 1, size.height - 1);
818
      // If mouse was released inside the bounds of combo box then do nothing,
819
      // Otherwise if mouse was released inside the list of combo box items
820
      // then change selection and close popup
821
      if (! bounds.contains(e.getPoint()))
822
        {
823
          MouseEvent convEvent = convertMouseEvent(e);
824
          Point point = convEvent.getPoint();
825
          Rectangle visRect = new Rectangle();
826
          list.computeVisibleRect(visRect);
827
          if (visRect.contains(point))
828
            {
829
              updateListBoxSelectionForEvent(convEvent, false);
830
              comboBox.setSelectedIndex(list.getSelectedIndex());
831
            }
832
          hide();
833
        }
834
      hasEntered = false;
835
      stopAutoScrolling();
836
    }
837
  }
838
 
839
  /**
840
   * InvocationMouseMotionListener is a mouse listener that listens to mouse
841
   * dragging events occuring in the combo box.
842
   */
843
  protected class InvocationMouseMotionHandler extends MouseMotionAdapter
844
  {
845
    /**
846
     * Creates a new InvocationMouseMotionHandler object.
847
     */
848
    protected InvocationMouseMotionHandler()
849
    {
850
      // Nothing to do here.
851
    }
852
 
853
    /**
854
     * This method is responsible for highlighting item in the drop down list
855
     * over which the mouse is currently being dragged.
856
     */
857
    public void mouseDragged(MouseEvent e)
858
    {
859
      if (isVisible())
860
        {
861
          MouseEvent convEvent = convertMouseEvent(e);
862
          Rectangle visRect = new Rectangle();
863
          list.computeVisibleRect(visRect);
864
          if (convEvent.getPoint().y >= visRect.y
865
              && (convEvent.getPoint().y <= visRect.y + visRect.height - 1))
866
            {
867
              hasEntered = true;
868
              if (isAutoScrolling)
869
                stopAutoScrolling();
870
              Point point = convEvent.getPoint();
871
              if (visRect.contains(point))
872
                {
873
                  valueIsAdjusting = true;
874
                  updateListBoxSelectionForEvent(convEvent, false);
875
                  valueIsAdjusting = false;
876
                }
877
            }
878
          else if (hasEntered)
879
            {
880
              int dir = convEvent.getPoint().y < visRect.y ? SCROLL_UP
881
                                                           : SCROLL_DOWN;
882
              if (isAutoScrolling && scrollDirection != dir)
883
                {
884
                  stopAutoScrolling();
885
                  startAutoScrolling(dir);
886
                }
887
              else if (!isAutoScrolling)
888
                startAutoScrolling(dir);
889
            }
890
          else if (e.getPoint().y < 0)
891
            {
892
              hasEntered = true;
893
              startAutoScrolling(SCROLL_UP);
894
            }
895
        }
896
    }
897
  }
898
 
899
  /**
900
   * ItemHandler is an item listener that listens to selection events occuring
901
   * in the combo box. FIXME: should specify here what it does when item is
902
   * selected or deselected in the combo box list.
903
   */
904
  protected class ItemHandler extends Object implements ItemListener
905
  {
906
    /**
907
     * Creates a new ItemHandler object.
908
     */
909
    protected ItemHandler()
910
    {
911
      // Nothing to do here.
912
    }
913
 
914
    /**
915
     * This method responds to the selection events occuring in the combo box.
916
     *
917
     * @param e ItemEvent specifying the combo box's selection
918
     */
919
    public void itemStateChanged(ItemEvent e)
920
    {
921
      if (e.getStateChange() == ItemEvent.SELECTED && ! valueIsAdjusting)
922
        {
923
          valueIsAdjusting = true;
924
          syncListSelection();
925
          valueIsAdjusting = false;
926
          list.ensureIndexIsVisible(comboBox.getSelectedIndex());
927
        }
928
    }
929
  }
930
 
931
  /**
932
   * ListMouseHandler is a listener that listens to mouse events occuring in
933
   * the combo box's list of items. This class is responsible for hiding
934
   * popup portion of the combo box if the mouse is released inside the combo
935
   * box's list.
936
   */
937
  protected class ListMouseHandler extends MouseAdapter
938
  {
939
    protected ListMouseHandler()
940
    {
941
      // Nothing to do here.
942
    }
943
 
944
    public void mousePressed(MouseEvent e)
945
    {
946
      // Nothing to do here.
947
    }
948
 
949
    public void mouseReleased(MouseEvent anEvent)
950
    {
951
      comboBox.setSelectedIndex(list.getSelectedIndex());
952
      hide();
953
    }
954
  }
955
 
956
  /**
957
   * ListMouseMotionHandler listens to mouse motion events occuring in the
958
   * combo box's list. This class is responsible for highlighting items in
959
   * the list when mouse is moved over them
960
   */
961
  protected class ListMouseMotionHandler extends MouseMotionAdapter
962
  {
963
    protected ListMouseMotionHandler()
964
    {
965
      // Nothing to do here.
966
    }
967
 
968
    public void mouseMoved(MouseEvent anEvent)
969
    {
970
      Point point = anEvent.getPoint();
971
      Rectangle visRect = new Rectangle();
972
      list.computeVisibleRect(visRect);
973
      if (visRect.contains(point))
974
        {
975
          valueIsAdjusting = true;
976
          updateListBoxSelectionForEvent(anEvent, false);
977
          valueIsAdjusting = false;
978
        }
979
    }
980
  }
981
 
982
  /**
983
   * This class listens to changes occuring in the bound properties of the
984
   * combo box
985
   */
986
  protected class PropertyChangeHandler extends Object
987
    implements PropertyChangeListener
988
  {
989
    protected PropertyChangeHandler()
990
    {
991
      // Nothing to do here.
992
    }
993
 
994
    public void propertyChange(PropertyChangeEvent e)
995
    {
996
      if (e.getPropertyName().equals("renderer"))
997
        {
998
          list.setCellRenderer(comboBox.getRenderer());
999
          if (isVisible())
1000
            hide();
1001
        }
1002
      if (e.getPropertyName().equals("model"))
1003
        {
1004
          ComboBoxModel oldModel = (ComboBoxModel) e.getOldValue();
1005
          uninstallComboBoxModelListeners(oldModel);
1006
          ComboBoxModel newModel = (ComboBoxModel) e.getNewValue();
1007
          list.setModel(newModel);
1008
          installComboBoxModelListeners(newModel);
1009
          if (comboBox.getItemCount() > 0)
1010
            comboBox.setSelectedIndex(0);
1011
          if (isVisible())
1012
            hide();
1013
        }
1014
    }
1015
  }
1016
 
1017
  // ------ private helper methods --------------------
1018
 
1019
  /**
1020
   * This method uninstalls Listeners registered with combo boxes list of
1021
   * items
1022
   */
1023
  private void uninstallListListeners()
1024
  {
1025
    list.removeMouseListener(listMouseListener);
1026
    listMouseListener = null;
1027
 
1028
    list.removeMouseMotionListener(listMouseMotionListener);
1029
    listMouseMotionListener = null;
1030
  }
1031
 
1032
  void syncListSelection()
1033
  {
1034
    int index = comboBox.getSelectedIndex();
1035
    if (index == -1)
1036
      list.clearSelection();
1037
    else
1038
      list.setSelectedIndex(index);
1039
  }
1040
 
1041
  // --------------------------------------------------------------------
1042
  //  The following classes are here only for backwards API compatibility
1043
  //  They aren't used.
1044
  // --------------------------------------------------------------------
1045
 
1046
  /**
1047
   * This class is not used any more.
1048
   */
1049
  public class ListDataHandler extends Object implements ListDataListener
1050
  {
1051
    public ListDataHandler()
1052
    {
1053
      // Nothing to do here.
1054
    }
1055
 
1056
    public void contentsChanged(ListDataEvent e)
1057
    {
1058
      // Nothing to do here.
1059
    }
1060
 
1061
    public void intervalAdded(ListDataEvent e)
1062
    {
1063
      // Nothing to do here.
1064
    }
1065
 
1066
    public void intervalRemoved(ListDataEvent e)
1067
    {
1068
      // Nothing to do here.
1069
    }
1070
  }
1071
 
1072
  /**
1073
   * This class is not used anymore
1074
   */
1075
  protected class ListSelectionHandler extends Object
1076
    implements ListSelectionListener
1077
  {
1078
    protected ListSelectionHandler()
1079
    {
1080
      // Nothing to do here.
1081
    }
1082
 
1083
    public void valueChanged(ListSelectionEvent e)
1084
    {
1085
      // Nothing to do here.
1086
    }
1087
  }
1088
 
1089
  /**
1090
   * This class is not used anymore
1091
   */
1092
  public class InvocationKeyHandler extends KeyAdapter
1093
  {
1094
    public InvocationKeyHandler()
1095
    {
1096
      // Nothing to do here.
1097
    }
1098
 
1099
    public void keyReleased(KeyEvent e)
1100
    {
1101
      // Nothing to do here.
1102
    }
1103
  }
1104
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.