📄 basiclistui.java
字号:
if (list.isSelectedIndex(list.getAnchorSelectionIndex())) list.getSelectionModel().setLeadSelectionIndex(index); else list.addSelectionInterval(list.getAnchorSelectionIndex(), index); } else if (event.isControlDown()) { if (list.getSelectionMode() == ListSelectionModel.SINGLE_SELECTION) list.setSelectedIndex(index); else if (list.isSelectedIndex(index)) list.removeSelectionInterval(index,index); else list.addSelectionInterval(index,index); } else list.setSelectedIndex(index); list.ensureIndexIsVisible(list.getLeadSelectionIndex()); } /** * Called when a mouse button is pressed down on the * {@link JList}. * * @param event The event representing the mouse press */ public void mousePressed(MouseEvent event) { // TODO: What should be done here, if anything? } /** * Called when a mouse button is released on * the {@link JList} * * @param event The event representing the mouse press */ public void mouseReleased(MouseEvent event) { // TODO: What should be done here, if anything? } /** * Called when the mouse pointer enters the area bounded * by the {@link JList} * * @param event The event representing the mouse entry */ public void mouseEntered(MouseEvent event) { // TODO: What should be done here, if anything? } /** * Called when the mouse pointer leaves the area bounded * by the {@link JList} * * @param event The event representing the mouse exit */ public void mouseExited(MouseEvent event) { // TODO: What should be done here, if anything? } /** * Called when the mouse pointer moves over the area bounded * by the {@link JList} while a button is held down. * * @param event The event representing the mouse drag */ public void mouseDragged(MouseEvent event) { // TODO: What should be done here, if anything? } /** * Called when the mouse pointer moves over the area bounded * by the {@link JList}. * * @param event The event representing the mouse move */ public void mouseMoved(MouseEvent event) { // TODO: What should be done here, if anything? } } /** * Helper class which listens to {@link PropertyChangeEvent}s * from the {@link JList}. */ public class PropertyChangeHandler implements PropertyChangeListener { /** * Called when the {@link JList} changes one of its bound properties. * * @param e The event representing the property change */ public void propertyChange(PropertyChangeEvent e) { if (e.getSource() == BasicListUI.this.list) { if (e.getOldValue() != null && e.getOldValue() instanceof ListModel) ((ListModel) e.getOldValue()).removeListDataListener(BasicListUI.this.listDataListener); if (e.getNewValue() != null && e.getNewValue() instanceof ListModel) ((ListModel) e.getNewValue()).addListDataListener(BasicListUI.this.listDataListener); } // Update the updateLayoutStateNeeded flag. if (e.getPropertyName().equals("model")) updateLayoutStateNeeded += modelChanged; else if (e.getPropertyName().equals("selectionModel")) updateLayoutStateNeeded += selectionModelChanged; else if (e.getPropertyName().equals("font")) updateLayoutStateNeeded += fontChanged; else if (e.getPropertyName().equals("fixedCellWidth")) updateLayoutStateNeeded += fixedCellWidthChanged; else if (e.getPropertyName().equals("fixedCellHeight")) updateLayoutStateNeeded += fixedCellHeightChanged; else if (e.getPropertyName().equals("prototypeCellValue")) updateLayoutStateNeeded += prototypeCellValueChanged; else if (e.getPropertyName().equals("cellRenderer")) updateLayoutStateNeeded += cellRendererChanged; BasicListUI.this.damageLayout(); } } /** * A constant to indicate that the model has changed. */ protected static final int modelChanged = 1; /** * A constant to indicate that the selection model has changed. */ protected static final int selectionModelChanged = 2; /** * A constant to indicate that the font has changed. */ protected static final int fontChanged = 4; /** * A constant to indicate that the fixedCellWidth has changed. */ protected static final int fixedCellWidthChanged = 8; /** * A constant to indicate that the fixedCellHeight has changed. */ protected static final int fixedCellHeightChanged = 16; /** * A constant to indicate that the prototypeCellValue has changed. */ protected static final int prototypeCellValueChanged = 32; /** * A constant to indicate that the cellRenderer has changed. */ protected static final int cellRendererChanged = 64; /** * Creates a new BasicListUI for the component. * * @param c The component to create a UI for * * @return A new UI */ public static ComponentUI createUI(final JComponent c) { return new BasicListUI(); } /** The current focus listener. */ protected FocusListener focusListener; /** The data listener listening to the model. */ protected ListDataListener listDataListener; /** The selection listener listening to the selection model. */ protected ListSelectionListener listSelectionListener; /** The mouse listener listening to the list. */ protected MouseInputListener mouseInputListener; /** The property change listener listening to the list. */ protected PropertyChangeListener propertyChangeListener; /** The component listener that receives notification for resizing the * JList component.*/ private ComponentListener componentListener; /** Saved reference to the list this UI was created for. */ protected JList list; /** * The height of a single cell in the list. This field is used when the * fixedCellHeight property of the list is set. Otherwise this field is * set to <code>-1</code> and {@link #cellHeights} is used instead. */ protected int cellHeight; /** The width of a single cell in the list. */ protected int cellWidth; /** * An array of varying heights of cells in the list, in cases where each * cell might have a different height. This field is used when the * <code>fixedCellHeight</code> property of the list is not set. Otherwise * this field is <code>null</code> and {@link #cellHeight} is used. */ protected int[] cellHeights; /** * A bitmask that indicates which properties of the JList have changed. * When nonzero, indicates that the UI class is out of * date with respect to the underlying list, and must recalculate the * list layout before painting or performing size calculations. * * @see #modelChanged * @see #selectionModelChanged * @see #fontChanged * @see #fixedCellWidthChanged * @see #fixedCellHeightChanged * @see #prototypeCellValueChanged * @see #cellRendererChanged */ protected int updateLayoutStateNeeded; /** * The {@link CellRendererPane} that is used for painting. */ protected CellRendererPane rendererPane; /** The action bound to KeyStrokes. */ ListAction action; /** * Calculate the height of a particular row. If there is a fixed {@link * #cellHeight}, return it; otherwise return the specific row height * requested from the {@link #cellHeights} array. If the requested row * is invalid, return <code>-1</code>. * * @param row The row to get the height of * * @return The height, in pixels, of the specified row */ protected int getRowHeight(int row) { int height; if (cellHeights == null) height = cellHeight; else { if (row < 0 || row >= cellHeights.length) height = -1; else height = cellHeights[row]; } return height; } /** * Calculate the bounds of a particular cell, considering the upper left * corner of the list as the origin position <code>(0,0)</code>. * * @param l Ignored; calculates over <code>this.list</code> * @param index1 The first row to include in the bounds * @param index2 The last row to incude in the bounds * * @return A rectangle encompassing the range of rows between * <code>index1</code> and <code>index2</code> inclusive */ public Rectangle getCellBounds(JList l, int index1, int index2) { maybeUpdateLayoutState(); if (l != list || cellWidth == -1) return null; int minIndex = Math.min(index1, index2); int maxIndex = Math.max(index1, index2); Point loc = indexToLocation(list, minIndex); Rectangle bounds = new Rectangle(loc.x, loc.y, cellWidth, getRowHeight(minIndex)); for (int i = minIndex + 1; i <= maxIndex; i++) { Point hiLoc = indexToLocation(list, i); Rectangle hibounds = new Rectangle(hiLoc.x, hiLoc.y, cellWidth, getRowHeight(i)); bounds = bounds.union(hibounds); } return bounds; } /** * Calculate the Y coordinate of the upper edge of a particular row, * considering the Y coordinate <code>0</code> to occur at the top of the * list. * * @param row The row to calculate the Y coordinate of * * @return The Y coordinate of the specified row, or <code>-1</code> if * the specified row number is invalid */ protected int convertRowToY(int row) { int y = 0; for (int i = 0; i < row; ++i) { int h = getRowHeight(i); if (h == -1) return -1; y += h; } return y; } /** * Calculate the row number containing a particular Y coordinate, * considering the Y coodrinate <code>0</code> to occur at the top of the * list. * * @param y0 The Y coordinate to calculate the row number for * * @return The row number containing the specified Y value, or <code>-1</code> * if the list model is empty * * @specnote This method is specified to return -1 for an invalid Y * coordinate. However, some simple tests show that the behaviour * is to return the index of the last list element for an Y * coordinate that lies outside of the list bounds (even for * negative indices). <code>-1</code> * is only returned if the list model is empty. */ protected int convertYToRow(int y0) { if (list.getModel().getSize() == 0) return -1; // When y0 < 0, then the JDK returns the maximum row index of the list. So // do we. if (y0 < 0) return list.getModel().getSize() - 1; // Update the layout if necessary. maybeUpdateLayoutState(); int index = list.getModel().getSize() - 1;; // If a fixed cell height is set, then we can work more efficient. if (cellHeight > 0) index = Math.min(y0 / cellHeight, index); // If we have no fixed cell height, we must add up each cell height up // to y0. else { int h = 0; for (int row = 0; row < cellHeights.length; ++row) { h += cellHeights[row]; if (y0 < h) { index = row; break; } } } return index; } /** * Recomputes the {@link #cellHeights}, {@link #cellHeight}, and {@link * #cellWidth} properties by examining the variouis properties of the * {@link JList}. */ protected void updateLayoutState() { int nrows = list.getModel().getSize(); cellHeight = -1; cellWidth = -1; if (cellHeights == null || cellHeights.length != nrows) cellHeights = new int[nrows]; ListCellRenderer rend = list.getCellRenderer(); // Update the cellHeight(s) fields. int fixedCellHeight = list.getFixedCellHeight(); if (fixedCellHeight > 0) { cellHeight = fixedCellHeight; cellHeights = null; } else { cellHeight = -1; for (int i = 0; i < nrows; ++i) { Component flyweight = rend.getListCellRendererComponent(list, list.getModel().getElementAt(i), i, list.isSelectedIndex(i), list.getSelectionModel().getAnchorSelectionIndex() == i); Dimension dim = flyweight.getPreferredSize(); cellHeights[i] = dim.height; } } // Update the cellWidth field. int fixedCellWidth = list.getFixedCellWidth(); if (fixedCellWidth > 0) cellWidth = fixedCellWidth; else { for (int i = 0; i < nrows; ++i) { Component flyweight = rend.getListCellRendererComponent(list, list.getModel().getElementAt(i), i, list.isSelectedIndex(i), list.getSelectionModel().getAnchorSelectionIndex() == i); Dimension dim = flyweight.getPreferredSize(); cellWidth = Math.max(cellWidth, dim.width); } if (list.getLayoutOrientation() == JList.VERTICAL) cellWidth = Math.max(cellWidth, list.getSize().width); } } /** * Marks the current layout as damaged and requests revalidation from the * JList. * This is package-private to avoid an accessor method. * * @see #updateLayoutStateNeeded */ void damageLayout() { updateLayoutStateNeeded = 1; } /** * Calls {@link #updateLayoutState} if {@link #updateLayoutStateNeeded} * is nonzero, then resets {@link #updateLayoutStateNeeded} to zero. */ protected void maybeUpdateLayoutState() { if (updateLayoutStateNeeded != 0) { updateLayoutState(); updateLayoutStateNeeded = 0; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -