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

Subversion Repositories openrisc

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* BasicListUI.java --
2
   Copyright (C) 2002, 2004, 2005, 2006 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.Component;
42
import java.awt.Dimension;
43
import java.awt.Graphics;
44
import java.awt.Insets;
45
import java.awt.Point;
46
import java.awt.Rectangle;
47
import java.awt.event.ActionEvent;
48
import java.awt.event.ActionListener;
49
import java.awt.event.FocusEvent;
50
import java.awt.event.FocusListener;
51
import java.awt.event.MouseEvent;
52
import java.beans.PropertyChangeEvent;
53
import java.beans.PropertyChangeListener;
54
 
55
import javax.swing.AbstractAction;
56
import javax.swing.ActionMap;
57
import javax.swing.CellRendererPane;
58
import javax.swing.DefaultListSelectionModel;
59
import javax.swing.InputMap;
60
import javax.swing.JComponent;
61
import javax.swing.JList;
62
import javax.swing.ListCellRenderer;
63
import javax.swing.ListModel;
64
import javax.swing.ListSelectionModel;
65
import javax.swing.LookAndFeel;
66
import javax.swing.SwingUtilities;
67
import javax.swing.TransferHandler;
68
import javax.swing.UIDefaults;
69
import javax.swing.UIManager;
70
import javax.swing.event.ListDataEvent;
71
import javax.swing.event.ListDataListener;
72
import javax.swing.event.ListSelectionEvent;
73
import javax.swing.event.ListSelectionListener;
74
import javax.swing.event.MouseInputListener;
75
import javax.swing.plaf.ActionMapUIResource;
76
import javax.swing.plaf.ComponentUI;
77
import javax.swing.plaf.ListUI;
78
import javax.swing.plaf.UIResource;
79
 
80
/**
81
 * The Basic Look and Feel UI delegate for the
82
 * JList.
83
 */
