Package javax.swing.plaf.basic

Source Code of javax.swing.plaf.basic.BasicTableHeaderUI

/*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
/**
* @author Anton Avtamonov
* @version $Revision$
*/
package javax.swing.plaf.basic;

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

import javax.swing.CellRendererPane;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.TableHeaderUI;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

import org.apache.harmony.x.swing.Utilities;


public class BasicTableHeaderUI extends TableHeaderUI {
    public class MouseInputHandler implements MouseInputListener {
        private final Cursor HEADER_RESIZING_CURSOR = new Cursor(Cursor.E_RESIZE_CURSOR);

        private Cursor originalHeaderCursor;
        private int initialMousePosition;
        private int initialColumnWidth;

        public void mouseClicked(final MouseEvent e) {
        }

        public void mousePressed(final MouseEvent e) {
            initialMousePosition = e.getX();
            TableColumn processedColumn = getResizingColumn(e);
            if (processedColumn != null) {
                header.setResizingColumn(processedColumn);
                initialColumnWidth = processedColumn.getWidth();
                return;
            }
            processedColumn = getReorderingColumn(e);
            if (processedColumn != null) {
                header.setDraggedColumn(processedColumn);
                dragColumn(e);
            }
        }

        public void mouseReleased(final MouseEvent e) {
            if (header.getResizingColumn() != null) {
                header.setResizingColumn(null);
                header.setCursor(originalHeaderCursor);
            } else if (header.getDraggedColumn() != null) {
                header.setDraggedDistance(0);
                int draggingColumnIndex = getColumnIndex(header.getDraggedColumn());
                header.getColumnModel().moveColumn(draggingColumnIndex, draggingColumnIndex);
                header.setDraggedColumn(null);
            }
        }


        public void mouseMoved(final MouseEvent e) {
            updateCursor(e);
        }

        public void mouseDragged(final MouseEvent e) {
            if (header.getResizingColumn() != null) {
                int increment;
                if (header.getTable().getComponentOrientation().isLeftToRight()) {
                    increment = e.getX() - initialMousePosition;
                } else {
                    increment = initialMousePosition - e.getX();
                }
                header.setCursor(HEADER_RESIZING_CURSOR);
                header.getResizingColumn().setWidth(initialColumnWidth + increment);
            } else if (header.getDraggedColumn() != null) {
                dragColumn(e);
            }
        }

        public void mouseEntered(final MouseEvent e) {
            if (header != null) {
                updateCursor(e);
            }
        }

        public void mouseExited(final MouseEvent e) {
            if (header != null) {
                header.setCursor(originalHeaderCursor);
            }
        }


        private void dragColumn(final MouseEvent e) {
            int increment = e.getX() - initialMousePosition;
            int draggingColumnIndex = getColumnIndex(header.getDraggedColumn());
            Rectangle draggingColumnRect = header.getHeaderRect(draggingColumnIndex);
            if (increment > 0) {
                int draggingFront = draggingColumnRect.x + draggingColumnRect.width + increment;
                int swappingColumnIndex = header.columnAtPoint(new Point(draggingFront, 0));
                if (swappingColumnIndex == -1) {
                    swappingColumnIndex = header.getColumnModel().getColumnCount() - 1;
                }
                Rectangle swappingColumnRect = header.getHeaderRect(swappingColumnIndex);
                int swappingColumnCenter = swappingColumnRect.x + swappingColumnRect.width / 2;
                if (draggingColumnIndex != swappingColumnIndex && draggingFront >= swappingColumnCenter) {
                    int distance = increment - swappingColumnRect.width;
                    header.setDraggedDistance(distance);
                    initialMousePosition = e.getX() - distance;
                    header.getColumnModel().moveColumn(draggingColumnIndex, swappingColumnIndex);
                } else {
                    header.setDraggedDistance(increment);
                    header.getColumnModel().moveColumn(draggingColumnIndex, draggingColumnIndex);
                }
            } else {
                int draggingFront = draggingColumnRect.x + increment;
                int swappingColumnIndex = header.columnAtPoint(new Point(draggingFront, 0));
                if (swappingColumnIndex == -1) {
                    swappingColumnIndex = 0;
                }
                Rectangle swappingColumnRect = header.getHeaderRect(swappingColumnIndex);
                int swappingColumnCenter = swappingColumnRect.x + swappingColumnRect.width / 2;
                if (draggingColumnIndex != swappingColumnIndex && draggingFront <= swappingColumnCenter) {
                    int distance = swappingColumnRect.width + increment;
                    header.setDraggedDistance(distance);
                    initialMousePosition = e.getX() - distance;
                    header.getColumnModel().moveColumn(draggingColumnIndex, swappingColumnIndex);
                } else {
                    header.setDraggedDistance(increment);
                    header.getColumnModel().moveColumn(draggingColumnIndex, draggingColumnIndex);
                }
            }
        }

