1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48: import ;
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54:
55: import ;
56: import ;
57: import ;
58: import ;
59: import ;
60: import ;
61: import ;
62: import ;
63: import ;
64: import ;
65: import ;
66: import ;
67: import ;
68: import ;
69: import ;
70: import ;
71: import ;
72: import ;
73: import ;
74: import ;
75: import ;
76: import ;
77: import ;
78:
79:
83: public class BasicListUI extends ListUI
84: {
85:
86:
90: public class FocusHandler implements FocusListener
91: {
92:
97: public void focusGained(FocusEvent e)
98: {
99: repaintCellFocus();
100: }
101:
102:
107: public void focusLost(FocusEvent e)
108: {
109: repaintCellFocus();
110: }
111:
112:
116: protected void repaintCellFocus()
117: {
118:
119: }
120: }
121:
122:
128: public class ListDataHandler implements ListDataListener
129: {
130:
136: public void contentsChanged(ListDataEvent e)
137: {
138: list.revalidate();
139: }
140:
141:
146: public void intervalAdded(ListDataEvent e)
147: {
148: list.revalidate();
149: }
150:
151:
156: public void intervalRemoved(ListDataEvent e)
157: {
158: list.revalidate();
159: }
160: }
161:
162:
166: public class ListSelectionHandler implements ListSelectionListener
167: {
168:
173: public void valueChanged(ListSelectionEvent e)
174: {
175: int index1 = e.getFirstIndex();
176: int index2 = e.getLastIndex();
177: Rectangle damaged = getCellBounds(list, index1, index2);
178: list.repaint(damaged);
179: }
180: }
181:
182:
189: private static class ActionListenerProxy
190: extends AbstractAction
191: {
192: ActionListener target;
193: String bindingCommandName;
194:
195: public ActionListenerProxy(ActionListener li,
196: String cmd)
197: {
198: target = li;
199: bindingCommandName = cmd;
200: }
201:
202: public void actionPerformed(ActionEvent e)
203: {
204: ActionEvent derivedEvent = new ActionEvent(e.getSource(),
205: e.getID(),
206: bindingCommandName,
207: e.getModifiers());
208: target.actionPerformed(derivedEvent);
209: }
210: }
211:
212: class ListAction extends AbstractAction
213: {
214: public void actionPerformed (ActionEvent e)
215: {
216: int lead = list.getLeadSelectionIndex();
217: int max = list.getModel().getSize() - 1;
218: DefaultListSelectionModel selModel = (DefaultListSelectionModel)list.getSelectionModel();
219: String command = e.getActionCommand();
220:
221: if (max == -1)
222: return;
223:
224: if (command.equals("selectNextRow"))
225: {
226: selectNextIndex();
227: }
228: else if (command.equals("selectPreviousRow"))
229: {
230: selectPreviousIndex();
231: }
232: else if (command.equals("clearSelection"))
233: {
234: list.clearSelection();
235: }
236: else if (command.equals("selectAll"))
237: {
238: list.setSelectionInterval(0, max);
239:
240:
241: list.addSelectionInterval(lead, lead);
242: }
243: else if (command.equals("selectLastRow"))
244: {
245: list.setSelectedIndex(list.getModel().getSize() - 1);
246: }
247: else if (command.equals("selectLastRowChangeLead"))
248: {
249: selModel.moveLeadSelectionIndex(list.getModel().getSize() - 1);
250: }
251: else if (command.equals("scrollDownExtendSelection"))
252: {
253: int target;
254: if (lead == list.getLastVisibleIndex())
255: {
256: target = Math.min
257: (max, lead + (list.getLastVisibleIndex() -
258: list.getFirstVisibleIndex() + 1));
259: }
260: else
261: target = list.getLastVisibleIndex();
262: selModel.setLeadSelectionIndex(target);
263: }
264: else if (command.equals("scrollDownChangeLead"))
265: {
266: int target;
267: if (lead == list.getLastVisibleIndex())
268: {
269: target = Math.min
270: (max, lead + (list.getLastVisibleIndex() -
271: list.getFirstVisibleIndex() + 1));
272: }
273: else
274: target = list.getLastVisibleIndex();
275: selModel.moveLeadSelectionIndex(target);
276: }
277: else if (command.equals("scrollUpExtendSelection"))
278: {
279: int target;
280: if (lead == list.getFirstVisibleIndex())
281: {
282: target = Math.max
283: (0, lead - (list.getLastVisibleIndex() -
284: list.getFirstVisibleIndex() + 1));
285: }
286: else
287: target = list.getFirstVisibleIndex();
288: selModel.setLeadSelectionIndex(target);
289: }
290: else if (command.equals("scrollUpChangeLead"))
291: {
292: int target;
293: if (lead == list.getFirstVisibleIndex())
294: {
295: target = Math.max
296: (0, lead - (list.getLastVisibleIndex() -
297: list.getFirstVisibleIndex() + 1));
298: }
299: else
300: target = list.getFirstVisibleIndex();
301: selModel.moveLeadSelectionIndex(target);
302: }
303: else if (command.equals("selectNextRowExtendSelection"))
304: {
305: selModel.setLeadSelectionIndex(Math.min(lead + 1,max));
306: }
307: else if (command.equals("selectFirstRow"))
308: {
309: list.setSelectedIndex(0);
310: }
311: else if (command.equals("selectFirstRowChangeLead"))
312: {
313: selModel.moveLeadSelectionIndex(0);
314: }
315: else if (command.equals("selectFirstRowExtendSelection"))
316: {
317: selModel.setLeadSelectionIndex(0);
318: }
319: else if (command.equals("selectPreviousRowExtendSelection"))
320: {
321: selModel.setLeadSelectionIndex(Math.max(0,lead - 1));
322: }
323: else if (command.equals("scrollUp"))
324: {
325: int target;
326: if (lead == list.getFirstVisibleIndex())
327: {
328: target = Math.max
329: (0, lead - (list.getLastVisibleIndex() -
330: list.getFirstVisibleIndex() + 1));
331: }
332: else
333: target = list.getFirstVisibleIndex();
334: list.setSelectedIndex(target);
335: }
336: else if (command.equals("selectLastRowExtendSelection"))
337: {
338: selModel.setLeadSelectionIndex(list.getModel().getSize() - 1);
339: }
340: else if (command.equals("scrollDown"))
341: {
342: int target;
343: if (lead == list.getLastVisibleIndex())
344: {
345: target = Math.min
346: (max, lead + (list.getLastVisibleIndex() -
347: list.getFirstVisibleIndex() + 1));
348: }
349: else
350: target = list.getLastVisibleIndex();
351: list.setSelectedIndex(target);
352: }
353: else if (command.equals("selectNextRowChangeLead"))
354: {
355: if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
356: selectNextIndex();
357: else
358: {
359: selModel.moveLeadSelectionIndex(Math.min(max, lead + 1));
360: }
361: }
362: else if (command.equals("selectPreviousRowChangeLead"))
363: {
364: if (selModel.getSelectionMode() != ListSelectionModel.MULTIPLE_INTERVAL_SELECTION)
365: selectPreviousIndex();
366: else
367: {
368: selModel.moveLeadSelectionIndex(Math.max(0, lead - 1));
369: }
370: }
371: else if (command.equals("addToSelection"))
372: {
373: list.addSelectionInterval(lead, lead);
374: }
375: else if (command.equals("extendTo"))
376: {
377: selModel.setSelectionInterval(selModel.getAnchorSelectionIndex(),
378: lead);
379: }
380: else if (command.equals("toggleAndAnchor"))
381: {
382: if (!list.isSelectedIndex(lead))
383: list.addSelectionInterval(lead, lead);
384: else
385: list.removeSelectionInterval(lead, lead);
386: selModel.setAnchorSelectionIndex(lead);
387: }
388: else
389: {
390:
391:
392:
393:
394: }
395:
396: list.ensureIndexIsVisible(list.getLeadSelectionIndex());
397: }
398: }
399:
400:
404: public class MouseInputHandler implements MouseInputListener
405: {
406:
412: public void mouseClicked(MouseEvent event)
413: {
414: Point click = event.getPoint();
415: int index = locationToIndex(list, click);
416: if (index == -1)
417: return;
418: if (event.isShiftDown())
419: {
420: if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
421: list.setSelectedIndex(index);
422: else if (list.getSelectionMode() ==
423: ListSelectionModel.SINGLE_INTERVAL_SELECTION)
424:
425:
426:
427:
428:
429: list.setSelectionInterval(list.getAnchorSelectionIndex(), index);
430: else
431:
432:
433:
434:
435:
436:
437: if (list.isSelectedIndex(list.getAnchorSelectionIndex()))
438: list.getSelectionModel().setLeadSelectionIndex(index);
439: else
440: list.addSelectionInterval(list.getAnchorSelectionIndex(), index);
441: }
442: else if (event.isControlDown())
443: {
444: if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION)
445: list.setSelectedIndex(index);
446: else if (list.isSelectedIndex(index))
447: list.removeSelectionInterval(index,index);
448: else
449: list.addSelectionInterval(index,index);
450: }
451: else
452: list.setSelectedIndex(index);
453:
454: list.ensureIndexIsVisible(list.getLeadSelectionIndex());
455: }
456:
457:
463: public void mousePressed(MouseEvent event)
464: {
465:
466: }
467:
468:
474: public void mouseReleased(MouseEvent event)
475: {
476:
477: }
478:
479:
485: public void mouseEntered(MouseEvent event)
486: {
487:
488: }
489:
490:
496: public void mouseExited(MouseEvent event)
497: {
498:
499: }
500:
501:
507: public void mouseDragged(MouseEvent event)
508: {
509: Point click = event.getPoint();
510: int index = locationToIndex(list, click);
511: if (index == -1)
512: return;
513: if (!event.isShiftDown() && !event.isControlDown())
514: list.setSelectedIndex(index);
515:
516: list.ensureIndexIsVisible(list.getLeadSelectionIndex());
517: }
518:
519:
525: public void mouseMoved(MouseEvent event)
526: {
527:
528: }
529: }
530:
531:
535: public class PropertyChangeHandler implements PropertyChangeListener
536: {
537:
542: public void propertyChange(PropertyChangeEvent e)
543: {
544: if (e.getSource() == BasicListUI.this.list)
545: {
546: if (e.getOldValue() != null && e.getOldValue() instanceof ListModel)
547: ((ListModel) e.getOldValue()).removeListDataListener(BasicListUI.this.listDataListener);
548:
549: if (e.getNewValue() != null && e.getNewValue() instanceof ListModel)
550: ((ListModel) e.getNewValue()).addListDataListener(BasicListUI.this.listDataListener);
551: }
552:
553: if (e.getPropertyName().equals("model"))
554: updateLayoutStateNeeded |= modelChanged;
555: else if (e.getPropertyName().equals("selectionModel"))
556: updateLayoutStateNeeded |= selectionModelChanged;
557: else if (e.getPropertyName().equals("font"))
558: updateLayoutStateNeeded |= fontChanged;
559: else if (e.getPropertyName().equals("fixedCellWidth"))
560: updateLayoutStateNeeded |= fixedCellWidthChanged;
561: else if (e.getPropertyName().equals("fixedCellHeight"))
562: updateLayoutStateNeeded |= fixedCellHeightChanged;
563: else if (e.getPropertyName().equals("prototypeCellValue"))
564: updateLayoutStateNeeded |= prototypeCellValueChanged;
565: else if (e.getPropertyName().equals("cellRenderer"))
566: updateLayoutStateNeeded |= cellRendererChanged;
567: }
568: }
569:
570:
573: protected static final int modelChanged = 1;
574:
575:
578: protected static final int selectionModelChanged = 2;
579:
580:
583: protected static final int fontChanged = 4;
584:
585:
588: protected static final int fixedCellWidthChanged = 8;
589:
590:
593: protected static final int fixedCellHeightChanged = 16;
594:
595:
598: protected static final int prototypeCellValueChanged = 32;
599:
600:
603: protected static final int cellRendererChanged = 64;
604:
605:
612: public static ComponentUI createUI(final JComponent c)
613: {
614: return new BasicListUI();
615: }
616:
617:
618: protected FocusListener focusListener;
619:
620:
621: protected ListDataListener listDataListener;
622:
623:
624: protected ListSelectionListener listSelectionListener;
625:
626:
627: protected MouseInputListener mouseInputListener;
628:
629:
630: protected PropertyChangeListener propertyChangeListener;
631:
632:
633: protected JList list;
634:
635:
640: protected int cellHeight;
641:
642:
643: protected int cellWidth;
644:
645:
651: protected int[] cellHeights;
652:
653:
667: protected int updateLayoutStateNeeded;
668:
669:
672: protected CellRendererPane rendererPane;
673:
674:
675: ListAction action;
676:
677:
687: protected int getRowHeight(int row)
688: {
689: int height;
690: if (cellHeights == null)
691: height = cellHeight;
692: else
693: {
694: if (row < 0 || row >= cellHeights.length)
695: height = -1;
696: else
697: height = cellHeights[row];
698: }
699: return height;
700: }
701:
702:
713: public Rectangle getCellBounds(JList l, int index1, int index2)
714: {
715: maybeUpdateLayoutState();
716:
717: if (l != list || cellWidth == -1)
718: return null;
719:
720: int minIndex = Math.min(index1, index2);
721: int maxIndex = Math.max(index1, index2);
722: Point loc = indexToLocation(list, minIndex);
723: Rectangle bounds = new Rectangle(loc.x, loc.y, cellWidth,
724: getCellHeight(minIndex));
725: for (int i = minIndex + 1; i <= maxIndex; i++)
726: {
727: Point hiLoc = indexToLocation(list, i);
728: Rectangle hibounds = new Rectangle(hiLoc.x, hiLoc.y, cellWidth,
729: getCellHeight(i));
730: bounds = bounds.union(hibounds);
731: }
732:
733: return bounds;
734: }
735:
736:
743: private int getCellHeight(int index)
744: {
745: int height = cellHeight;
746: if (height <= 0)
747: {
748: if (list.getLayoutOrientation() == JList.VERTICAL)
749: height = getRowHeight(index);
750: else
751: {
752: for (int j = 0; j < cellHeights.length; j++)
753: height = Math.max(height, cellHeights[j]);
754: }
755: }
756: return height;
757: }
758:
759:
769: protected int convertRowToY(int row)
770: {
771: int y = 0;
772: for (int i = 0; i < row; ++i)
773: {
774: int h = getRowHeight(i);
775: if (h == -1)
776: return -1;
777: y += h;
778: }
779: return y;
780: }
781:
782:
799: protected int convertYToRow(int y0)
800: {
801: if (list.getModel().getSize() == 0)
802: return -1;
803:
804:
805:
806: if (y0 < 0)
807: return list.getModel().getSize() - 1;
808:
809:
810: maybeUpdateLayoutState();
811:
812: int index = list.getModel().getSize() - 1;
813:
814:
815: if (cellHeight > 0)
816: index = Math.min(y0 / cellHeight, index);
817:
818:
819: else
820: {
821: int h = 0;
822: for (int row = 0; row < cellHeights.length; ++row)
823: {
824: h += cellHeights[row];
825: if (y0 < h)
826: {
827: index = row;
828: break;
829: }
830: }
831: }
832: return index;
833: }
834:
835:
840: protected void updateLayoutState()
841: {
842: int nrows = list.getModel().getSize();
843: cellHeight = -1;
844: cellWidth = -1;
845: if (cellHeights == null || cellHeights.length != nrows)
846: cellHeights = new int[nrows];
847: ListCellRenderer rend = list.getCellRenderer();
848:
849: int fixedCellHeight = list.getFixedCellHeight();
850: if (fixedCellHeight > 0)
851: {
852: cellHeight = fixedCellHeight;
853: cellHeights = null;
854: }
855: else
856: {
857: cellHeight = -1;
858: for (int i = 0; i < nrows; ++i)
859: {
860: Component flyweight =
861: rend.getListCellRendererComponent(list,
862: list.getModel().getElementAt(i),
863: i, list.isSelectedIndex(i),
864: list.getSelectionModel().getAnchorSelectionIndex() == i);
865: Dimension dim = flyweight.getPreferredSize();
866: cellHeights[i] = dim.height;
867: }
868: }
869:
870:
871: int fixedCellWidth = list.getFixedCellWidth();
872: if (fixedCellWidth > 0)
873: cellWidth = fixedCellWidth;
874: else
875: {
876: for (int i = 0; i < nrows; ++i)
877: {
878: Component flyweight =
879: rend.getListCellRendererComponent(list,
880: list.getModel().getElementAt(i),
881: i, list.isSelectedIndex(i),
882: list.getSelectionModel().getAnchorSelectionIndex() == i);
883: Dimension dim = flyweight.getPreferredSize();
884: cellWidth = Math.max(cellWidth, dim.width);
885: }
886: if (list.getLayoutOrientation() == JList.VERTICAL)
887: cellWidth = Math.max(cellWidth, list.getSize().width);
888: }
889: }
890:
891:
895: protected void maybeUpdateLayoutState()
896: {
897: if (updateLayoutStateNeeded != 0 || !list.isValid())
898: {
899: updateLayoutState();
900: updateLayoutStateNeeded = 0;
901: }
902: }
903:
904:
907: public BasicListUI()
908: {
909: updateLayoutStateNeeded = 1;
910: rendererPane = new CellRendererPane();
911: }
912:
913:
919: protected void installDefaults()
920: {
921: LookAndFeel.installColorsAndFont(list, "List.background",
922: "List.foreground", "List.font");
923: list.setSelectionForeground(UIManager.getColor("List.selectionForeground"));
924: list.setSelectionBackground(UIManager.getColor("List.selectionBackground"));
925: list.setOpaque(true);
926: }
927:
928:
932: protected void uninstallDefaults()
933: {
934: list.setForeground(null);
935: list.setBackground(null);
936: list.setSelectionForeground(null);
937: list.setSelectionBackground(null);
938: }
939:
940:
946: protected void installListeners()
947: {
948: if (focusListener == null)
949: focusListener = createFocusListener();
950: list.addFocusListener(focusListener);
951: if (listDataListener == null)
952: listDataListener = createListDataListener();
953: list.getModel().addListDataListener(listDataListener);
954: if (listSelectionListener == null)
955: listSelectionListener = createListSelectionListener();
956: list.addListSelectionListener(listSelectionListener);
957: if (mouseInputListener == null)
958: mouseInputListener = createMouseInputListener();
959: list.addMouseListener(mouseInputListener);
960: list.addMouseMotionListener(mouseInputListener);
961: if (propertyChangeListener == null)
962: propertyChangeListener = createPropertyChangeListener();
963: list.addPropertyChangeListener(propertyChangeListener);
964: }
965:
966:
969: protected void uninstallListeners()
970: {
971: list.removeFocusListener(focusListener);
972: list.getModel().removeListDataListener(listDataListener);
973: list.removeListSelectionListener(listSelectionListener);
974: list.removeMouseListener(mouseInputListener);
975: list.removeMouseMotionListener(mouseInputListener);
976: list.removePropertyChangeListener(propertyChangeListener);
977: }
978:
979:
982: protected void installKeyboardActions()
983: {
984: InputMap focusInputMap = (InputMap) UIManager.get("List.focusInputMap");
985: InputMapUIResource parentInputMap = new InputMapUIResource();
986:
987: ActionMap parentActionMap = new ActionMapUIResource();
988: action = new ListAction();
989: Object keys[] = focusInputMap.allKeys();
990:
991: for (int i = 0; i < keys.length; i++)
992: {
993: KeyStroke stroke = (KeyStroke)keys[i];
994: String actionString = (String) focusInputMap.get(stroke);
995: parentInputMap.put(KeyStroke.getKeyStroke(stroke.getKeyCode(),
996: stroke.getModifiers()),
997: actionString);
998:
999: parentActionMap.put (actionString,
1000: new ActionListenerProxy(action, actionString));
1001: }
1002:
1003:
1004: parentInputMap.setParent(list.getInputMap().getParent());
1005: parentActionMap.setParent(list.getActionMap().getParent());
1006: list.getInputMap().setParent(parentInputMap);
1007: list.getActionMap().setParent(parentActionMap);
1008: }
1009:
1010:
1013: protected void uninstallKeyboardActions()
1014: {
1015:
1016: }
1017:
1018:
1026: public void installUI(final JComponent c)
1027: {
1028: super.installUI(c);
1029: list = (JList) c;
1030: installDefaults();
1031: installListeners();
1032: installKeyboardActions();
1033: maybeUpdateLayoutState();
1034: }
1035:
1036:
1044: public void uninstallUI(final JComponent c)
1045: {
1046: uninstallKeyboardActions();
1047: uninstallListeners();
1048: uninstallDefaults();
1049: list = null;
1050: }
1051:
1052:
1060: public Dimension getPreferredSize(JComponent c)
1061: {
1062: maybeUpdateLayoutState();
1063: int size = list.getModel().getSize();
1064: int visibleRows = list.getVisibleRowCount();
1065: int layoutOrientation = list.getLayoutOrientation();
1066:
1067: int h;
1068: int w;
1069: int maxCellHeight = cellHeight;
1070: if (maxCellHeight <= 0)
1071: {
1072: for (int i = 0; i < cellHeights.length; i++)
1073: maxCellHeight = Math.max(maxCellHeight, cellHeights[i]);
1074: }
1075: if (layoutOrientation == JList.HORIZONTAL_WRAP)
1076: {
1077: if (visibleRows > 0)
1078: {
1079:
1080: double modelSize = size;
1081: int neededColumns = (int) Math.ceil(modelSize / visibleRows);
1082: int adjustedRows = (int) Math.ceil(modelSize / neededColumns);
1083: h = maxCellHeight * adjustedRows;
1084: w = cellWidth * neededColumns;
1085: }
1086: else
1087: {
1088: int neededColumns = Math.min(1, list.getWidth() / cellWidth);
1089: h = size / neededColumns * maxCellHeight;
1090: w = neededColumns * cellWidth;
1091: }
1092: }
1093: else if (layoutOrientation == JList.VERTICAL_WRAP)
1094: {
1095: if (visibleRows > 0)
1096: h = visibleRows * maxCellHeight;
1097: else
1098: h = Math.max(list.getHeight(), maxCellHeight);
1099: int neededColumns = h / maxCellHeight;
1100: w = cellWidth * neededColumns;
1101: }
1102: else
1103: {
1104: if (list.getFixedCellWidth() > 0)
1105: w = list.getFixedCellWidth();
1106: else
1107: w = cellWidth;
1108: if (list.getFixedCellHeight() > 0)
1109:
1110:
1111: h = list.getFixedCellHeight() * size;
1112: else
1113: h = maxCellHeight * size;
1114: }
1115: Insets insets = list.getInsets();
1116: Dimension retVal = new Dimension(w + insets.left + insets.right,
1117: h + insets.top + insets.bottom);
1118: return retVal;
1119: }
1120:
1121:
1134: protected void paintCell(Graphics g, int row, Rectangle bounds,
1135: ListCellRenderer rend, ListModel data,
1136: ListSelectionModel sel, int lead)
1137: {
1138: boolean isSel = list.isSelectedIndex(row);
1139: boolean hasFocus = (list.getLeadSelectionIndex() == row) && BasicListUI.this.list.hasFocus();
1140: Component comp = rend.getListCellRendererComponent(list,
1141: data.getElementAt(row),
1142: 0, isSel, hasFocus);
1143: rendererPane.paintComponent(g, comp, list, bounds);
1144: }
1145:
1146:
1153: public void paint(Graphics g, JComponent c)
1154: {
1155: int nrows = list.getModel().getSize();
1156: if (nrows == 0)
1157: return;
1158:
1159: maybeUpdateLayoutState();
1160: ListCellRenderer render = list.getCellRenderer();
1161: ListModel model = list.getModel();
1162: ListSelectionModel sel = list.getSelectionModel();
1163: int lead = sel.getLeadSelectionIndex();
1164: Rectangle clip = g.getClipBounds();
1165:
1166: int startIndex = locationToIndex(list, new Point(clip.x, clip.y));
1167: int endIndex = locationToIndex(list, new Point(clip.x + clip.width,
1168: clip.y + clip.height));
1169:
1170: for (int row = startIndex; row <= endIndex; ++row)
1171: {
1172: Rectangle bounds = getCellBounds(list, row, row);
1173: if (bounds.intersects(clip))
1174: paintCell(g, row, bounds, render, model, sel, lead);
1175: }
1176: }
1177:
1178:
1189: public int locationToIndex(JList l, Point location)
1190: {
1191: int layoutOrientation = list.getLayoutOrientation();
1192: int index = -1;
1193: switch (layoutOrientation)
1194: {
1195: case JList.VERTICAL:
1196: index = convertYToRow(location.y);
1197: break;
1198: case JList.HORIZONTAL_WRAP:
1199:
1200: int maxCellHeight = getCellHeight(0);
1201: int visibleRows = list.getHeight() / maxCellHeight;
1202: int cellsPerRow = -1;
1203: int numberOfItems = list.getModel().getSize();
1204: cellsPerRow = numberOfItems / visibleRows + 1;
1205:
1206:
1207: int cellsPerColumn = numberOfItems / cellsPerRow + 1;
1208: int gridX = Math.min(location.x / cellWidth, cellsPerRow - 1);
1209: int gridY = Math.min(location.y / maxCellHeight, cellsPerColumn);
1210: index = gridX + gridY * cellsPerRow;
1211: break;
1212: case JList.VERTICAL_WRAP:
1213:
1214: int maxCellHeight2 = getCellHeight(0);
1215: int visibleRows2 = list.getHeight() / maxCellHeight2;
1216: int numberOfItems2 = list.getModel().getSize();
1217: int cellsPerRow2 = numberOfItems2 / visibleRows2 + 1;
1218:
1219: int gridX2 = Math.min(location.x / cellWidth, cellsPerRow2 - 1);
1220: int gridY2 = Math.min(location.y / maxCellHeight2, visibleRows2);
1221: index = gridY2 + gridX2 * visibleRows2;
1222: break;
1223: }
1224: return index;
1225: }
1226:
1227: public Point indexToLocation(JList l, int index)
1228: {
1229: int layoutOrientation = list.getLayoutOrientation();
1230: Point loc = null;
1231: switch (layoutOrientation)
1232: {
1233: case JList.VERTICAL:
1234: loc = new Point(0, convertRowToY(index));
1235: break;
1236: case JList.HORIZONTAL_WRAP:
1237:
1238: int maxCellHeight = getCellHeight(0);
1239: int visibleRows = list.getHeight() / maxCellHeight;
1240: int numberOfCellsPerRow = -1;
1241: int numberOfItems = list.getModel().getSize();
1242: numberOfCellsPerRow = numberOfItems / visibleRows + 1;
1243:
1244:
1245: int gridX = index % numberOfCellsPerRow;
1246: int gridY = index / numberOfCellsPerRow;
1247: int locX = gridX * cellWidth;
1248: int locY;
1249: locY = gridY * maxCellHeight;
1250: loc = new Point(locX, locY);
1251: break;
1252: case JList.VERTICAL_WRAP:
1253:
1254: int maxCellHeight2 = getCellHeight(0);
1255: int visibleRows2 = list.getHeight() / maxCellHeight2;
1256:
1257: if (visibleRows2 > 0)
1258: {
1259: int gridY2 = index % visibleRows2;
1260: int gridX2 = index / visibleRows2;
1261: int locX2 = gridX2 * cellWidth;
1262: int locY2 = gridY2 * maxCellHeight2;
1263: loc = new Point(locX2, locY2);
1264: }
1265: else
1266: loc = new Point(0, convertRowToY(index));
1267: break;
1268: }
1269: return loc;
1270: }
1271:
1272:
1277: protected FocusListener createFocusListener()
1278: {
1279: return new FocusHandler();
1280: }
1281:
1282:
1287: protected ListDataListener createListDataListener()
1288: {
1289: return new ListDataHandler();
1290: }
1291:
1292:
1297: protected ListSelectionListener createListSelectionListener()
1298: {
1299: return new ListSelectionHandler();
1300: }
1301:
1302:
1307: protected MouseInputListener createMouseInputListener()
1308: {
1309: return new MouseInputHandler();
1310: }
1311:
1312:
1317: protected PropertyChangeListener createPropertyChangeListener()
1318: {
1319: return new PropertyChangeHandler();
1320: }
1321:
1322:
1325: protected void selectNextIndex()
1326: {
1327: int index = list.getSelectionModel().getLeadSelectionIndex();
1328: if (index < list.getModel().getSize() - 1)
1329: {
1330: index++;
1331: list.setSelectedIndex(index);
1332: }
1333: list.ensureIndexIsVisible(index);
1334: }
1335:
1336:
1339: protected void selectPreviousIndex()
1340: {
1341: int index = list.getSelectionModel().getLeadSelectionIndex();
1342: if (index > 0)
1343: {
1344: index--;
1345: list.setSelectedIndex(index);
1346: }
1347: list.ensureIndexIsVisible(index);
1348: }
1349: }