961 lines · 34.1 KB · Java
RawDownload
/* * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing.plaf.basic; import java.awt.*;import java.awt.event.*;import java.util.*;import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.*;import javax.swing.table.*; import sun.swing.*; /** * BasicTableHeaderUI implementation * * @author Alan Chung * @author Philip Milne */public class BasicTableHeaderUI extends TableHeaderUI {     private static Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR); //// Instance Variables//     /** The JTableHeader that is delegating the painting to this UI. */    protected JTableHeader header;    protected CellRendererPane rendererPane;     // Listeners that are attached to the JTable    protected MouseInputListener mouseInputListener;     // The column header over which the mouse currently is.    private int rolloverColumn = -1;     // The column that should be highlighted when the table header has the focus.    private int selectedColumnIndex = 0; // Read ONLY via getSelectedColumnIndex!     private static FocusListener focusListener = new FocusListener() {        public void focusGained(FocusEvent e) {            repaintHeader(e.getSource());        }         public void focusLost(FocusEvent e) {            repaintHeader(e.getSource());        }         private void repaintHeader(Object source) {            if (source instanceof JTableHeader) {                JTableHeader th = (JTableHeader)source;                BasicTableHeaderUI ui =                   (BasicTableHeaderUI)BasicLookAndFeel.                                        getUIOfType(th.getUI(),                                            BasicTableHeaderUI.class);                if (ui == null) {                    return;                }                 th.repaint(th.getHeaderRect(ui.getSelectedColumnIndex()));            }        }    };     /**     * This class should be treated as a &quot;protected&quot; inner class.     * Instantiate it only within subclasses of {@code BasicTableHeaderUI}.     */    public class MouseInputHandler implements MouseInputListener {         private int mouseXOffset;        private Cursor otherCursor = resizeCursor;         public void mouseClicked(MouseEvent e) {            if (!header.isEnabled()) {                return;            }            if (e.getClickCount() % 2 == 1 &&                    SwingUtilities.isLeftMouseButton(e)) {                JTable table = header.getTable();                RowSorter sorter;                if (table != null && (sorter = table.getRowSorter()) != null) {                    int columnIndex = header.columnAtPoint(e.getPoint());                    if (columnIndex != -1) {                        columnIndex = table.convertColumnIndexToModel(                                columnIndex);                        sorter.toggleSortOrder(columnIndex);                    }                }            }        }         private TableColumn getResizingColumn(Point p) {            return getResizingColumn(p, header.columnAtPoint(p));        }         private TableColumn getResizingColumn(Point p, int column) {            if (column == -1) {                 return null;            }            Rectangle r = header.getHeaderRect(column);            r.grow(-3, 0);            if (r.contains(p)) {                return null;            }            int midPoint = r.x + r.width/2;            int columnIndex;            if( header.getComponentOrientation().isLeftToRight() ) {                columnIndex = (p.x < midPoint) ? column - 1 : column;            } else {                columnIndex = (p.x < midPoint) ? column : column - 1;            }            if (columnIndex == -1) {                return null;            }            return header.getColumnModel().getColumn(columnIndex);        }         public void mousePressed(MouseEvent e) {            if (!header.isEnabled()) {                return;            }            header.setDraggedColumn(null);            header.setResizingColumn(null);            header.setDraggedDistance(0);             Point p = e.getPoint();             // First find which header cell was hit            TableColumnModel columnModel = header.getColumnModel();            int index = header.columnAtPoint(p);             if (index != -1) {                // The last 3 pixels + 3 pixels of next column are for resizing                TableColumn resizingColumn = getResizingColumn(p, index);                if (canResize(resizingColumn, header)) {                    header.setResizingColumn(resizingColumn);                    if( header.getComponentOrientation().isLeftToRight() ) {                        mouseXOffset = p.x - resizingColumn.getWidth();                    } else {                        mouseXOffset = p.x + resizingColumn.getWidth();                    }                }                else if (header.getReorderingAllowed()) {                    TableColumn hitColumn = columnModel.getColumn(index);                    header.setDraggedColumn(hitColumn);                    mouseXOffset = p.x;                }            }             if (header.getReorderingAllowed()) {                int oldRolloverColumn = rolloverColumn;                rolloverColumn = -1;                rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);            }        }         private void swapCursor() {            Cursor tmp = header.getCursor();            header.setCursor(otherCursor);            otherCursor = tmp;        }         public void mouseMoved(MouseEvent e) {            if (!header.isEnabled()) {                return;            }            if (canResize(getResizingColumn(e.getPoint()), header) !=                (header.getCursor() == resizeCursor)) {                swapCursor();            }            updateRolloverColumn(e);       }         public void mouseDragged(MouseEvent e) {            if (!header.isEnabled()) {                return;            }            int mouseX = e.getX();             TableColumn resizingColumn  = header.getResizingColumn();            TableColumn draggedColumn  = header.getDraggedColumn();             boolean headerLeftToRight = header.getComponentOrientation().isLeftToRight();             if (resizingColumn != null) {                int oldWidth = resizingColumn.getWidth();                int newWidth;                if (headerLeftToRight) {                    newWidth = mouseX - mouseXOffset;                } else  {                    newWidth = mouseXOffset - mouseX;                }                mouseXOffset += changeColumnWidth(resizingColumn, header,                                                  oldWidth, newWidth);            }            else if (draggedColumn != null) {                TableColumnModel cm = header.getColumnModel();                int draggedDistance = mouseX - mouseXOffset;                int direction = (draggedDistance < 0) ? -1 : 1;                int columnIndex = viewIndexForColumn(draggedColumn);                int newColumnIndex = columnIndex + (headerLeftToRight ? direction : -direction);                if (0 <= newColumnIndex && newColumnIndex < cm.getColumnCount()) {                    int width = cm.getColumn(newColumnIndex).getWidth();                    if (Math.abs(draggedDistance) > (width / 2)) {                         mouseXOffset = mouseXOffset + direction * width;                        header.setDraggedDistance(draggedDistance - direction * width);                         //Cache the selected column.                        int selectedIndex =                                SwingUtilities2.convertColumnIndexToModel(                                        header.getColumnModel(),                                        getSelectedColumnIndex());                         //Now do the move.                        cm.moveColumn(columnIndex, newColumnIndex);                         //Update the selected index.                        selectColumn(                            SwingUtilities2.convertColumnIndexToView(                                    header.getColumnModel(), selectedIndex),                            false);                         return;                    }                }                setDraggedDistance(draggedDistance, columnIndex);            }             updateRolloverColumn(e);        }         public void mouseReleased(MouseEvent e) {            if (!header.isEnabled()) {                return;            }            setDraggedDistance(0, viewIndexForColumn(header.getDraggedColumn()));             header.setResizingColumn(null);            header.setDraggedColumn(null);             updateRolloverColumn(e);        }         public void mouseEntered(MouseEvent e) {            if (!header.isEnabled()) {                return;            }            updateRolloverColumn(e);        }         public void mouseExited(MouseEvent e) {            if (!header.isEnabled()) {                return;            }            int oldRolloverColumn = rolloverColumn;            rolloverColumn = -1;            rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);        }//// Protected & Private Methods//         private void setDraggedDistance(int draggedDistance, int column) {            header.setDraggedDistance(draggedDistance);            if (column != -1) {                header.getColumnModel().moveColumn(column, column);            }        }    } ////  Factory methods for the Listeners//     /**     * Creates the mouse listener for the JTableHeader.     */    protected MouseInputListener createMouseInputListener() {        return new MouseInputHandler();    } ////  The installation/uninstall procedures and support//     public static ComponentUI createUI(JComponent h) {        return new BasicTableHeaderUI();    } //  Installation     public void installUI(JComponent c) {        header = (JTableHeader)c;         rendererPane = new CellRendererPane();        header.add(rendererPane);         installDefaults();        installListeners();        installKeyboardActions();    }     /**     * Initializes JTableHeader properties such as font, foreground, and background.     * The font, foreground, and background properties are only set if their     * current value is either null or a UIResource, other properties are set     * if the current value is null.     *     * @see #installUI     */    protected void installDefaults() {        LookAndFeel.installColorsAndFont(header, "TableHeader.background",                                         "TableHeader.foreground", "TableHeader.font");        LookAndFeel.installProperty(header, "opaque", Boolean.TRUE);    }     /**     * Attaches listeners to the JTableHeader.     */    protected void installListeners() {        mouseInputListener = createMouseInputListener();         header.addMouseListener(mouseInputListener);        header.addMouseMotionListener(mouseInputListener);        header.addFocusListener(focusListener);    }     /**     * Register all keyboard actions on the JTableHeader.     */    protected void installKeyboardActions() {        InputMap keyMap = (InputMap)DefaultLookup.get(header, this,                "TableHeader.ancestorInputMap");        SwingUtilities.replaceUIInputMap(header,                                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);        LazyActionMap.installLazyActionMap(header, BasicTableHeaderUI.class,                "TableHeader.actionMap");    } // Uninstall methods     public void uninstallUI(JComponent c) {        uninstallDefaults();        uninstallListeners();        uninstallKeyboardActions();         header.remove(rendererPane);        rendererPane = null;        header = null;    }     protected void uninstallDefaults() {}     protected void uninstallListeners() {        header.removeMouseListener(mouseInputListener);        header.removeMouseMotionListener(mouseInputListener);         mouseInputListener = null;    }     /**     * Unregisters default key actions.     */    protected void uninstallKeyboardActions() {        SwingUtilities.replaceUIInputMap(header, JComponent.WHEN_FOCUSED, null);        SwingUtilities.replaceUIActionMap(header, null);    }     /**     * Populates TableHeader's actions.     */    static void loadActionMap(LazyActionMap map) {        map.put(new Actions(Actions.TOGGLE_SORT_ORDER));        map.put(new Actions(Actions.SELECT_COLUMN_TO_LEFT));        map.put(new Actions(Actions.SELECT_COLUMN_TO_RIGHT));        map.put(new Actions(Actions.MOVE_COLUMN_LEFT));        map.put(new Actions(Actions.MOVE_COLUMN_RIGHT));        map.put(new Actions(Actions.RESIZE_LEFT));        map.put(new Actions(Actions.RESIZE_RIGHT));        map.put(new Actions(Actions.FOCUS_TABLE));    } //// Support for mouse rollover//     /**     * Returns the index of the column header over which the mouse     * currently is. When the mouse is not over the table header,     * -1 is returned.     *     * @see #rolloverColumnUpdated(int, int)     * @return the index of the current rollover column     * @since 1.6     */    protected int getRolloverColumn() {        return rolloverColumn;    }     /**     * This method gets called every time when a rollover column in the table     * header is updated. Every look and feel that supports a rollover effect     * in a table header should override this method and repaint the header.     *     * @param oldColumn the index of the previous rollover column or -1 if the     * mouse was not over a column     * @param newColumn the index of the new rollover column or -1 if the mouse     * is not over a column     * @see #getRolloverColumn()     * @see JTableHeader#getHeaderRect(int)     * @since 1.6     */    protected void rolloverColumnUpdated(int oldColumn, int newColumn) {    }     private void updateRolloverColumn(MouseEvent e) {        if (header.getDraggedColumn() == null &&            header.contains(e.getPoint())) {             int col = header.columnAtPoint(e.getPoint());            if (col != rolloverColumn) {                int oldRolloverColumn = rolloverColumn;                rolloverColumn = col;                rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);            }        }    } //// Support for keyboard and mouse access//    private int selectNextColumn(boolean doIt) {        int newIndex = getSelectedColumnIndex();        if (newIndex < header.getColumnModel().getColumnCount() - 1) {            newIndex++;            if (doIt) {                selectColumn(newIndex);            }        }        return newIndex;    }     private int selectPreviousColumn(boolean doIt) {        int newIndex = getSelectedColumnIndex();        if (newIndex > 0) {            newIndex--;            if (doIt) {                selectColumn(newIndex);            }        }        return newIndex;    }     /**     * Selects the specified column in the table header. Repaints the     * affected header cells and makes sure the newly selected one is visible.     */    void selectColumn(int newColIndex) {        selectColumn(newColIndex, true);    }     void selectColumn(int newColIndex, boolean doScroll) {        Rectangle repaintRect = header.getHeaderRect(selectedColumnIndex);        header.repaint(repaintRect);        selectedColumnIndex = newColIndex;        repaintRect = header.getHeaderRect(newColIndex);        header.repaint(repaintRect);        if (doScroll) {            scrollToColumn(newColIndex);        }        return;    }    /**

Lines 1–500 of 961.