        private TableColumn getResizingColumn(final MouseEvent e) {
            if (!header.getResizingAllowed()) {
                return null;
            }

            int column = header.columnAtPoint(e.getPoint());
            if (column == -1) {
                return null;
            }

            Rectangle columnBounds = header.getHeaderRect(column);
            if (header.getTable().getComponentOrientation().isLeftToRight()) {
                if (column == 0 && columnBounds.x + MOUSE_TOLERANCE > e.getX()) {
                    return null;
                }

                if (columnBounds.x + MOUSE_TOLERANCE > e.getX()) {
                    TableColumn result = header.getColumnModel().getColumn(column - 1);
                    return result.getResizable() ? result : null;
                }
                if (columnBounds.x + columnBounds.width - MOUSE_TOLERANCE < e.getX()) {
                    TableColumn result = header.getColumnModel().getColumn(column);
                    return result.getResizable() ? result : null;
                }
            } else {
                if (column == 0 && columnBounds.x  + columnBounds.width - MOUSE_TOLERANCE < e.getX()) {
                    return null;
                }

                if (columnBounds.x  + columnBounds.width - MOUSE_TOLERANCE < e.getX()) {
                    TableColumn result = header.getColumnModel().getColumn(column - 1);
                    return result.getResizable() ? result : null;
                }
                if (columnBounds.x + MOUSE_TOLERANCE > e.getX()) {
                    TableColumn result = header.getColumnModel().getColumn(column);
                    return result.getResizable() ? result : null;
                }
            }

            return null;
        }

        private TableColumn getReorderingColumn(final MouseEvent e) {
            if (!header.getReorderingAllowed()) {
                return null;
            }

            int column = header.columnAtPoint(e.getPoint());
            if (column == -1) {
                return null;
            }

            return header.getColumnModel().getColumn(column);
        }

        private void updateCursor(final MouseEvent e) {
            if (e == null || e.getButton() > 0 || e.getModifiersEx() > 0) {
                return;
            }

            if (header.getCursor() != HEADER_RESIZING_CURSOR) {
                originalHeaderCursor = header.getCursor();
            }
            header.setCursor(getResizingColumn(e) != null && header.getDraggedColumn() == null ? HEADER_RESIZING_CURSOR : originalHeaderCursor);
        }
    }

    protected JTableHeader header;
    protected CellRendererPane rendererPane;
    protected MouseInputListener mouseInputListener;

    private static final int MOUSE_TOLERANCE = 3;

    private static final SizeInfo MINIMUM_WIDTH_INFO = new SizeInfo() {
        public int getWidth(final TableColumn column) {
            return column.getMinWidth();
        }

        public int getHeight(final TableColumn column, final JTableHeader header, final int columnIndex) {
            Component renderingComponent = getRenderingComponent(column, header, columnIndex);
            return renderingComponent != null ? renderingComponent.getMinimumSize().height : 0;
        }
    };
    private static final SizeInfo MAXIMUM_WIDTH_INFO = new SizeInfo() {
        public int getWidth(final TableColumn column) {
            return column.getMaxWidth();
        }

        public int getHeight(final TableColumn column, final JTableHeader header, final int columnIndex) {
            Component renderingComponent = getRenderingComponent(column, header, columnIndex);
            return renderingComponent != null ? renderingComponent.getMaximumSize().height : 0;
        }
    };
    private static final SizeInfo PREFERRED_WIDTH_INFO = new SizeInfo() {
        public int getWidth(final TableColumn column) {
            return column.getPreferredWidth();
        }

        public int getHeight(final TableColumn column, final JTableHeader header, final int columnIndex) {
            Component renderingComponent = getRenderingComponent(column, header, columnIndex);
            return renderingComponent != null ? renderingComponent.getPreferredSize().height : 0;
        }
    };


    public static ComponentUI createUI(final JComponent c) {
        return new BasicTableHeaderUI();
    }

    public void installUI(final JComponent c) {
        header = (JTableHeader)c;
        rendererPane = new CellRendererPane();

        installDefaults();
        installListeners();
        installKeyboardActions();
    }

    public void uninstallUI(final JComponent c) {
        uninstallKeyboardActions();
        uninstallListeners();
        uninstallDefaults();

        rendererPane = null;
        header = null;
    }

