44 |
import java.awt.Graphics; |
import java.awt.Graphics; |
45 |
import java.awt.Point; |
import java.awt.Point; |
46 |
import java.awt.Rectangle; |
import java.awt.Rectangle; |
47 |
|
import java.awt.event.ComponentAdapter; |
48 |
|
import java.awt.event.ComponentEvent; |
49 |
|
import java.awt.event.ComponentListener; |
50 |
import java.awt.event.FocusEvent; |
import java.awt.event.FocusEvent; |
51 |
import java.awt.event.FocusListener; |
import java.awt.event.FocusListener; |
52 |
import java.awt.event.MouseEvent; |
import java.awt.event.MouseEvent; |
53 |
import java.beans.PropertyChangeEvent; |
import java.beans.PropertyChangeEvent; |
54 |
import java.beans.PropertyChangeListener; |
import java.beans.PropertyChangeListener; |
55 |
|
|
56 |
|
import javax.swing.CellRendererPane; |
57 |
import javax.swing.JComponent; |
import javax.swing.JComponent; |
58 |
import javax.swing.JList; |
import javax.swing.JList; |
59 |
|
import javax.swing.JViewport; |
60 |
import javax.swing.ListCellRenderer; |
import javax.swing.ListCellRenderer; |
61 |
import javax.swing.ListModel; |
import javax.swing.ListModel; |
62 |
import javax.swing.ListSelectionModel; |
import javax.swing.ListSelectionModel; |
76 |
*/ |
*/ |
77 |
public class BasicListUI extends ListUI |
public class BasicListUI extends ListUI |
78 |
{ |
{ |
79 |
|
|
80 |
|
/** |
81 |
|
* A helper class which listens for {@link ComponentEvent}s from |
82 |
|
* the JList. |
83 |
|
*/ |
84 |
|
private class ComponentHandler extends ComponentAdapter { |
85 |
|
|
86 |
|
/** |
87 |
|
* Called when the component is hidden. Invalidates the internal |
88 |
|
* layout. |
89 |
|
*/ |
90 |
|
public void componentResized(ComponentEvent ev) { |
91 |
|
BasicListUI.this.damageLayout(); |
92 |
|
} |
93 |
|
} |
94 |
|
|
95 |
/** |
/** |
96 |
* A helper class which listens for {@link FocusEvents} |
* A helper class which listens for {@link FocusEvents} |
97 |
* from the JList. |
* from the JList. |
98 |
*/ |
*/ |
99 |
class FocusHandler implements FocusListener |
public class FocusHandler implements FocusListener |
100 |
{ |
{ |
101 |
/** |
/** |
102 |
* Called when the JList acquires focus. |
* Called when the JList acquires focus. |
133 |
* |
* |
134 |
* @see javax.swing.JList#model |
* @see javax.swing.JList#model |
135 |
*/ |
*/ |
136 |
class ListDataHandler implements ListDataListener |
public class ListDataHandler implements ListDataListener |
137 |
{ |
{ |
138 |
/** |
/** |
139 |
* Called when a general change has happened in the model which cannot |
* Called when a general change has happened in the model which cannot |
171 |
* A helper class which listens for {@link ListSelectionEvent}s |
* A helper class which listens for {@link ListSelectionEvent}s |
172 |
* from the {@link JList}'s {@link ListSelectionModel}. |
* from the {@link JList}'s {@link ListSelectionModel}. |
173 |
*/ |
*/ |
174 |
class ListSelectionHandler implements ListSelectionListener |
public class ListSelectionHandler implements ListSelectionListener |
175 |
{ |
{ |
176 |
/** |
/** |
177 |
* Called when the list selection changes. |
* Called when the list selection changes. |
187 |
* A helper class which listens for {@link MouseEvent}s |
* A helper class which listens for {@link MouseEvent}s |
188 |
* from the {@link JList}. |
* from the {@link JList}. |
189 |
*/ |
*/ |
190 |
class MouseInputHandler implements MouseInputListener |
public class MouseInputHandler implements MouseInputListener |
191 |
{ |
{ |
192 |
/** |
/** |
193 |
* Called when a mouse button press/release cycle completes |
* Called when a mouse button press/release cycle completes |
207 |
*/ |
*/ |
208 |
public void mousePressed(MouseEvent event) |
public void mousePressed(MouseEvent event) |
209 |
{ |
{ |
210 |
int row = BasicListUI.this.convertYToRow(event.getY()); |
Point click = event.getPoint(); |
211 |
if (row == -1) |
int index = BasicListUI.this.locationToIndex(list, click); |
212 |
|
if (index == -1) |
213 |
return; |
return; |
214 |
|
|
215 |
BasicListUI.this.list.setSelectedIndex(row); |
BasicListUI.this.list.setSelectedIndex(index); |
216 |
} |
} |
217 |
|
|
218 |
/** |
/** |
270 |
* Helper class which listens to {@link PropertyChangeEvent}s |
* Helper class which listens to {@link PropertyChangeEvent}s |
271 |
* from the {@link JList}. |
* from the {@link JList}. |
272 |
*/ |
*/ |
273 |
class PropertyChangeHandler implements PropertyChangeListener |
public class PropertyChangeHandler implements PropertyChangeListener |
274 |
{ |
{ |
275 |
/** |
/** |
276 |
* Called when the {@link JList} changes one of its bound properties. |
* Called when the {@link JList} changes one of its bound properties. |
304 |
} |
} |
305 |
|
|
306 |
/** The current focus listener. */ |
/** The current focus listener. */ |
307 |
FocusHandler focusListener; |
protected FocusHandler focusListener; |
308 |
|
|
309 |
/** The data listener listening to the model. */ |
/** The data listener listening to the model. */ |
310 |
ListDataHandler listDataListener; |
protected ListDataHandler listDataListener; |
311 |
|
|
312 |
/** The selection listener listening to the selection model. */ |
/** The selection listener listening to the selection model. */ |
313 |
ListSelectionHandler listSelectionListener; |
protected ListSelectionHandler listSelectionListener; |
314 |
|
|
315 |
/** The mouse listener listening to the list. */ |
/** The mouse listener listening to the list. */ |
316 |
MouseInputHandler mouseInputListener; |
protected MouseInputHandler mouseInputListener; |
317 |
|
|
318 |
/** The property change listener listening to the list. */ |
/** The property change listener listening to the list. */ |
319 |
PropertyChangeHandler propertyChangeListener; |
protected PropertyChangeHandler propertyChangeListener; |
320 |
|
|
321 |
|
/** The component listener that receives notification for resizing the |
322 |
|
* JList component.*/ |
323 |
|
private ComponentListener componentListener; |
324 |
|
|
325 |
/** Saved reference to the list this UI was created for. */ |
/** Saved reference to the list this UI was created for. */ |
326 |
JList list; |
protected JList list; |
327 |
|
|
328 |
/** The height of a single cell in the list. */ |
/** The height of a single cell in the list. */ |
329 |
int cellHeight; |
protected int cellHeight; |
330 |
|
|
331 |
/** The width of a single cell in the list. */ |
/** The width of a single cell in the list. */ |
332 |
int cellWidth; |
protected int cellWidth; |
333 |
|
|
334 |
/** |
/** |
335 |
* An array of varying heights of cells in the list, in cases where each |
* An array of varying heights of cells in the list, in cases where each |
336 |
* cell might have a different height. |
* cell might have a different height. |
337 |
*/ |
*/ |
338 |
int[] cellHeights; |
protected int[] cellHeights; |
339 |
|
|
340 |
/** |
/** |
341 |
* A simple counter. When nonzero, indicates that the UI class is out of |
* A simple counter. When nonzero, indicates that the UI class is out of |
342 |
* date with respect to the underlying list, and must recalculate the |
* date with respect to the underlying list, and must recalculate the |
343 |
* list layout before painting or performing size calculations. |
* list layout before painting or performing size calculations. |
344 |
*/ |
*/ |
345 |
int updateLayoutStateNeeded; |
protected int updateLayoutStateNeeded; |
346 |
|
|
347 |
|
/** |
348 |
|
* The {@link CellRendererPane} that is used for painting. |
349 |
|
*/ |
350 |
|
protected CellRendererPane rendererPane; |
351 |
|
|
352 |
/** |
/** |
353 |
* Calculate the height of a particular row. If there is a fixed {@link |
* Calculate the height of a particular row. If there is a fixed {@link |
359 |
* |
* |
360 |
* @return The height, in pixels, of the specified row |
* @return The height, in pixels, of the specified row |
361 |
*/ |
*/ |
362 |
int getRowHeight(int row) |
protected int getRowHeight(int row) |
363 |
{ |
{ |
364 |
if (row < 0 || row >= cellHeights.length) |
if (row < 0 || row >= cellHeights.length) |
365 |
return -1; |
return -1; |
387 |
if (l != list || cellWidth == -1) |
if (l != list || cellWidth == -1) |
388 |
return null; |
return null; |
389 |
|
|
390 |
int lo = Math.min(index1, index2); |
int minIndex = Math.min(index1, index2); |
391 |
int hi = Math.max(index1, index2); |
int maxIndex = Math.max(index1, index2); |
392 |
Rectangle lobounds = new Rectangle(0, convertRowToY(lo), cellWidth, |
Point loc = indexToLocation(list, minIndex); |
393 |
getRowHeight(lo)); |
Rectangle bounds = new Rectangle(loc.x, loc.y, cellWidth, |
394 |
Rectangle hibounds = new Rectangle(0, convertRowToY(hi), cellWidth, |
getRowHeight(minIndex)); |
|
getRowHeight(hi)); |
|
395 |
|
|
396 |
return lobounds.union(hibounds); |
for (int i = minIndex + 1; i <= maxIndex; i++) |
397 |
|
{ |
398 |
|
Point hiLoc = indexToLocation(list, i); |
399 |
|
Rectangle hibounds = new Rectangle(hiLoc.x, hiLoc.y, cellWidth, |
400 |
|
getRowHeight(i)); |
401 |
|
bounds = bounds.union(hibounds); |
402 |
|
} |
403 |
|
|
404 |
|
return bounds; |
405 |
} |
} |
406 |
|
|
407 |
/** |
/** |
414 |
* @return The Y coordinate of the specified row, or <code>-1</code> if |
* @return The Y coordinate of the specified row, or <code>-1</code> if |
415 |
* the specified row number is invalid |
* the specified row number is invalid |
416 |
*/ |
*/ |
417 |
int convertRowToY(int row) |
protected int convertRowToY(int row) |
418 |
{ |
{ |
419 |
int y = 0; |
int y = 0; |
420 |
for (int i = 0; i < row; ++i) |
for (int i = 0; i < row; ++i) |
437 |
* @return The row number containing the specified Y value, or <code>-1</code> |
* @return The row number containing the specified Y value, or <code>-1</code> |
438 |
* if the specified Y coordinate is invalid |
* if the specified Y coordinate is invalid |
439 |
*/ |
*/ |
440 |
int convertYToRow(int y0) |
protected int convertYToRow(int y0) |
441 |
{ |
{ |
442 |
for (int row = 0; row < cellHeights.length; ++row) |
for (int row = 0; row < cellHeights.length; ++row) |
443 |
{ |
{ |
455 |
* #cellWidth} properties by examining the variouis properties of the |
* #cellWidth} properties by examining the variouis properties of the |
456 |
* {@link JList}. |
* {@link JList}. |
457 |
*/ |
*/ |
458 |
void updateLayoutState() |
protected void updateLayoutState() |
459 |
{ |
{ |
460 |
int nrows = list.getModel().getSize(); |
int nrows = list.getModel().getSize(); |
461 |
cellHeight = -1; |
cellHeight = -1; |
474 |
false); |
false); |
475 |
Dimension dim = flyweight.getPreferredSize(); |
Dimension dim = flyweight.getPreferredSize(); |
476 |
cellHeights[i] = dim.height; |
cellHeights[i] = dim.height; |
477 |
|
// compute average cell height (little hack here) |
478 |
|
cellHeight = (cellHeight * i + cellHeights[i]) / (i + 1); |
479 |
cellWidth = Math.max(cellWidth, dim.width); |
cellWidth = Math.max(cellWidth, dim.width); |
480 |
|
if (list.getLayoutOrientation() == JList.VERTICAL) |
481 |
|
cellWidth = Math.max(cellWidth, list.getSize().width); |
482 |
} |
} |
483 |
} |
} |
484 |
else |
else |
494 |
* |
* |
495 |
* @see #updateLayoutStateNeeded |
* @see #updateLayoutStateNeeded |
496 |
*/ |
*/ |
497 |
void damageLayout() |
private void damageLayout() |
498 |
{ |
{ |
499 |
updateLayoutStateNeeded = 1; |
updateLayoutStateNeeded = 1; |
500 |
list.revalidate(); |
list.revalidate(); |
504 |
* Calls {@link #updateLayoutState} if {@link #updateLayoutStateNeeded} |
* Calls {@link #updateLayoutState} if {@link #updateLayoutStateNeeded} |
505 |
* is nonzero, then resets {@link #updateLayoutStateNeeded} to zero. |
* is nonzero, then resets {@link #updateLayoutStateNeeded} to zero. |
506 |
*/ |
*/ |
507 |
void maybeUpdateLayoutState() |
protected void maybeUpdateLayoutState() |
508 |
{ |
{ |
509 |
if (updateLayoutStateNeeded != 0) |
if (updateLayoutStateNeeded != 0) |
510 |
{ |
{ |
523 |
listSelectionListener = new ListSelectionHandler(); |
listSelectionListener = new ListSelectionHandler(); |
524 |
mouseInputListener = new MouseInputHandler(); |
mouseInputListener = new MouseInputHandler(); |
525 |
propertyChangeListener = new PropertyChangeHandler(); |
propertyChangeListener = new PropertyChangeHandler(); |
526 |
|
componentListener = new ComponentHandler(); |
527 |
updateLayoutStateNeeded = 1; |
updateLayoutStateNeeded = 1; |
528 |
|
rendererPane = new CellRendererPane(); |
529 |
} |
} |
530 |
|
|
531 |
/** |
/** |
534 |
* |
* |
535 |
* @see #uninstallDefaults |
* @see #uninstallDefaults |
536 |
*/ |
*/ |
537 |
void installDefaults() |
protected void installDefaults() |
538 |
{ |
{ |
539 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
540 |
list.setForeground(defaults.getColor("List.foreground")); |
list.setForeground(defaults.getColor("List.foreground")); |
548 |
* Resets to <code>null</code> those defaults which were installed in |
* Resets to <code>null</code> those defaults which were installed in |
549 |
* {@link #installDefaults} |
* {@link #installDefaults} |
550 |
*/ |
*/ |
551 |
void uninstallDefaults() |
protected void uninstallDefaults() |
552 |
{ |
{ |
553 |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
UIDefaults defaults = UIManager.getLookAndFeelDefaults(); |
554 |
list.setForeground(null); |
list.setForeground(null); |
563 |
* |
* |
564 |
* @see #uninstallListeners |
* @see #uninstallListeners |
565 |
*/ |
*/ |
566 |
void installListeners() |
protected void installListeners() |
567 |
{ |
{ |
568 |
list.addFocusListener(focusListener); |
list.addFocusListener(focusListener); |
569 |
list.getModel().addListDataListener(listDataListener); |
list.getModel().addListDataListener(listDataListener); |
571 |
list.addMouseListener(mouseInputListener); |
list.addMouseListener(mouseInputListener); |
572 |
list.addMouseMotionListener(mouseInputListener); |
list.addMouseMotionListener(mouseInputListener); |
573 |
list.addPropertyChangeListener(propertyChangeListener); |
list.addPropertyChangeListener(propertyChangeListener); |
574 |
|
list.addComponentListener(componentListener); |
575 |
} |
} |
576 |
|
|
577 |
/** |
/** |
578 |
* Detaches all the listeners we attached in {@link #installListeners}. |
* Detaches all the listeners we attached in {@link #installListeners}. |
579 |
*/ |
*/ |
580 |
void uninstallListeners() |
protected void uninstallListeners() |
581 |
{ |
{ |
582 |
list.removeFocusListener(focusListener); |
list.removeFocusListener(focusListener); |
583 |
list.getModel().removeListDataListener(listDataListener); |
list.getModel().removeListDataListener(listDataListener); |
590 |
/** |
/** |
591 |
* Installs keyboard actions for this UI in the {@link JList}. |
* Installs keyboard actions for this UI in the {@link JList}. |
592 |
*/ |
*/ |
593 |
void installKeyboardActions() |
protected void installKeyboardActions() |
594 |
{ |
{ |
595 |
} |
} |
596 |
|
|
597 |
/** |
/** |
598 |
* Uninstalls keyboard actions for this UI in the {@link JList}. |
* Uninstalls keyboard actions for this UI in the {@link JList}. |
599 |
*/ |
*/ |
600 |
void uninstallKeyboardActions() |
protected void uninstallKeyboardActions() |
601 |
{ |
{ |
602 |
} |
} |
603 |
|
|
636 |
} |
} |
637 |
|
|
638 |
/** |
/** |
|
* Gets the maximum size this list can assume. |
|
|
* |
|
|
* @param c The component to measure the size of |
|
|
* |
|
|
* @return A new Dimension representing the component's maximum size |
|
|
*/ |
|
|
public Dimension getMaximumSize(JComponent c) |
|
|
{ |
|
|
return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); |
|
|
} |
|
|
|
|
|
/** |
|
639 |
* Gets the size this list would prefer to assume. This is calculated by |
* Gets the size this list would prefer to assume. This is calculated by |
640 |
* calling {@link #getCellBounds} over the entire list. |
* calling {@link #getCellBounds} over the entire list. |
641 |
* |
* |
645 |
*/ |
*/ |
646 |
public Dimension getPreferredSize(JComponent c) |
public Dimension getPreferredSize(JComponent c) |
647 |
{ |
{ |
648 |
if (list.getModel().getSize() == 0) |
int size = list.getModel().getSize(); |
649 |
|
if (size == 0) |
650 |
return new Dimension(0, 0); |
return new Dimension(0, 0); |
651 |
|
int visibleRows = list.getVisibleRowCount(); |
652 |
|
int layoutOrientation = list.getLayoutOrientation(); |
653 |
Rectangle bounds = getCellBounds(list, 0, list.getModel().getSize() - 1); |
Rectangle bounds = getCellBounds(list, 0, list.getModel().getSize() - 1); |
654 |
return bounds.getSize(); |
Dimension retVal = bounds.getSize(); |
655 |
|
Component parent = list.getParent(); |
656 |
|
if ((visibleRows == -1) && (parent instanceof JViewport)) |
657 |
|
{ |
658 |
|
JViewport viewport = (JViewport) parent; |
659 |
|
|
660 |
|
if (layoutOrientation == JList.HORIZONTAL_WRAP) |
661 |
|
{ |
662 |
|
int h = viewport.getSize().height; |
663 |
|
int cellsPerCol = h / cellHeight; |
664 |
|
int w = size / cellsPerCol * cellWidth; |
665 |
|
retVal = new Dimension(w, h); |
666 |
|
} |
667 |
|
else if (layoutOrientation == JList.VERTICAL_WRAP) |
668 |
|
{ |
669 |
|
int w = viewport.getSize().width; |
670 |
|
int cellsPerRow = Math.max(w / cellWidth, 1); |
671 |
|
int h = size / cellsPerRow * cellHeight; |
672 |
|
retVal = new Dimension(w, h); |
673 |
|
} |
674 |
|
} |
675 |
|
return retVal; |
676 |
} |
} |
677 |
|
|
678 |
/** |
/** |
682 |
* @param g The graphics context to paint in |
* @param g The graphics context to paint in |
683 |
* @param c The component to paint the background of |
* @param c The component to paint the background of |
684 |
*/ |
*/ |
685 |
public void paintBackground(Graphics g, JComponent c) |
private void paintBackground(Graphics g, JComponent c) |
686 |
{ |
{ |
687 |
Dimension size = getPreferredSize(c); |
Dimension size = getPreferredSize(c); |
688 |
Color save = g.getColor(); |
Color save = g.getColor(); |
704 |
* @param sel A selection model to provide to the cell renderer |
* @param sel A selection model to provide to the cell renderer |
705 |
* @param lead The lead selection index of the list |
* @param lead The lead selection index of the list |
706 |
*/ |
*/ |
707 |
void paintCell(Graphics g, int row, Rectangle bounds, ListCellRenderer rend, |
protected void paintCell(Graphics g, int row, Rectangle bounds, |
708 |
ListModel data, ListSelectionModel sel, int lead) |
ListCellRenderer rend, ListModel data, |
709 |
|
ListSelectionModel sel, int lead) |
710 |
{ |
{ |
711 |
boolean is_sel = list.isSelectedIndex(row); |
boolean is_sel = list.isSelectedIndex(row); |
712 |
boolean has_focus = false; |
boolean has_focus = false; |
713 |
Component comp = rend.getListCellRendererComponent(list, |
Component comp = rend.getListCellRendererComponent(list, |
714 |
data.getElementAt(row), |
data.getElementAt(row), |
715 |
0, is_sel, has_focus); |
0, is_sel, has_focus); |
716 |
g.translate(bounds.x, bounds.y); |
//comp.setBounds(new Rectangle(0, 0, bounds.width, bounds.height)); |
717 |
comp.setBounds(new Rectangle(0, 0, bounds.width, bounds.height)); |
//comp.paint(g); |
718 |
comp.paint(g); |
rendererPane.paintComponent(g, comp, list, bounds); |
|
g.translate(-bounds.x, -bounds.y); |
|
719 |
} |
} |
720 |
|
|
721 |
/** |
/** |
747 |
} |
} |
748 |
} |
} |
749 |
|
|
750 |
|
/** |
751 |
|
* Computes the index of a list cell given a point within the list. |
752 |
|
* |
753 |
|
* @param list the list which on which the computation is based on |
754 |
|
* @param location the coordinates |
755 |
|
* |
756 |
|
* @return the index of the list item that is located at the given |
757 |
|
* coordinates or <code>null</code> if the location is invalid |
758 |
|
*/ |
759 |
public int locationToIndex(JList list, Point location) |
public int locationToIndex(JList list, Point location) |
760 |
{ |
{ |
761 |
return convertYToRow(location.y); |
int layoutOrientation = list.getLayoutOrientation(); |
762 |
|
int index = -1; |
763 |
|
switch (layoutOrientation) |
764 |
|
{ |
765 |
|
case JList.VERTICAL: |
766 |
|
index = convertYToRow(location.y); |
767 |
|
break; |
768 |
|
case JList.HORIZONTAL_WRAP: |
769 |
|
// determine visible rows and cells per row |
770 |
|
int visibleRows = list.getVisibleRowCount(); |
771 |
|
int cellsPerRow = -1; |
772 |
|
int numberOfItems = list.getModel().getSize(); |
773 |
|
Dimension listDim = list.getSize(); |
774 |
|
if (visibleRows <= 0) |
775 |
|
{ |
776 |
|
try |
777 |
|
{ |
778 |
|
cellsPerRow = listDim.width / cellWidth; |
779 |
|
} |
780 |
|
catch (ArithmeticException ex) |
781 |
|
{ |
782 |
|
cellsPerRow = 1; |
783 |
|
} |
784 |
|
} |
785 |
|
else |
786 |
|
{ |
787 |
|
cellsPerRow = numberOfItems / visibleRows + 1; |
788 |
|
} |
789 |
|
|
790 |
|
// determine index for the given location |
791 |
|
int cellsPerColumn = numberOfItems / cellsPerRow + 1; |
792 |
|
int gridX = Math.min(location.x / cellWidth, cellsPerRow - 1); |
793 |
|
int gridY = Math.min(location.y / cellHeight, cellsPerColumn); |
794 |
|
index = gridX + gridY * cellsPerRow; |
795 |
|
break; |
796 |
|
case JList.VERTICAL_WRAP: |
797 |
|
// determine visible rows and cells per column |
798 |
|
int visibleRows2 = list.getVisibleRowCount(); |
799 |
|
if (visibleRows2 <= 0) |
800 |
|
{ |
801 |
|
Dimension listDim2 = list.getSize(); |
802 |
|
visibleRows2 = listDim2.height / cellHeight; |
803 |
|
} |
804 |
|
int numberOfItems2 = list.getModel().getSize(); |
805 |
|
int cellsPerRow2 = numberOfItems2 / visibleRows2 + 1; |
806 |
|
|
807 |
|
Dimension listDim2 = list.getSize(); |
808 |
|
int gridX2 = Math.min(location.x / cellWidth, cellsPerRow2 - 1); |
809 |
|
int gridY2 = Math.min(location.y / cellHeight, visibleRows2); |
810 |
|
index = gridY2 + gridX2 * visibleRows2; |
811 |
|
break; |
812 |
|
} |
813 |
|
return index; |
814 |
} |
} |
815 |
|
|
816 |
public Point indexToLocation(JList list, int index) |
public Point indexToLocation(JList list, int index) |
817 |
{ |
{ |
818 |
return new Point(0, convertRowToY(index)); |
int layoutOrientation = list.getLayoutOrientation(); |
819 |
|
Point loc = null; |
820 |
|
switch (layoutOrientation) |
821 |
|
{ |
822 |
|
case JList.VERTICAL: |
823 |
|
loc = new Point(0, convertRowToY(index)); |
824 |
|
break; |
825 |
|
case JList.HORIZONTAL_WRAP: |
826 |
|
// determine visible rows and cells per row |
827 |
|
int visibleRows = list.getVisibleRowCount(); |
828 |
|
int numberOfCellsPerRow = -1; |
829 |
|
if (visibleRows <= 0) |
830 |
|
{ |
831 |
|
Dimension listDim = list.getSize(); |
832 |
|
numberOfCellsPerRow = Math.max(listDim.width / cellWidth, 1); |
833 |
|
} |
834 |
|
else |
835 |
|
{ |
836 |
|
int numberOfItems = list.getModel().getSize(); |
837 |
|
numberOfCellsPerRow = numberOfItems / visibleRows + 1; |
838 |
|
} |
839 |
|
// compute coordinates inside the grid |
840 |
|
int gridX = index % numberOfCellsPerRow; |
841 |
|
int gridY = index / numberOfCellsPerRow; |
842 |
|
int locX = gridX * cellWidth; |
843 |
|
int locY = gridY * cellHeight; |
844 |
|
loc = new Point(locX, locY); |
845 |
|
break; |
846 |
|
case JList.VERTICAL_WRAP: |
847 |
|
// determine visible rows and cells per column |
848 |
|
int visibleRows2 = list.getVisibleRowCount(); |
849 |
|
if (visibleRows2 <= 0) |
850 |
|
{ |
851 |
|
Dimension listDim2 = list.getSize(); |
852 |
|
visibleRows2 = listDim2.height / cellHeight; |
853 |
|
} |
854 |
|
// compute coordinates inside the grid |
855 |
|
if (visibleRows2 > 0) |
856 |
|
{ |
857 |
|
int gridY2 = index % visibleRows2; |
858 |
|
int gridX2 = index / visibleRows2; |
859 |
|
int locX2 = gridX2 * cellWidth; |
860 |
|
int locY2 = gridY2 * cellHeight; |
861 |
|
loc = new Point(locX2, locY2); |
862 |
|
} |
863 |
|
else |
864 |
|
loc = new Point(0, convertRowToY(index)); |
865 |
|
break; |
866 |
|
} |
867 |
|
return loc; |
868 |
} |
} |
869 |
} |
} |