synthlistui.java

来自「java jdk 1.4的源码」· Java 代码 · 共 1,949 行 · 第 1/5 页

JAVA
1,949
字号
/* * @(#)SynthListUI.java	1.8 03/01/23 * * Copyright 2003 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */package com.sun.java.swing.plaf.gtk;import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.*;import javax.swing.text.Position;import java.awt.*;import java.awt.event.*;import java.awt.datatransfer.Transferable;import java.awt.dnd.*;import java.util.ArrayList;import java.util.TooManyListenersException;import java.beans.PropertyChangeListener;import java.beans.PropertyChangeEvent;/** * A Windows L&F implementation of ListUI. * <p> * * @version 1.8, 01/23/03 (based on BasicListUI v 1.91) * @author Hans Muller * @author Philip Milne */class SynthListUI extends ListUI implements SynthUI {    protected JList list = null;    private SynthStyle style;    protected CellRendererPane rendererPane;    // Listeners that this UI attaches to the JList    protected FocusListener focusListener;    protected MouseInputListener mouseInputListener;    protected ListSelectionListener listSelectionListener;    protected ListDataListener listDataListener;    protected PropertyChangeListener propertyChangeListener;    private KeyListener keyListener;    // PENDING(hmuller) need a doc pointer to #getRowHeight, #maybeUpdateLayoutState    protected int[] cellHeights = null;    protected int cellHeight = -1;    protected int cellWidth = -1;    protected int updateLayoutStateNeeded = modelChanged;    /**     * Height of the list. When asked to paint, if the current size of     * the list differs, this will update the layout state.     */    private int listHeight;    /**     * Width of the list. When asked to paint, if the current size of     * the list differs, this will update the layout state.     */    private int listWidth;    /**     * The layout orientation of the list.     */    private int layoutOrientation;    // Following ivars are used if the list is laying out horizontally    /**     * Number of columns to create.     */    private int columnCount;    /**     * Preferred height to make the list, this is only used if the      * the list is layed out horizontally.     */    private int preferredHeight;    /**     * Number of rows per column. This is only used if the row height is     * fixed.     */    private int rowsPerColumn;    /* The bits below define JList property changes that affect layout.     * When one of these properties changes we set a bit in     * updateLayoutStateNeeded.  The change is dealt with lazily, see     * maybeUpdateLayoutState.  Changes to the JLists model, e.g. the     * models length changed, are handled similarly, see DataListener.     */    protected final static int modelChanged = 1 << 0;    protected final static int selectionModelChanged = 1 << 1;    protected final static int fontChanged = 1 << 2;    protected final static int fixedCellWidthChanged = 1 << 3;    protected final static int fixedCellHeightChanged = 1 << 4;    protected final static int prototypeCellValueChanged = 1 << 5;    protected final static int cellRendererChanged = 1 << 6;    private final static int layoutOrientationChanged = 1 << 7;    private final static int heightChanged = 1 << 8;    private final static int widthChanged = 1 << 9;    private final static int componentOrientationChanged = 1 << 10;    public static void loadActionMap(ActionMap map) {        // NOTE: this needs to remain static. If you have a need to        // have Actions that reference the UI in the ActionMap,        // then you'll also need to change the registeration of the        // ActionMap.	map.put("selectPreviousColumn",		    new IncrementLeadByColumnAction("selectPreviousColumn",						     CHANGE_SELECTION, -1));	map.put("selectPreviousColumnExtendSelection",		    new IncrementLeadByColumnAction		    ("selectPreviousColumnExtendSelection",                     EXTEND_SELECTION, -1));	map.put("selectNextColumn",		    new IncrementLeadByColumnAction("selectNextColumn",						     CHANGE_SELECTION, 1));	map.put("selectNextColumnExtendSelection",		    new IncrementLeadByColumnAction		    ("selectNextColumnExtendSelection", EXTEND_SELECTION, 1));	map.put("selectPreviousRow",		    new IncrementLeadSelectionAction("selectPreviousRow",						     CHANGE_SELECTION, -1));	map.put("selectPreviousRowExtendSelection",		    new IncrementLeadSelectionAction		    ("selectPreviousRowExtendSelection",EXTEND_SELECTION, -1));	map.put("selectNextRow",		    new IncrementLeadSelectionAction("selectNextRow",						     CHANGE_SELECTION, 1));	map.put("selectNextRowExtendSelection",		    new IncrementLeadSelectionAction		    ("selectNextRowExtendSelection", EXTEND_SELECTION, 1));	map.put("selectFirstRow",		    new HomeAction("selectFirstRow", CHANGE_SELECTION));	map.put("selectFirstRowExtendSelection",		    new HomeAction("selectFirstRowExtendSelection",				   EXTEND_SELECTION));	map.put("selectLastRow",		    new EndAction("selctLastRow", CHANGE_SELECTION));	map.put("selectLastRowExtendSelection",		    new EndAction("selectLastRowExtendSelection",				  EXTEND_SELECTION));	map.put("scrollUp",		    new PageUpAction("scrollUp", CHANGE_SELECTION));	map.put("scrollUpExtendSelection",		    new PageUpAction("scrollUpExtendSelection",				     EXTEND_SELECTION));	map.put("scrollDown",		    new PageDownAction("scrollDown", CHANGE_SELECTION));	map.put("scrollDownExtendSelection",		    new PageDownAction("scrollDownExtendSelection",				       EXTEND_SELECTION));	map.put("selectAll", new SelectAllAction("selectAll"));	map.put("clearSelection", new 		    ClearSelectionAction("clearSelection"));        map.put(TransferHandler.getCutAction().getValue(Action.NAME),                TransferHandler.getCutAction());        map.put(TransferHandler.getCopyAction().getValue(Action.NAME),                TransferHandler.getCopyAction());        map.put(TransferHandler.getPasteAction().getValue(Action.NAME),                TransferHandler.getPasteAction());    }    /**     * Paint one List cell: compute the relevant state, get the "rubber stamp"     * cell renderer component, and then use the CellRendererPane to paint it.     * Subclasses may want to override this method rather than paint().     *     * @see #paint     */    protected void paintCell(        Graphics g,        int row,        Rectangle rowBounds,        ListCellRenderer cellRenderer,        ListModel dataModel,        ListSelectionModel selModel,        int leadIndex)    {        Object value = dataModel.getElementAt(row);        boolean cellHasFocus = list.hasFocus() && (row == leadIndex);        boolean isSelected = selModel.isSelectedIndex(row);        Component rendererComponent =            cellRenderer.getListCellRendererComponent(list, value, row, isSelected, cellHasFocus);        int cx = rowBounds.x;        int cy = rowBounds.y;        int cw = rowBounds.width;        int ch = rowBounds.height;        rendererPane.paintComponent(g, rendererComponent, list, cx, cy, cw, ch, true);    }    /**     * Paint the rows that intersect the Graphics objects clipRect.  This     * method calls paintCell as necessary.  Subclasses     * may want to override these methods.     *     * @see #paintCell     */    public void update(Graphics g, JComponent c) {        SynthContext context = getContext(c);        SynthLookAndFeel.update(context, g);        paint(context, g);        context.dispose();    }    public void paint(Graphics g, JComponent c) {        SynthContext context = getContext(c);        paint(context, g);        context.dispose();    }    protected void paint(SynthContext context, Graphics g) {        switch (layoutOrientation) {        case JList.VERTICAL_WRAP:            if (list.getHeight() != listHeight) {                updateLayoutStateNeeded |= heightChanged;                redrawList();            }            break;        case JList.HORIZONTAL_WRAP:            if (list.getWidth() != listWidth) {                updateLayoutStateNeeded |= widthChanged;                redrawList();            }            break;        default:            break;        }        maybeUpdateLayoutState();        ListCellRenderer renderer = list.getCellRenderer();        ListModel dataModel = list.getModel();        ListSelectionModel selModel = list.getSelectionModel();        int size;        if ((renderer == null) || (size = dataModel.getSize()) == 0) {            return;        }        // Determine how many columns we need to paint        Rectangle paintBounds = g.getClipBounds();	int startColumn, endColumn;	if (SynthLookAndFeel.isLeftToRight(list)) {            startColumn = convertLocationToColumn(paintBounds.x,                                                  paintBounds.y);	    endColumn = convertLocationToColumn(paintBounds.x +                                                paintBounds.width,                                                paintBounds.y);	} else {	    startColumn = convertLocationToColumn(paintBounds.x +                                                paintBounds.width,                                                paintBounds.y);            endColumn = convertLocationToColumn(paintBounds.x,                                                  paintBounds.y);	}        int maxY = paintBounds.y + paintBounds.height;        int leadIndex = list.getLeadSelectionIndex();        int rowIncrement = (layoutOrientation == JList.HORIZONTAL_WRAP) ?                           columnCount : 1;        for (int colCounter = startColumn; colCounter <= endColumn;             colCounter++) {            // And then how many rows in this columnn            int row = convertLocationToRowInColumn(paintBounds.y, colCounter);            int rowCount = getRowCount(colCounter);            int index = getModelIndex(colCounter, row);            Rectangle rowBounds = getCellBounds(list, index, index);            if (rowBounds == null) {                // Not valid, bail!                return;            }            while (row < rowCount && rowBounds.y < maxY &&                   index < size) {                rowBounds.height = getHeight(colCounter, row);                g.setClip(rowBounds.x, rowBounds.y, rowBounds.width,                          rowBounds.height);                g.clipRect(paintBounds.x, paintBounds.y, paintBounds.width,                           paintBounds.height);                paintCell(g, index, rowBounds, renderer, dataModel, selModel,                          leadIndex);                rowBounds.y += rowBounds.height;                index += rowIncrement;                row++;            }        }    }    /**     * The preferredSize of the list depends upon the layout orientation.     * <table><tr><td>Layout Orientation</td><td>Preferred Size</td></tr>     * <tr>     *   <td>JList.VERTICAL     *   <td>The preferredSize of the list is total height of the rows     *       and the maximum width of the cells.  If JList.fixedCellHeight     *       is specified then the total height of the rows is just     *       (cellVerticalMargins + fixedCellHeight) * model.getSize() where     *       rowVerticalMargins is the space we allocate for drawing     *       the yellow focus outline.  Similarly if fixedCellWidth is     *       specified then we just use that.     *   </td>     * <tr>     *   <td>JList.VERTICAL_WRAP     *   <td>If the visible row count is greater than zero, the preferredHeight     *       is the maximum cell height * visibleRowCount. If the visible row     *       count is <= 0, the preferred height is either the current height     *       of the list, or the maximum cell height, whichever is     *       bigger. The preferred width is than the maximum cell width *     *       number of columns needed. Where the number of columns needs is     *       list.height / max cell height. Max cell height is either the fixed     *       cell height, or is determined by iterating through all the cells     *       to find the maximum height from the ListCellRenderer.     * <tr>     *   <td>JList.HORIZONTAL_WRAP     *   <td>If the visible row count is greater than zero, the preferredHeight     *       is the maximum cell height * adjustedRowCount.  Where     *       visibleRowCount is used to determine the number of columns.     *       Because this lays out horizontally the number of rows is     *       then determined from the column count.  For example, lets say     *       you have a model with 10 items and the visible row count is 8.     *       The number of columns needed to display this is 2, but you no     *       longer need 8 rows to display this, you only need 5, thus     *       the adjustedRowCount is 5.     *       <p>If the visible row     *       count is <= 0, the preferred height is dictated by the      *       number of columns, which will be as many as can fit in the width     *       of the <code>JList</code> (width / max cell width), with at     *       least one column.  The preferred height then becomes the     *       model size / number of columns * maximum cell height.     *       Max cell height is either the fixed     *       cell height, or is determined by iterating through all the cells     *       to find the maximum height from the ListCellRenderer.     * </table>     * The above specifies the raw preferred width and height. The resulting     * preferred width is the above width + insets.left + insets.right and     * the resulting preferred height is the above height + insets.top +     * insets.bottom. Where the <code>Insets</code> are determined from     * <code>list.getInsets()</code>.     *     * @param c The JList component.     * @return The total size of the list.     */    public Dimension getPreferredSize(JComponent c) {        maybeUpdateLayoutState();        int lastRow = list.getModel().getSize() - 1;        if (lastRow < 0) {            return new Dimension(0, 0);        }        Insets insets = list.getInsets();        int width = cellWidth * columnCount + insets.left + insets.right;        int height;        if (layoutOrientation != JList.VERTICAL) {            height = preferredHeight;        }        else {            Rectangle bounds = getCellBounds(list, lastRow);            if (bounds != null) {                height = bounds.y + bounds.height + insets.bottom;            }            else {                height = 0;            }        }        return new Dimension(width, height);    }    /**     * @return the preferred size     * @see #getPreferredSize     */    public Dimension getMinimumSize(JComponent c) {        return getPreferredSize(c);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?