001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.widgets;
003
004import java.awt.FontMetrics;
005import java.awt.Rectangle;
006
007import javax.swing.JTable;
008import javax.swing.SwingConstants;
009import javax.swing.table.TableColumnModel;
010import javax.swing.table.TableModel;
011
012/**
013 * Table with a scrolling behavior that is better suited for cells with large amounts of text.
014 * <p>
015 * The scrolling in the {@link javax.swing.JTable} is well suited for tables with rows of small and constant height.
016 * If the height of the rows varies greatly or if some cells contain a lot of text, the scrolling becomes messy.
017 * <p>
018 * This class {@code LargeTextTable} has the same scrolling behavior as {@link javax.swing.JTextArea}:
019 * scrolling increments depend on the font size.
020 */
021public class LargeTextTable extends JTable {
022
023    private int fontHeight;
024    private int charWidth;
025
026    public LargeTextTable(TableModel tableModel, TableColumnModel tableColumnModel) {
027        super(tableModel, tableColumnModel);
028    }
029
030    @Override
031    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
032        switch (orientation) {
033            case SwingConstants.VERTICAL:
034                return getFontHeight();
035            case SwingConstants.HORIZONTAL:
036                return getCharWidth();
037            default:
038                throw new IllegalArgumentException("Invalid orientation: " + orientation);
039        }
040    }
041
042    @Override
043    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
044        switch (orientation) {
045            case SwingConstants.VERTICAL:
046                return visibleRect.height;
047            case SwingConstants.HORIZONTAL:
048                return visibleRect.width;
049            default:
050                throw new IllegalArgumentException("Invalid orientation: " + orientation);
051        }
052    }
053
054    private int getFontHeight() {
055        if (fontHeight == 0) {
056            FontMetrics fontMetrics = getFontMetrics(getFont());
057            fontHeight = fontMetrics.getHeight();
058        }
059        return fontHeight;
060    }
061
062    // see javax.swing.JTextArea#getColumnWidth()
063    private int getCharWidth() {
064        if (charWidth == 0) {
065            FontMetrics fontMetrics = getFontMetrics(getFont());
066            charWidth = fontMetrics.charWidth('m');
067        }
068        return charWidth;
069    }
070}