Ticket #20164: 20164.patch

File 20164.patch, 7.4 KB (added by Solarspot, 5 years ago)

In the attached patch the scrolling logic of this table is borrowed from javax.swing.JTextArea. That makes the scrolling smoother

  • src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDiscussionPanel.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDiscussionPanel.java b/src/org/openstreetmap/josm/gui/dialogs/changeset/ChangesetDiscussionPanel.java
    a b  
    2626import org.openstreetmap.josm.data.osm.Changeset;
    2727import org.openstreetmap.josm.gui.MainApplication;
    2828import org.openstreetmap.josm.gui.NoteInputDialog;
     29import org.openstreetmap.josm.gui.widgets.LargeTextTable;
    2930import org.openstreetmap.josm.io.NetworkManager;
    3031import org.openstreetmap.josm.io.OnlineResource;
    3132import org.openstreetmap.josm.io.OsmApi;
     
    168169
    169170    private Component buildDiscussionPanel() {
    170171        JPanel pnl = new JPanel(new BorderLayout());
    171         table = new JTable(model, new ChangesetDiscussionTableColumnModel());
     172        table = new LargeTextTable(model, new ChangesetDiscussionTableColumnModel());
    172173        table.setRowSorter(new ChangesetDiscussionTableRowSorter(model));
    173174        table.getTableHeader().setReorderingAllowed(false);
    174175
  • new file src/org/openstreetmap/josm/gui/widgets/LargeTextTable.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/src/org/openstreetmap/josm/gui/widgets/LargeTextTable.java b/src/org/openstreetmap/josm/gui/widgets/LargeTextTable.java
    new file mode 100644
    - +  
     1package org.openstreetmap.josm.gui.widgets;
     2
     3import java.awt.FontMetrics;
     4import java.awt.Rectangle;
     5
     6import javax.swing.JTable;
     7import javax.swing.SwingConstants;
     8import javax.swing.table.TableColumnModel;
     9import javax.swing.table.TableModel;
     10
     11/**
     12 * Table with a scrolling behavior that is better suited for cells with large amounts of text.
     13 * <p>
     14 * The scrolling in the {@link javax.swing.JTable} is well suited for tables with rows of small and constant height.
     15 * If the height of the rows varies greatly or if some cells contain a lot of text, the scrolling becomes messy.
     16 * <p>
     17 * This class {@code LargeTextTable} has the same scrolling behavior as {@link javax.swing.JTextArea}:
     18 * scrolling increments depend on the font size.
     19 */
     20public class LargeTextTable extends JTable {
     21
     22    private int fontHeight;
     23    private int charWidth;
     24
     25    public LargeTextTable(TableModel tableModel, TableColumnModel tableColumnModel) {
     26        super(tableModel, tableColumnModel);
     27    }
     28
     29    @Override
     30    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
     31        switch (orientation) {
     32            case SwingConstants.VERTICAL:
     33                return getFontHeight();
     34            case SwingConstants.HORIZONTAL:
     35                return getCharWidth();
     36            default:
     37                throw new IllegalArgumentException("Invalid orientation: " + orientation);
     38        }
     39    }
     40
     41    @Override
     42    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
     43        switch (orientation) {
     44            case SwingConstants.VERTICAL:
     45                return visibleRect.height;
     46            case SwingConstants.HORIZONTAL:
     47                return visibleRect.width;
     48            default:
     49                throw new IllegalArgumentException("Invalid orientation: " + orientation);
     50        }
     51    }
     52
     53    private int getFontHeight() {
     54        if (fontHeight == 0) {
     55            FontMetrics fontMetrics = getFontMetrics(getFont());
     56            fontHeight = fontMetrics.getHeight();
     57        }
     58        return fontHeight;
     59    }
     60
     61    // see javax.swing.JTextArea#getColumnWidth()
     62    private int getCharWidth() {
     63        if (charWidth == 0) {
     64            FontMetrics fontMetrics = getFontMetrics(getFont());
     65            charWidth = fontMetrics.charWidth('m');
     66        }
     67        return charWidth;
     68    }
     69}
  • new file test/unit/org/openstreetmap/josm/gui/widgets/LargeTextTableTest.java

    IDEA additional info:
    Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
    <+>UTF-8
    diff --git a/test/unit/org/openstreetmap/josm/gui/widgets/LargeTextTableTest.java b/test/unit/org/openstreetmap/josm/gui/widgets/LargeTextTableTest.java
    new file mode 100644
    - +  
     1package org.openstreetmap.josm.gui.widgets;
     2
     3import static org.hamcrest.CoreMatchers.is;
     4import static org.hamcrest.MatcherAssert.assertThat;
     5import static org.junit.jupiter.api.Assertions.assertThrows;
     6
     7import java.awt.Font;
     8import java.awt.FontMetrics;
     9import java.awt.Rectangle;
     10
     11import javax.swing.JTable;
     12import javax.swing.SwingConstants;
     13
     14import org.junit.jupiter.api.Test;
     15
     16import sun.swing.SwingUtilities2;
     17
     18class LargeTextTableTest {
     19    private JTable table = new LargeTextTable(null, null);
     20    private Rectangle visibleRectangle = new Rectangle(0, 0, 101, 202);
     21
     22    @Test
     23    void testGetScrollableBlockIncrementVertical() {
     24        int scrollableBlockIncrement = table.getScrollableBlockIncrement(visibleRectangle, SwingConstants.VERTICAL, 0);
     25
     26        assertThat(scrollableBlockIncrement, is(202));
     27    }
     28
     29    @Test
     30    void testGetScrollableBlockIncrementHorizontal() {
     31        int scrollableBlockIncrement = table.getScrollableBlockIncrement(visibleRectangle, SwingConstants.HORIZONTAL, 0);
     32
     33        assertThat(scrollableBlockIncrement, is(101));
     34    }
     35
     36    @Test
     37    void testGetScrollableBlockIncrementWithInvalidOrientation() {
     38        assertThrows(IllegalArgumentException.class,
     39                () -> table.getScrollableBlockIncrement(visibleRectangle, -11, 0));
     40    }
     41
     42    @Test
     43    void testGetScrollableUnitIncrementVertical() {
     44        Font font = new Font("", Font.PLAIN, 10);
     45        table.setFont(font);
     46
     47        int actualIncrement = table.getScrollableUnitIncrement(visibleRectangle, SwingConstants.VERTICAL, 0);
     48        int expectedIncrement = getFontMetrics(font).getHeight();
     49
     50        assertThat(actualIncrement, is(expectedIncrement));
     51    }
     52
     53    @Test
     54    void testGetScrollableUnitIncrementHorizontal() {
     55        Font font = new Font("", Font.PLAIN, 10);
     56        table.setFont(font);
     57
     58        int actualIncrement = table.getScrollableUnitIncrement(visibleRectangle, SwingConstants.HORIZONTAL, 0);
     59        int expectedIncrement = getFontMetrics(font).charWidth('m');
     60
     61        assertThat(actualIncrement, is(expectedIncrement));
     62    }
     63
     64    private FontMetrics getFontMetrics(Font font) {
     65        return SwingUtilities2.getFontMetrics(table, font);
     66    }
     67
     68    @Test
     69    void testGetScrollableUnitIncrementWithInvalidOrientation() {
     70        assertThrows(IllegalArgumentException.class, () -> table.getScrollableUnitIncrement(visibleRectangle, -11, 0));
     71
     72    }
     73}
     74 No newline at end of file