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: import ;
79:
80:
84: public class BasicListUI extends ListUI
85: {
86:
87:
91: public class FocusHandler implements FocusListener
92: {
93:
98: public void focusGained(FocusEvent e)
99: {
100: repaintCellFocus();
101: }
102:
103:
108: public void focusLost(FocusEvent e)
109: {
110: repaintCellFocus();
111: }
112:
113:
117: protected void repaintCellFocus()
118: {
119:
120: }
121: }
122:
123:
129: public class ListDataHandler implements ListDataListener
130: {
131:
137: public void contentsChanged(ListDataEvent e)
138: {
139: updateLayoutStateNeeded |= modelChanged;
140: list.revalidate();
141: }
142:
143:
148: public void intervalAdded(ListDataEvent e)
149: {
150: updateLayoutStateNeeded |= modelChanged;
151: list.revalidate();
152: }
153:
154:
159: public void intervalRemoved(ListDataEvent e)
160: {
161: updateLayoutStateNeeded |= modelChanged;
162: list.revalidate();
163: }
164: }
165:
166:
170: public class ListSelectionHandler implements ListSelectionListener
171: {
172:
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:
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:
220: private class ListAction
221: extends AbstractAction
222: {
223:
224:
225:
226:
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:
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:
263:
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:
408:
409:
410:
411: }
412:
413: list.ensureIndexIsVisible(list.getLeadSelectionIndex());
414: }
415: }
416:
417:
421: public class MouseInputHandler implements MouseInputListener
422: {
423:
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:
442:
443:
444:
445:
446: list.setSelectionInterval(list.getAnchorSelectionIndex(), index);
447: else
448:
449:
450:
451:
452:
453:
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:
480: public void mousePressed(MouseEvent event)
481: {
482:
483: list.requestFocusInWindow();
484: }
485:
486:
492: public void mouseReleased(MouseEvent event)
493: {
494:
495: }
496:
497:
503: public void mouseEntered(MouseEvent event)
504: {
505:
506: }
507:
508:
514: public void mouseExited(MouseEvent event)
515: {
516:
517: }
518:
519:
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:
543: public void mouseMoved(MouseEvent event)
544: {
545:
546: }
547: }
548:
549:
553: public class PropertyChangeHandler implements PropertyChangeListener
554: {
555:
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:
595: protected static final int modelChanged = 1;
596:
597:
600: protected static final int selectionModelChanged = 2;
601:
602:
605: protected static final int fontChanged = 4;
606:
607:
610: protected static final int fixedCellWidthChanged = 8;
611:
612:
615: protected static final int fixedCellHeightChanged = 16;
616:
617:
620: protected static final int prototypeCellValueChanged = 32;
621:
622:
625: protected static final int cellRendererChanged = 64;
626:
627:
634: public static ComponentUI createUI(final JComponent c)
635: {
636: return new BasicListUI();
637: }
638:
639:
640: protected FocusListener focusListener;
641:
642:
643: protected ListDataListener listDataListener;
644:
645:
646: protected ListSelectionListener listSelectionListener;
647:
648:
649: protected MouseInputListener mouseInputListener;
650:
651:
652: protected PropertyChangeListener propertyChangeListener;
653:
654:
655: protected JList list;
656:
657:
662: protected int cellHeight;
663:
664:
665: protected int cellWidth;
666:
667:
673: protected int[] cellHeights;
674:
675:
689: protected int updateLayoutStateNeeded;
690:
691:
694: protected CellRendererPane rendererPane;
695:
696:
697: ListAction action;
698:
699:
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:
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:
748:
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:
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:
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:
828: protected int convertYToRow(int y0)
829: {
830: if (list.getModel().getSize() == 0)
831: return -1;
832:
833:
834:
835: if (y0 < 0)
836: return list.getModel().getSize() - 1;
837:
838:
839: maybeUpdateLayoutState();
840:
841: int index = list.getModel().getSize() - 1;
842:
843:
844: if (cellHeight > 0)
845: index = Math.min(y0 / cellHeight, index);
846:
847:
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:
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:
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:
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:
922: protected void maybeUpdateLayoutState()
923: {
924: if (updateLayoutStateNeeded != 0 || !list.isValid())
925: {
926: updateLayoutState();
927: updateLayoutStateNeeded = 0;
928: }
929: }
930:
931:
934: public BasicListUI()
935: {
936: updateLayoutStateNeeded = 1;
937: rendererPane = new CellRendererPane();
938: }
939:
940:
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:
959: protected void uninstallDefaults()
960: {
961: list.setForeground(null);
962: list.setBackground(null);
963: list.setSelectionForeground(null);
964: list.setSelectionBackground(null);
965: }
966:
967:
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:
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:
1009: protected void installKeyboardActions()
1010: {
1011:
1012: InputMap focusInputMap = (InputMap) UIManager.get("List.focusInputMap");
1013: SwingUtilities.replaceUIInputMap(list, JComponent.WHEN_FOCUSED,
1014: focusInputMap);
1015:
1016:
1017: ActionMap am = (ActionMap) UIManager.get("List.actionMap");
1018: if (am == null)
1019: {
1020:
1021:
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:
1078: protected void uninstallKeyboardActions()
1079: {
1080:
1081: InputMap im = SwingUtilities.getUIInputMap(list, JComponent.WHEN_FOCUSED);
1082: if (im instanceof UIResource)
1083: SwingUtilities.replaceUIInputMap(list, JComponent.WHEN_FOCUSED, null);
1084:
1085:
1086: if (SwingUtilities.getUIActionMap(list) instanceof UIResource)
1087: SwingUtilities.replaceUIActionMap(list, null);
1088: }
1089:
1090:
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:
1116: public void uninstallUI(final JComponent c)
1117: {
1118: uninstallKeyboardActions();
1119: uninstallListeners();
1120: uninstallDefaults();
1121: list = null;
1122: }
1123:
1124:
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:
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:
1182:
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:
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:
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:
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:
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:
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:
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:
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:
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:
1326: int maxCellHeight2 = getCellHeight(0);
1327: int visibleRows2 = list.getHeight() / maxCellHeight2;
1328:
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:
1349: protected FocusListener createFocusListener()
1350: {
1351: return new FocusHandler();
1352: }
1353:
1354:
1359: protected ListDataListener createListDataListener()
1360: {
1361: return new ListDataHandler();
1362: }
1363:
1364:
1369: protected ListSelectionListener createListSelectionListener()
1370: {
1371: return new ListSelectionHandler();
1372: }
1373:
1374:
1379: protected MouseInputListener createMouseInputListener()
1380: {
1381: return new MouseInputHandler();
1382: }
1383:
1384:
1389: protected PropertyChangeListener createPropertyChangeListener()
1390: {
1391: return new PropertyChangeHandler();
1392: }
1393:
1394:
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:
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: }