84
public class BasicListUI extends ListUI
85
{
86
 
87
  /**
88
   * A helper class which listens for {@link FocusEvent}s
89
   * from the JList.
90
   */
91
  public class FocusHandler implements FocusListener
92
  {
93
    /**
94
     * Called when the JList acquires focus.
95
     *
96
     * @param e The FocusEvent representing focus acquisition
97
     */
98
    public void focusGained(FocusEvent e)
99
    {
100
      repaintCellFocus();
101
    }
102
 
103
    /**
104
     * Called when the JList loses focus.
105
     *
106
     * @param e The FocusEvent representing focus loss
107
     */
108
    public void focusLost(FocusEvent e)
109
    {
110
      repaintCellFocus();
111
    }
112
 
113
    /**
114
     * Helper method to repaint the focused cell's
115
     * lost or acquired focus state.
116
     */
117
    protected void repaintCellFocus()
118
    {
119
      // TODO: Implement this properly.
120
    }
121
  }
122
 
123
  /**
124
   * A helper class which listens for {@link ListDataEvent}s generated by
125
   * the {@link JList}'s {@link ListModel}.
126
   *
127
   * @see javax.swing.JList#getModel()
128
   */
129
  public class ListDataHandler implements ListDataListener
130
  {
131
    /**
132
     * Called when a general change has happened in the model which cannot
133
     * be represented in terms of a simple addition or deletion.
134
     *
135
     * @param e The event representing the change
136
     */
137
    public void contentsChanged(ListDataEvent e)
138
    {
139
      updateLayoutStateNeeded |= modelChanged;
140
      list.revalidate();
141
    }
142
 
143
    /**
144
     * Called when an interval of objects has been added to the model.
145
     *
146
     * @param e The event representing the addition
147
     */
148
    public void intervalAdded(ListDataEvent e)
149
    {
150
      updateLayoutStateNeeded |= modelChanged;
151
      list.revalidate();
152
    }
153
 
154
    /**
155
     * Called when an inteval of objects has been removed from the model.
156
     *
157
     * @param e The event representing the removal
158
     */
159
    public void intervalRemoved(ListDataEvent e)
160
    {
161
      updateLayoutStateNeeded |= modelChanged;
162
      list.revalidate();
163
    }
164
  }
165
 
166
  /**
167
   * A helper class which listens for {@link ListSelectionEvent}s
168
   * from the {@link JList}'s {@link ListSelectionModel}.
169
   */
170
  public class ListSelectionHandler implements ListSelectionListener
171
  {
172
    /**
173
     * Called when the list selection changes.
174
     *
175
     * @param e The event representing the change
176
     */
177
    public void valueChanged(ListSelectionEvent e)
178
    {
179
      int index1 = e.getFirstIndex();
180
      int index2 = e.getLastIndex();
181
      Rectangle damaged = getCellBounds(list, index1, index2);
182
      if (damaged != null)
183
        list.repaint(damaged);
184
    }
185
  }
186
 
187
  /**
188
   * This class is used to mimmic the behaviour of the JDK when registering
189
   * keyboard actions.  It is the same as the private class used in JComponent
190
   * for the same reason.  This class receives an action event and dispatches
191
   * it to the true receiver after altering the actionCommand property of the
192
   * event.
193
   */
194
  private static class ActionListenerProxy
195
    extends AbstractAction
196
  {
197
    ActionListener target;
198
    String bindingCommandName;
199
 
200
    public ActionListenerProxy(ActionListener li,
201
                               String cmd)
202
    {
203
      target = li;
204
      bindingCommandName = cmd;
205
    }
206
 
207
    public void actionPerformed(ActionEvent e)
208
    {
209
      ActionEvent derivedEvent = new ActionEvent(e.getSource(),
210
                                                 e.getID(),
211
                                                 bindingCommandName,
212
                                                 e.getModifiers());
213
      target.actionPerformed(derivedEvent);
214
    }
215
  }
216
 
217
  /**
218
   * Implements the action for the JList's keyboard commands.
219
   */
220
  private class ListAction
221
    extends AbstractAction
222
  {
223
    // TODO: Maybe make a couple of classes out of this bulk Action.
224
    // Form logical groups of Actions when doing this.
225
 
226
    /**
227
     * Creates a new ListAction for the specified command.
228
     *
229
     * @param cmd the actionCommand to set
230
     */
231
    ListAction(String cmd)
232
    {
233
      putValue(ACTION_COMMAND_KEY, cmd);
234
    }
235
 
236
    public void actionPerformed(ActionEvent e)
237
    {
238
      int lead = list.getLeadSelectionIndex();
239
      int max = list.getModel().getSize() - 1;
240
      DefaultListSelectionModel selModel
241
          = (DefaultListSelectionModel) list.getSelectionModel();
242
      String command = e.getActionCommand();
243
      // Do nothing if list is empty
244
      if (max == -1)
245
        return;
246
 
247
      if (command.equals("selectNextRow"))
248
        {
249
          selectNextIndex();
250
        }
251
      else if (command.equals("selectPreviousRow"))
252
        {
253
          selectPreviousIndex();
254
        }
255
      else if (command.equals("clearSelection"))
256
        {
257
          list.clearSelection();
258
        }
259
      else if (command.equals("selectAll"))
260
        {
261
          list.setSelectionInterval(0, max);
262
          // this next line is to restore the lead selection index to the old
263
          // position, because select-all should not change the lead index
264
          list.addSelectionInterval(lead, lead);
265
        }
266
      else if (command.equals("selectLastRow"))
267
        {
268
          list.setSelectedIndex(list.getModel().getSize() - 1);
269
        }
270
      else if (command.equals("selectLastRowChangeLead"))
271
        {
272
          selModel.moveLeadSelectionIndex(list.getModel().getSize() - 1);
273
        }
274
      else if (command.equals("scrollDownExtendSelection"))
275
        {
276
          int target;
277
          if (lead == list.getLastVisibleIndex())
278
            {
279
              target = Math.min(max, lead + (list.getLastVisibleIndex()
280
                  - list.getFirstVisibleIndex() + 1));
281
            }
282
          else
283
            target = list.getLastVisibleIndex();
284
          selModel.setLeadSelectionIndex(target);
285
        }
286
      else if (command.equals("scrollDownChangeLead"))
287
        {
288
          int target;
289
          if (lead == list.getLastVisibleIndex())
290
            {
291
              target = Math.min(max, lead + (list.getLastVisibleIndex()
292
                  - list.getFirstVisibleIndex() + 1));
293
            }
294
          else
295
            target = list.getLastVisibleIndex();
296
          selModel.moveLeadSelectionIndex(target);
297
        }
298
      else if (command.equals("scrollUpExtendSelection"))
299
        {
300
          int target;
301
          if (lead == list.getFirstVisibleIndex())
302
            {
303
              target = Math.max(0, lead - (list.getLastVisibleIndex()
304
                  - list.getFirstVisibleIndex() + 1));
305
            }
306
          else
307
            target = list.getFirstVisibleIndex();
308
          selModel.setLeadSelectionIndex(target);
309
        }
310
      else if (command.equals("scrollUpChangeLead"))
311
        {
312
          int target;
313
          if (lead == list.getFirstVisibleIndex())
314
            {
315
              target = Math.max(0, lead - (list.getLastVisibleIndex()
316
                  - list.getFirstVisibleIndex() + 1));
317
            }
318
          else
319
            target = list.getFirstVisibleIndex();
320
          selModel.moveLeadSelectionIndex(target);
321
        }
322
      else if (command.equals("selectNextRowExtendSelection"))
323
        {
324
          selModel.setLeadSelectionIndex(Math.min(lead + 1, max));
325
        }
326
      else if (command.equals("selectFirstRow"))
327
        {
328
          list.setSelectedIndex(0);
329
        }
330
      else if (command.equals("selectFirstRowChangeLead"))
331
        {
332
          selModel.moveLeadSelectionIndex(0);
333
        }
334
      else if (command.equals("selectFirstRowExtendSelection"))
335
        {
336
          selModel.setLeadSelectionIndex(0);
337
        }
338
      else if (command.equals("selectPreviousRowExtendSelection"))
339
        {
340
          selModel.setLeadSelectionIndex(Math.max(0, lead - 1));
341
        }
342
      else if (command.equals("scrollUp"))
343
        {
344
          int target;
345
          if (lead == list.getFirstVisibleIndex())
346
            {
347
              target = Math.max(0, lead - (list.getLastVisibleIndex()
348
                  - list.getFirstVisibleIndex() + 1));
349
            }
350
          else
351
            target = list.getFirstVisibleIndex();
352
          list.setSelectedIndex(target);
353
        }
354
      else if (command.equals("selectLastRowExtendSelection"))
355
        {
356
          selModel.setLeadSelectionIndex(list.getModel().getSize() - 1);
357
        }
358
      else if (command.equals("scrollDown"))
359
        {
360
          int target;
361
          if (lead == list.getLastVisibleIndex())
362
            {
363
              target = Math.min(max, lead + (list.getLastVisibleIndex()
364
                  - list.getFirstVisibleIndex() + 1));
365
            }
366
          else
367
            target = list.getLastVisibleIndex();
368
          list.setSelectedIndex(target);
369
        }
370
      else if (command.equals("selectNextRowChangeLead"))
371
          {
372
            if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
373
              selectNextIndex();
374
            else
375
              {
376
                selModel.moveLeadSelectionIndex(Math.min(max, lead + 1));
377
              }
378
          }
379
      else if (command.equals("selectPreviousRowChangeLead"))
380
        {
381
          if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
382
            selectPreviousIndex();
383
          else
384
            {
385
              selModel.moveLeadSelectionIndex(Math.max(0, lead - 1));
386
            }
387
        }
388
      else if (command.equals("addToSelection"))
389
        {
390
          list.addSelectionInterval(lead, lead);
391
        }
392
      else if (command.equals("extendTo"))
393
        {
394
          selModel.setSelectionInterval(selModel.getAnchorSelectionIndex(),
395
                                        lead);
396
        }
397
      else if (command.equals("toggleAndAnchor"))
398
        {
399
          if (!list.isSelectedIndex(lead))
400
            list.addSelectionInterval(lead, lead);
401
          else
402
            list.removeSelectionInterval(lead, lead);
403
          selModel.setAnchorSelectionIndex(lead);
404
        }
405
      else
406
        {
407
          // DEBUG: uncomment the following line to print out
408
          // key bindings that aren't implemented yet
409
 
410
          // System.out.println ("not implemented: "+e.getActionCommand());
411
        }
412
 
413
      list.ensureIndexIsVisible(list.getLeadSelectionIndex());
414
    }
415
  }
416
 
417
  /**
418
   * A helper class which listens for {@link MouseEvent}s
419
   * from the {@link JList}.
420
   */
421
  public class MouseInputHandler implements MouseInputListener
422
  {
423
    /**
424
     * Called when a mouse button press/release cycle completes
425
     * on the {@link JList}
426
     *
427
     * @param event The event representing the mouse click
428
     */
429
    public void mouseClicked(MouseEvent event)
430
    {
431
      Point click = event.getPoint();
432
      int index = locationToIndex(list, click);
433
      if (index == -1)
434
        return;
435
      if (event.isShiftDown())
436
        {
437
          if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
438
            list.setSelectedIndex(index);
439
          else if (list.getSelectionMode() ==
440
                   ListSelectionModel.SINGLE_INTERVAL_SELECTION)
441
            // COMPAT: the IBM VM is compatible with the following line of code.
442
            // However, compliance with Sun's VM would correspond to replacing
443
            // getAnchorSelectionIndex() with getLeadSelectionIndex().This is
444
            // both unnatural and contradictory to the way they handle other
445
            // similar UI interactions.
446
            list.setSelectionInterval(list.getAnchorSelectionIndex(), index);
447
          else
448
            // COMPAT: both Sun and IBM are compatible instead with:
449
            // list.setSelectionInterval
450
            //     (list.getLeadSelectionIndex(),index);
451
            // Note that for IBM this is contradictory to what they did in
452
            // the above situation for SINGLE_INTERVAL_SELECTION.
453
            // The most natural thing to do is the following:
454
            if (list.isSelectedIndex(list.getAnchorSelectionIndex()))
455
              list.getSelectionModel().setLeadSelectionIndex(index);
456
            else
457
              list.addSelectionInterval(list.getAnchorSelectionIndex(), index);
458
        }
459
      else if (event.isControlDown())
460
        {
461
          if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
462
            list.setSelectedIndex(index);
463
          else if (list.isSelectedIndex(index))
464
            list.removeSelectionInterval(index, index);
465
          else
466
            list.addSelectionInterval(index, index);
467
        }
468
      else
469
        list.setSelectedIndex(index);
470
 
471
      list.ensureIndexIsVisible(list.getLeadSelectionIndex());
472
    }
473
 
474
    /**
475
     * Called when a mouse button is pressed down on the
476
     * {@link JList}.
477
     *
478
     * @param event The event representing the mouse press
479
     */
480
    public void mousePressed(MouseEvent event)
481
    {
482
      // We need to explicitly request focus.
483
      list.requestFocusInWindow();
484
    }
485
 
486
    /**
487
     * Called when a mouse button is released on
488
     * the {@link JList}
489
     *
490
     * @param event The event representing the mouse press
491
     */
492
    public void mouseReleased(MouseEvent event)
493
    {
494
      // TODO: What should be done here, if anything?
495
    }
496
 
497
    /**
498
     * Called when the mouse pointer enters the area bounded
499
     * by the {@link JList}
500
     *
501
     * @param event The event representing the mouse entry
502
     */
503
    public void mouseEntered(MouseEvent event)
504
    {
505
      // TODO: What should be done here, if anything?
506
    }
507
 
508
    /**
509
     * Called when the mouse pointer leaves the area bounded
510
     * by the {@link JList}
511
     *
512
     * @param event The event representing the mouse exit
513
     */
514
    public void mouseExited(MouseEvent event)
515
    {
516
      // TODO: What should be done here, if anything?
517
    }
518
 
519
    /**
520
     * Called when the mouse pointer moves over the area bounded
521
     * by the {@link JList} while a button is held down.
522
     *
523
     * @param event The event representing the mouse drag
524
     */
525
    public void mouseDragged(MouseEvent event)
526
    {
527
      Point click = event.getPoint();
528
      int index = locationToIndex(list, click);
529
      if (index == -1)
530
        return;
531
      if (!event.isShiftDown() && !event.isControlDown())
532
        list.setSelectedIndex(index);
533
 
534
      list.ensureIndexIsVisible(list.getLeadSelectionIndex());
535
    }
536
 
537
    /**
538
     * Called when the mouse pointer moves over the area bounded
539
     * by the {@link JList}.
540
     *
541
     * @param event The event representing the mouse move
542
     */
543
    public void mouseMoved(MouseEvent event)
544
    {
545
      // TODO: What should be done here, if anything?
546
    }
547
  }
548
 
549
  /**
550
   * Helper class which listens to {@link PropertyChangeEvent}s
551
   * from the {@link JList}.
552
   */
553
  public class PropertyChangeHandler implements PropertyChangeListener
554
  {
555
    /**
556
     * Called when the {@link JList} changes one of its bound properties.
557
     *
558
     * @param e The event representing the property change
559
     */
560
    public void propertyChange(PropertyChangeEvent e)
561
    {
562
      if (e.getPropertyName().equals("model"))
563
        {
564
          if (e.getOldValue() != null && e.getOldValue() instanceof ListModel)
565
            {
566
              ListModel oldModel = (ListModel) e.getOldValue();
567
              oldModel.removeListDataListener(listDataListener);
568
            }
569
          if (e.getNewValue() != null && e.getNewValue() instanceof ListModel)
570
            {
571
              ListModel newModel = (ListModel) e.getNewValue();
572
              newModel.addListDataListener(BasicListUI.this.listDataListener);
573
            }
574
 
575
          updateLayoutStateNeeded |= modelChanged;
576
        }
577
      else if (e.getPropertyName().equals("selectionModel"))
578
        updateLayoutStateNeeded |= selectionModelChanged;
579
      else if (e.getPropertyName().equals("font"))
580
        updateLayoutStateNeeded |= fontChanged;
581
      else if (e.getPropertyName().equals("fixedCellWidth"))
582
        updateLayoutStateNeeded |= fixedCellWidthChanged;
583
      else if (e.getPropertyName().equals("fixedCellHeight"))
584
        updateLayoutStateNeeded |= fixedCellHeightChanged;
585
      else if (e.getPropertyName().equals("prototypeCellValue"))
586
        updateLayoutStateNeeded |= prototypeCellValueChanged;
587
      else if (e.getPropertyName().equals("cellRenderer"))
588
        updateLayoutStateNeeded |= cellRendererChanged;
589
    }
590
  }
591
 
592
  /**
593
   * A constant to indicate that the model has changed.
594
   */
595
  protected static final int modelChanged = 1;
596
 
597
  /**
598
   * A constant to indicate that the selection model has changed.
599
   */
600
  protected static final int selectionModelChanged = 2;
601
 
602
  /**
603
   * A constant to indicate that the font has changed.
604
   */
605
  protected static final int fontChanged = 4;
606
 
607
  /**
608
   * A constant to indicate that the fixedCellWidth has changed.
609
   */
610
  protected static final int fixedCellWidthChanged = 8;
611
 
612
  /**
613
   * A constant to indicate that the fixedCellHeight has changed.
614
   */
615
  protected static final int fixedCellHeightChanged = 16;
616
 
617
  /**
618
   * A constant to indicate that the prototypeCellValue has changed.
619
   */
620
  protected static final int prototypeCellValueChanged = 32;
621
 
622
  /**
623
   * A constant to indicate that the cellRenderer has changed.
624
   */
625
  protected static final int cellRendererChanged = 64;
626
 
627
  /**
628
   * Creates a new BasicListUI for the component.
629
   *
630
   * @param c The component to create a UI for
631
   *
632
   * @return A new UI
633
   */
634
  public static ComponentUI createUI(final JComponent c)
635
  {
636
    return new BasicListUI();
637
  }
638
 
639
  /** The current focus listener. */
640
  protected FocusListener focusListener;
641
 
642
  /** The data listener listening to the model. */
643
  protected ListDataListener listDataListener;
644
 
645
  /** The selection listener listening to the selection model. */
646
  protected ListSelectionListener listSelectionListener;
647
 
648
  /** The mouse listener listening to the list. */
649
  protected MouseInputListener mouseInputListener;
650
 
651
  /** The property change listener listening to the list. */
652
  protected PropertyChangeListener propertyChangeListener;
653
 
654
  /** Saved reference to the list this UI was created for. */
655
  protected JList list;
656
 
657
  /**
658
   * The height of a single cell in the list. This field is used when the
659
   * fixedCellHeight property of the list is set. Otherwise this field is
660
   * set to <code>-1</code> and {@link #cellHeights} is used instead.
661
   */
662
  protected int cellHeight;
663
 
664
  /** The width of a single cell in the list. */
665
  protected int cellWidth;
666
 
667
  /**
668
   * An array of varying heights of cells in the list, in cases where each
669
   * cell might have a different height. This field is used when the
670
   * <code>fixedCellHeight</code> property of the list is not set. Otherwise
671
   * this field is <code>null</code> and {@link #cellHeight} is used.
672
   */
673
  protected int[] cellHeights;
674
 
675
  /**
676
   * A bitmask that indicates which properties of the JList have changed.
677
   * When nonzero, indicates that the UI class is out of
678
   * date with respect to the underlying list, and must recalculate the
679
   * list layout before painting or performing size calculations.
680
   *
681
   * @see #modelChanged
682
   * @see #selectionModelChanged
683
   * @see #fontChanged
684
   * @see #fixedCellWidthChanged
685
   * @see #fixedCellHeightChanged
686
   * @see #prototypeCellValueChanged
687
   * @see #cellRendererChanged
688
   */
689
  protected int updateLayoutStateNeeded;
690
 
691
  /**
692
   * The {@link CellRendererPane} that is used for painting.
693
   */
694
  protected CellRendererPane rendererPane;
695
 
696
  /** The action bound to KeyStrokes. */
697
  ListAction action;
698
 
699
  /**
700
   * Calculate the height of a particular row. If there is a fixed {@link
701
   * #cellHeight}, return it; otherwise return the specific row height
702
   * requested from the {@link #cellHeights} array. If the requested row
703
   * is invalid, return <code>-1</code>.
704
   *
705
   * @param row The row to get the height of
706
   *
707
   * @return The height, in pixels, of the specified row
708
   */
709
  protected int getRowHeight(int row)
710
  {
711
    int height;
712
    if (cellHeights == null)
713
      height = cellHeight;
714
    else
715
      {
716
        if (row < 0 || row >= cellHeights.length)
717
          height = -1;
718
        else
719
          height = cellHeights[row];
720
      }
721
    return height;
722
  }
723
 
724
  /**
725
   * Calculate the bounds of a particular cell, considering the upper left
726
   * corner of the list as the origin position <code>(0,0)</code>.
727
   *
728
   * @param l Ignored; calculates over <code>this.list</code>
729
   * @param index1 The first row to include in the bounds
730
   * @param index2 The last row to incude in the bounds
731
   *
732
   * @return A rectangle encompassing the range of rows between
733
   * <code>index1</code> and <code>index2</code> inclusive, or null
734
   * such a rectangle couldn't be calculated for the given indexes.
735
   */
736
  public Rectangle getCellBounds(JList l, int index1, int index2)
737
  {
738
    maybeUpdateLayoutState();
739
 
740
    if (l != list || cellWidth == -1)
741
      return null;
742
 
743
    int minIndex = Math.min(index1, index2);
744
    int maxIndex = Math.max(index1, index2);
745
    Point loc = indexToLocation(list, minIndex);
746
 
747
    // When the layoutOrientation is VERTICAL, then the width == the list
748
    // width. Otherwise the cellWidth field is used.
749
    int width = cellWidth;
750
    if (l.getLayoutOrientation() == JList.VERTICAL)
751
      width = l.getWidth();
752
 
753
    Rectangle bounds = new Rectangle(loc.x, loc.y, width,
754
                                     getCellHeight(minIndex));
755
    for (int i = minIndex + 1; i <= maxIndex; i++)
756
      {
757
        Point hiLoc = indexToLocation(list, i);
758
        bounds = SwingUtilities.computeUnion(hiLoc.x, hiLoc.y, width,
759
                                             getCellHeight(i), bounds);
760
      }
761
 
762
    return bounds;
763
  }
764
 
765
  /**
766
   * Calculates the maximum cell height.
767
   *
768
   * @param index the index of the cell
769
   *
770
   * @return the maximum cell height
771
   */
772
  private int getCellHeight(int index)
773
  {
774
    int height = cellHeight;
775
    if (height <= 0)
776
      {
777
        if (list.getLayoutOrientation() == JList.VERTICAL)
778
          height = getRowHeight(index);
779
        else
780
          {
781
            for (int j = 0; j < cellHeights.length; j++)
782
              height = Math.max(height, cellHeights[j]);
783
          }
784
      }
785
    return height;
786
  }
787
 
788
  /**
789
   * Calculate the Y coordinate of the upper edge of a particular row,
790
   * considering the Y coordinate <code>0</code> to occur at the top of the
791
   * list.
792
   *
793
   * @param row The row to calculate the Y coordinate of
794
   *
795
   * @return The Y coordinate of the specified row, or <code>-1</code> if
796
   * the specified row number is invalid
797
   */
798
  protected int convertRowToY(int row)
799
  {
800
    int y = 0;
801
    for (int i = 0; i < row; ++i)
802
      {
803
        int h = getRowHeight(i);
804
        if (h == -1)
805
          return -1;
806
        y += h;
807
      }
808
    return y;
809
  }
810
 
811
  /**
812
   * Calculate the row number containing a particular Y coordinate,
813
   * considering the Y coodrinate <code>0</code> to occur at the top of the
814
   * list.
815
   *
816
   * @param y0 The Y coordinate to calculate the row number for
817
   *
818
   * @return The row number containing the specified Y value, or <code>-1</code>
819
   *         if the list model is empty
820
   *
821
   * @specnote This method is specified to return -1 for an invalid Y
822
   *           coordinate. However, some simple tests show that the behaviour
823
   *           is to return the index of the last list element for an Y
824
   *           coordinate that lies outside of the list bounds (even for
825
   *           negative indices). <code>-1</code>
826
   *           is only returned if the list model is empty.
827
   */
828
  protected int convertYToRow(int y0)
829
  {
830
    if (list.getModel().getSize() == 0)
831
      return -1;
832
 
833
    // When y0 < 0, then the JDK returns the maximum row index of the list. So
834
    // do we.
835
    if (y0 < 0)
836
      return list.getModel().getSize() - 1;
837
 
838
    // Update the layout if necessary.
839
    maybeUpdateLayoutState();
840
 
841
    int index = list.getModel().getSize() - 1;
842
 
843
    // If a fixed cell height is set, then we can work more efficient.
844
    if (cellHeight > 0)
845
      index = Math.min(y0 / cellHeight, index);
846
    // If we have no fixed cell height, we must add up each cell height up
847
    // to y0.
848
    else
849
      {
850
        int h = 0;
851
        for (int row = 0; row < cellHeights.length; ++row)
852
          {
853
            h += cellHeights[row];
854
            if (y0 < h)
855
              {
856
                index = row;
857
                break;
858
              }
859
          }
860
      }
861
    return index;
862
  }
863
 
864
  /**
865
   * Recomputes the {@link #cellHeights}, {@link #cellHeight}, and {@link
866
   * #cellWidth} properties by examining the variouis properties of the
867
   * {@link JList}.
868
   */
869
  protected void updateLayoutState()
870
  {
871
    int nrows = list.getModel().getSize();
872
    cellHeight = -1;
873
    cellWidth = -1;
874
    if (cellHeights == null || cellHeights.length != nrows)
875
      cellHeights = new int[nrows];
876
    ListCellRenderer rend = list.getCellRenderer();
877
    // Update the cellHeight(s) fields.
878
    int fixedCellHeight = list.getFixedCellHeight();
879
    if (fixedCellHeight > 0)
880
      {
881
        cellHeight = fixedCellHeight;
882
        cellHeights = null;
883
      }
884
    else
885
      {
886
        cellHeight = -1;
887
        for (int i = 0; i < nrows; ++i)
888
          {
889
            Component flyweight =
890
              rend.getListCellRendererComponent(list,
891
                      list.getModel().getElementAt(i),
892
                      i, list.isSelectedIndex(i),
893
                      list.getSelectionModel().getAnchorSelectionIndex() == i);
894
            Dimension dim = flyweight.getPreferredSize();
895
            cellHeights[i] = dim.height;
896
          }
897
      }
898
 
899
    // Update the cellWidth field.
900
    int fixedCellWidth = list.getFixedCellWidth();
901
    if (fixedCellWidth > 0)
902
      cellWidth = fixedCellWidth;
903
    else
904
      {
905
        for (int i = 0; i < nrows; ++i)
906
          {
907
            Component flyweight =
908
              rend.getListCellRendererComponent(list,
909
                                                list.getModel().getElementAt(i),
910
                                                i, list.isSelectedIndex(i),
911
                                                list.getSelectionModel().getAnchorSelectionIndex() == i);
912
            Dimension dim = flyweight.getPreferredSize();
913
            cellWidth = Math.max(cellWidth, dim.width);
914
          }
915
      }
916
  }
917
 
918
  /**
919
   * Calls {@link #updateLayoutState} if {@link #updateLayoutStateNeeded}
920
   * is nonzero, then resets {@link #updateLayoutStateNeeded} to zero.
921
   */
922
  protected void maybeUpdateLayoutState()
923
  {
924
    if (updateLayoutStateNeeded != 0 || !list.isValid())
925
      {
926
        updateLayoutState();
927
        updateLayoutStateNeeded = 0;
928
      }
929
  }
930
 
931
  /**
932
   * Creates a new BasicListUI object.
933
   */
934
  public BasicListUI()
935
  {
936
    updateLayoutStateNeeded = 1;
937
    rendererPane = new CellRendererPane();
938
  }
939
 
940
  /**
941
   * Installs various default settings (mostly colors) from the {@link
942
   * UIDefaults} into the {@link JList}
943
   *
944
   * @see #uninstallDefaults
945
   */
946
  protected void installDefaults()
947
  {
948
    LookAndFeel.installColorsAndFont(list, "List.background",
949
                                     "List.foreground", "List.font");
950
    list.setSelectionForeground(UIManager.getColor("List.selectionForeground"));
951
    list.setSelectionBackground(UIManager.getColor("List.selectionBackground"));
952
    list.setOpaque(true);
953
  }
954
 
955
  /**
956
   * Resets to <code>null</code> those defaults which were installed in
957
   * {@link #installDefaults}
958
   */
959
  protected void uninstallDefaults()
960
  {
961
    list.setForeground(null);
962
    list.setBackground(null);
963
    list.setSelectionForeground(null);
964
    list.setSelectionBackground(null);
965
  }
966
 
967
  /**
968
   * Attaches all the listeners we have in the UI class to the {@link
969
   * JList}, its model and its selection model.
970
   *
971
   * @see #uninstallListeners
972
   */
973
  protected void installListeners()
974
  {
975
    if (focusListener == null)
976
      focusListener = createFocusListener();
977
    list.addFocusListener(focusListener);
978
    if (listDataListener == null)
979
      listDataListener = createListDataListener();
980
    list.getModel().addListDataListener(listDataListener);
981
    if (listSelectionListener == null)
982
      listSelectionListener = createListSelectionListener();
983
    list.addListSelectionListener(listSelectionListener);
984
    if (mouseInputListener == null)
985
      mouseInputListener = createMouseInputListener();
986
    list.addMouseListener(mouseInputListener);
987
    list.addMouseMotionListener(mouseInputListener);
988
    if (propertyChangeListener == null)
989
      propertyChangeListener = createPropertyChangeListener();
990
    list.addPropertyChangeListener(propertyChangeListener);
991
  }
992
 
993
  /**
994
   * Detaches all the listeners we attached in {@link #installListeners}.
995
   */
996
  protected void uninstallListeners()
997
  {
998
    list.removeFocusListener(focusListener);
999
    list.getModel().removeListDataListener(listDataListener);
1000
    list.removeListSelectionListener(listSelectionListener);
1001
    list.removeMouseListener(mouseInputListener);
1002
    list.removeMouseMotionListener(mouseInputListener);
1003
    list.removePropertyChangeListener(propertyChangeListener);
1004
  }
1005
 
1006
  /**
1007
   * Installs keyboard actions for this UI in the {@link JList}.
1008
   */
1009
  protected void installKeyboardActions()
1010
  {
1011
    // Install UI InputMap.
1012
    InputMap focusInputMap = (InputMap) UIManager.get("List.focusInputMap");
1013
    SwingUtilities.replaceUIInputMap(list, JComponent.WHEN_FOCUSED,
1014
                                     focusInputMap);
1015
 
1016
    // Install UI ActionMap.
1017
    ActionMap am = (ActionMap) UIManager.get("List.actionMap");
1018
    if (am == null)
1019
      {
1020
        // Create the actionMap once and store it in the current UIDefaults
1021
        // for use in other components.
1022
        am = new ActionMapUIResource();
1023
        ListAction action;
1024
        action = new ListAction("selectPreviousRow");
1025
        am.put("selectPreviousRow", action);
1026
        action = new ListAction("selectNextRow");
1027
        am.put("selectNextRow", action);
1028
        action = new ListAction("selectPreviousRowExtendSelection");
1029
        am.put("selectPreviousRowExtendSelection", action);
1030
        action = new ListAction("selectNextRowExtendSelection");
1031
        am.put("selectNextRowExtendSelection", action);
1032
 
1033
        action = new ListAction("selectPreviousColumn");
1034
        am.put("selectPreviousColumn", action);
1035
        action = new ListAction("selectNextColumn");
1036
        am.put("selectNextColumn", action);
1037
        action = new ListAction("selectPreviousColumnExtendSelection");
1038
        am.put("selectPreviousColumnExtendSelection", action);
1039
        action = new ListAction("selectNextColumnExtendSelection");
1040
        am.put("selectNextColumnExtendSelection", action);
1041
 
1042
        action = new ListAction("selectFirstRow");
1043
        am.put("selectFirstRow", action);
1044
        action = new ListAction("selectLastRow");
1045
        am.put("selectLastRow", action);
1046
        action = new ListAction("selectFirstRowExtendSelection");
1047
        am.put("selectFirstRowExtendSelection", action);
1048
        action = new ListAction("selectLastRowExtendSelection");
1049
        am.put("selectLastRowExtendSelection", action);
1050
 
1051
        action = new ListAction("scrollUp");
1052
        am.put("scrollUp", action);
1053
        action = new ListAction("scrollUpExtendSelection");
1054
        am.put("scrollUpExtendSelection", action);
1055
        action = new ListAction("scrollDown");
1056
        am.put("scrollDown", action);
1057
        action = new ListAction("scrollDownExtendSelection");
1058
        am.put("scrollDownExtendSelection", action);
1059
 
1060
        action = new ListAction("selectAll");
1061
        am.put("selectAll", action);
1062
        action = new ListAction("clearSelection");
1063
        am.put("clearSelection", action);
1064
 
1065
        am.put("copy", TransferHandler.getCopyAction());
1066
        am.put("cut", TransferHandler.getCutAction());
1067
        am.put("paste", TransferHandler.getPasteAction());
1068
 
1069
        UIManager.put("List.actionMap", am);
1070
      }
1071
 
1072
    SwingUtilities.replaceUIActionMap(list, am);
1073
  }
1074
 
1075
  /**
1076
   * Uninstalls keyboard actions for this UI in the {@link JList}.
1077
   */
1078
  protected void uninstallKeyboardActions()
1079
  {
1080
    // Uninstall the InputMap.
1081
    InputMap im = SwingUtilities.getUIInputMap(list, JComponent.WHEN_FOCUSED);
1082
    if (im instanceof UIResource)
1083
      SwingUtilities.replaceUIInputMap(list, JComponent.WHEN_FOCUSED, null);
1084
 
1085
    // Uninstall the ActionMap.
1086
    if (SwingUtilities.getUIActionMap(list) instanceof UIResource)
1087
      SwingUtilities.replaceUIActionMap(list, null);
1088
  }
1089
 
1090
  /**
1091
   * Installs the various aspects of the UI in the {@link JList}. In
1092
   * particular, calls {@link #installDefaults}, {@link #installListeners}
1093
   * and {@link #installKeyboardActions}. Also saves a reference to the
1094
   * provided component, cast to a {@link JList}.
1095
   *
1096
   * @param c The {@link JList} to install the UI into
1097
   */
1098
  public void installUI(final JComponent c)
1099
  {
1100
    super.installUI(c);
1101
    list = (JList) c;
1102
    installDefaults();
1103
    installListeners();
1104
    installKeyboardActions();
1105
    maybeUpdateLayoutState();
1106
  }
1107
 
1108
  /**
1109
   * Uninstalls all the aspects of the UI which were installed in {@link
1110
   * #installUI}. When finished uninstalling, drops the saved reference to
1111
   * the {@link JList}.
1112
   *
1113
   * @param c Ignored; the UI is uninstalled from the {@link JList}
1114
   * reference saved during the call to {@link #installUI}
1115
   */
1116
  public void uninstallUI(final JComponent c)
1117
  {
1118
    uninstallKeyboardActions();
1119
    uninstallListeners();
1120
    uninstallDefaults();
1121
    list = null;
1122
  }
1123
 
1124
  /**
1125
   * Gets the size this list would prefer to assume. This is calculated by
1126
   * calling {@link #getCellBounds} over the entire list.
1127
   *
1128
   * @param c Ignored; uses the saved {@link JList} reference
1129
   *
1130
   * @return DOCUMENT ME!
1131
   */
1132
  public Dimension getPreferredSize(JComponent c)
1133
  {
1134
    maybeUpdateLayoutState();
1135
    int size = list.getModel().getSize();
1136
    int visibleRows = list.getVisibleRowCount();
1137
    int layoutOrientation = list.getLayoutOrientation();
1138
 
1139
    int h;
1140
    int w;
1141
    int maxCellHeight = cellHeight;
1142
    if (maxCellHeight <= 0)
1143
      {
1144
        for (int i = 0; i < cellHeights.length; i++)
1145
          maxCellHeight = Math.max(maxCellHeight, cellHeights[i]);
1146
      }
1147
    if (layoutOrientation == JList.HORIZONTAL_WRAP)
1148
      {
1149
        if (visibleRows > 0)
1150
          {
1151
            // We cast to double here to force double divisions.
1152
            double modelSize = size;
1153
            int neededColumns = (int) Math.ceil(modelSize / visibleRows);
1154
            int adjustedRows = (int) Math.ceil(modelSize / neededColumns);
1155
            h = maxCellHeight * adjustedRows;
1156
            w = cellWidth * neededColumns;
1157
          }
1158
        else
1159
          {
1160
            int neededColumns = Math.min(1, list.getWidth() / cellWidth);
1161
            h = size / neededColumns * maxCellHeight;
1162
            w = neededColumns * cellWidth;
1163
          }
1164
      }
1165
    else if (layoutOrientation == JList.VERTICAL_WRAP)
1166
      {
1167
        if (visibleRows > 0)
1168
          h = visibleRows * maxCellHeight;
1169
        else
1170
          h = Math.max(list.getHeight(), maxCellHeight);
1171
        int neededColumns = h / maxCellHeight;
1172
        w = cellWidth * neededColumns;
1173
      }
1174
    else
1175
      {
1176
        if (list.getFixedCellWidth() > 0)
1177
          w = list.getFixedCellWidth();
1178
        else
1179
          w = cellWidth;
1180
        if (list.getFixedCellHeight() > 0)
1181
          // FIXME: We need to add some cellVerticalMargins here, according
1182
          // to the specs.
1183
          h = list.getFixedCellHeight() * size;
1184
        else
1185
          h = maxCellHeight * size;
1186
      }
1187
    Insets insets = list.getInsets();
1188
    Dimension retVal = new Dimension(w + insets.left + insets.right,
1189
                                     h + insets.top + insets.bottom);
1190
    return retVal;
1191
  }
1192
 
1193
  /**
1194
   * Paints a single cell in the list.
1195
   *
1196
   * @param g The graphics context to paint in
1197
   * @param row The row number to paint
1198
   * @param bounds The bounds of the cell to paint, assuming a coordinate
1199
   * system beginning at <code>(0,0)</code> in the upper left corner of the
1200
   * list
1201
   * @param rend A cell renderer to paint with
1202
   * @param data The data to provide to the cell renderer
1203
   * @param sel A selection model to provide to the cell renderer
1204
   * @param lead The lead selection index of the list
1205
   */
1206
  protected void paintCell(Graphics g, int row, Rectangle bounds,
1207
                 ListCellRenderer rend, ListModel data,
1208
                 ListSelectionModel sel, int lead)
1209
  {
1210
    boolean isSel = list.isSelectedIndex(row);
1211
    boolean hasFocus = (list.getLeadSelectionIndex() == row) && BasicListUI.this.list.hasFocus();
1212
    Component comp = rend.getListCellRendererComponent(list,
1213
                                                       data.getElementAt(row),
1214
                                                       row, isSel, hasFocus);
1215
    rendererPane.paintComponent(g, comp, list, bounds);
1216
  }
1217
 
1218
  /**
1219
   * Paints the list by repeatedly calling {@link #paintCell} for each visible
1220
   * cell in the list.
1221
   *
1222
   * @param g The graphics context to paint with
1223
   * @param c Ignored; uses the saved {@link JList} reference
1224
   */
1225
  public void paint(Graphics g, JComponent c)
1226
  {
1227
    int nrows = list.getModel().getSize();
1228
    if (nrows == 0)
1229
      return;
1230
 
1231
    maybeUpdateLayoutState();
1232
    ListCellRenderer render = list.getCellRenderer();
1233
    ListModel model = list.getModel();
1234
    ListSelectionModel sel = list.getSelectionModel();
1235
    int lead = sel.getLeadSelectionIndex();
1236
    Rectangle clip = g.getClipBounds();
1237
 
1238
    int startIndex = locationToIndex(list, new Point(clip.x, clip.y));
1239
    int endIndex = locationToIndex(list, new Point(clip.x + clip.width,
1240
                                             clip.y + clip.height));
1241
 
1242
    for (int row = startIndex; row <= endIndex; ++row)
1243
      {
1244
        Rectangle bounds = getCellBounds(list, row, row);
1245
        if (bounds != null && bounds.intersects(clip))
1246
          paintCell(g, row, bounds, render, model, sel, lead);
1247
      }
1248
  }
1249
 
1250
  /**
1251
   * Computes the index of a list cell given a point within the list. If the
1252
   * location lies outside the bounds of the list, the greatest index in the
1253
   * list model is returned.
1254
   *
1255
   * @param l the list which on which the computation is based on
1256
   * @param location the coordinates
1257
   *
1258
   * @return the index of the list item that is located at the given
1259
   *         coordinates or <code>-1</code> if the list model is empty
1260
   */
1261
  public int locationToIndex(JList l, Point location)
1262
  {
1263
    int layoutOrientation = list.getLayoutOrientation();
1264
    int index = -1;
1265
    switch (layoutOrientation)
1266
      {
1267
      case JList.VERTICAL:
1268
        index = convertYToRow(location.y);
1269
        break;
1270
      case JList.HORIZONTAL_WRAP:
1271
        // determine visible rows and cells per row
1272
        int maxCellHeight = getCellHeight(0);
1273
        int visibleRows = list.getHeight() / maxCellHeight;
1274
        int cellsPerRow = -1;
1275
        int numberOfItems = list.getModel().getSize();
1276
        cellsPerRow = numberOfItems / visibleRows + 1;
1277
 
1278
        // determine index for the given location
1279
        int cellsPerColumn = numberOfItems / cellsPerRow + 1;
1280
        int gridX = Math.min(location.x / cellWidth, cellsPerRow - 1);
1281
        int gridY = Math.min(location.y / maxCellHeight, cellsPerColumn);
1282
        index = gridX + gridY * cellsPerRow;
1283
        break;
1284
      case JList.VERTICAL_WRAP:
1285
        // determine visible rows and cells per column
1286
        int maxCellHeight2 = getCellHeight(0);
1287
        int visibleRows2 = list.getHeight() / maxCellHeight2;
1288
        int numberOfItems2 = list.getModel().getSize();
1289
        int cellsPerRow2 = numberOfItems2 / visibleRows2 + 1;
1290
 
1291
        int gridX2 = Math.min(location.x / cellWidth, cellsPerRow2 - 1);
1292
        int gridY2 = Math.min(location.y / maxCellHeight2, visibleRows2);
1293
        index = gridY2 + gridX2 * visibleRows2;
1294
        break;
1295
      }
1296
    return index;
1297
  }
1298
 
1299
  public Point indexToLocation(JList l, int index)
1300
  {
1301
    int layoutOrientation = list.getLayoutOrientation();
1302
    Point loc = null;
1303
    switch (layoutOrientation)
1304
      {
1305
      case JList.VERTICAL:
1306
        loc = new Point(0, convertRowToY(index));
1307
        break;
1308
      case JList.HORIZONTAL_WRAP:
1309
        // determine visible rows and cells per row
1310
        int maxCellHeight = getCellHeight(0);
1311
        int visibleRows = list.getHeight() / maxCellHeight;
1312
        int numberOfCellsPerRow = -1;
1313
        int numberOfItems = list.getModel().getSize();
1314
        numberOfCellsPerRow = numberOfItems / visibleRows + 1;
1315
 
1316
        // compute coordinates inside the grid
1317
        int gridX = index % numberOfCellsPerRow;
1318
        int gridY = index / numberOfCellsPerRow;
1319
        int locX = gridX * cellWidth;
1320
        int locY;
1321
        locY = gridY * maxCellHeight;
1322
        loc = new Point(locX, locY);
1323
        break;
1324
      case JList.VERTICAL_WRAP:
1325
        // determine visible rows and cells per column
1326
        int maxCellHeight2 = getCellHeight(0);
1327
        int visibleRows2 = list.getHeight() / maxCellHeight2;
1328
        // compute coordinates inside the grid
1329
        if (visibleRows2 > 0)
1330
          {
1331
            int gridY2 = index % visibleRows2;
1332
            int gridX2 = index / visibleRows2;
1333
            int locX2 = gridX2 * cellWidth;
1334
            int locY2 = gridY2 * maxCellHeight2;
1335
            loc = new Point(locX2, locY2);
1336
          }
1337
        else
1338
          loc = new Point(0, convertRowToY(index));
1339
        break;
1340
      }
1341
    return loc;
1342
  }
1343
 
1344
  /**
1345
   * Creates and returns the focus listener for this UI.
1346
   *
1347
   * @return the focus listener for this UI
1348
   */
1349
  protected FocusListener createFocusListener()
1350
  {
1351
    return new FocusHandler();
1352
  }
1353
 
1354
  /**
1355
   * Creates and returns the list data listener for this UI.
1356
   *
1357
   * @return the list data listener for this UI
1358
   */
1359
  protected ListDataListener createListDataListener()
1360
  {
1361
    return new ListDataHandler();
1362
  }
1363
 
1364
  /**
1365
   * Creates and returns the list selection listener for this UI.
1366
   *
1367
   * @return the list selection listener for this UI
1368
   */
1369
  protected ListSelectionListener createListSelectionListener()
1370
  {
1371
    return new ListSelectionHandler();
1372
  }
1373
 
1374
  /**
1375
   * Creates and returns the mouse input listener for this UI.
1376
   *
1377
   * @return the mouse input listener for this UI
1378
   */
1379
  protected MouseInputListener createMouseInputListener()
1380
  {
1381
    return new MouseInputHandler();
1382
  }
1383
 
1384
  /**
1385
   * Creates and returns the property change listener for this UI.
1386
   *
1387
   * @return the property change listener for this UI
1388
   */
1389
  protected PropertyChangeListener createPropertyChangeListener()
1390
  {
1391
    return new PropertyChangeHandler();
1392
  }
1393
 
1394
  /**
1395
   * Selects the next list item and force it to be visible.
1396
   */
1397
  protected void selectNextIndex()
1398
  {
1399
    int index = list.getSelectionModel().getLeadSelectionIndex();
1400
    if (index < list.getModel().getSize() - 1)
1401
      {
1402
        index++;
1403
        list.setSelectedIndex(index);
1404
      }
1405
    list.ensureIndexIsVisible(index);
1406
  }
1407
 
1408
  /**
1409
   * Selects the previous list item and force it to be visible.
1410
   */
1411
  protected void selectPreviousIndex()
1412
  {
1413
    int index = list.getSelectionModel().getLeadSelectionIndex();
1414
    if (index > 0)
1415
      {
1416
        index--;
1417
        list.setSelectedIndex(index);
1418
      }
1419
    list.ensureIndexIsVisible(index);
1420
  }
1421
}

powered by: WebSVN 2.1.0

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