    public void paint(final Graphics g, final JComponent c) {
        Rectangle clipRect = g.getClipBounds();
        for (int i = 0; i < header.getColumnModel().getColumnCount(); i++) {
            TableColumn column = header.getColumnModel().getColumn(i);
            Rectangle columnRect = header.getHeaderRect(i);
            if (header.getDraggedColumn() != column) {
                paintColumn(g, column, clipRect, columnRect, i);
            }
        }

        if (header.getDraggedColumn() != null) {
            int draggedIndex = getColumnIndex(header.getDraggedColumn());
            Rectangle columnRect = header.getHeaderRect(draggedIndex);
            paintBackgroundUnderDraggedCell(g, columnRect);
            columnRect.translate(header.getDraggedDistance(), 0);
            paintColumn(g, header.getDraggedColumn(), clipRect, columnRect, draggedIndex);
        }
    }

    public Dimension getMinimumSize(final JComponent c) {
        return getColumnSize(MINIMUM_WIDTH_INFO);
    }

    public Dimension getMaximumSize(final JComponent c) {
        return getColumnSize(MAXIMUM_WIDTH_INFO);
    }

    public Dimension getPreferredSize(final JComponent c) {
        return getColumnSize(PREFERRED_WIDTH_INFO);
    }


    protected void installDefaults() {
        LookAndFeel.installColorsAndFont(header, "TableHeader.background", "TableHeader.foreground", "TableHeader.font");

        LookAndFeel.installProperty(header, "opaque", Boolean.TRUE);
    }

    protected void uninstallDefaults() {
        if (header != null) {
            Utilities.uninstallColorsAndFont(header);
        }
    }

    protected void installListeners() {
        mouseInputListener = createMouseInputListener();
        if (mouseInputListener != null) {
            header.addMouseListener(mouseInputListener);
            header.addMouseMotionListener(mouseInputListener);
        }
    }

    protected void uninstallListeners() {
        header.removeMouseListener(mouseInputListener);
        header.removeMouseMotionListener(mouseInputListener);
        mouseInputListener = null;
    }

    protected void installKeyboardActions() {
    }

    protected void uninstallKeyboardActions() {
    }

    protected MouseInputListener createMouseInputListener() {
        return new MouseInputHandler();
    }


    private void paintColumn(final Graphics g, final TableColumn column, final Rectangle clipRect, final Rectangle columnRect, final int columnIndex) {
        if (clipRect != null && !clipRect.intersects(columnRect)) {
            return;
        }

        TableCellRenderer renderer = column.getHeaderRenderer() != null ? column.getHeaderRenderer()
                                                                        : header.getDefaultRenderer();

        Component renderingComponent = renderer.getTableCellRendererComponent(header.getTable(), column.getHeaderValue(), false, false, -1, columnIndex);
        rendererPane.paintComponent(g, renderingComponent, header, columnRect);
    }

    private void paintBackgroundUnderDraggedCell(final Graphics g, final Rectangle columnRect) {
        g.setColor(header.getParent().getBackground());
        g.fillRect(columnRect.x, columnRect.y, columnRect.width, columnRect.height);
    }

    private Dimension getColumnSize(final SizeInfo info) {
        int width = 0;
        int height = 0;
        TableColumnModel model = header.getColumnModel();
        for (int i = 0; i < model.getColumnCount(); i++) {
            TableColumn column = model.getColumn(i);
            width += info.getWidth(column);
            int columnHeight = info.getHeight(column, header, i);
            if (height < columnHeight) {
                height = columnHeight;
            }
        }

        return new Dimension(width, height);
    }

    private int getColumnIndex(final TableColumn column) {
        for (int i = 0; i < header.getColumnModel().getColumnCount(); i++) {
            if (header.getColumnModel().getColumn(i) == column) {
                return i;
            }
        }
        return -1;
    }

    private static abstract class SizeInfo {
        protected Component getRenderingComponent(final TableColumn column, final JTableHeader header, final int columnIndex) {
            if (column.getHeaderValue() == null) {
                return null;
            }

            TableCellRenderer renderer = column.getHeaderRenderer() != null ? column.getHeaderRenderer()
                                                                          : header.getDefaultRenderer();

            return renderer.getTableCellRendererComponent(header.getTable(), column.getHeaderValue(), false, false, -1, columnIndex);
        }

        public abstract int getWidth(TableColumn column);
        public abstract int getHeight(TableColumn column, JTableHeader header, int columnIndex);
    }
}
TOP

Related Classes of javax.swing.plaf.basic.BasicTableHeaderUI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.