Alexey Romanov
Alexey Romanov

Reputation: 170733

Limit size of a JTextPane inside a JScrollPane

JTextArea has a setColumns method to set maximum number of columns, but JTextPane doesn't. Of course, it can have different fonts in a single pane, so setting number of columns or rows doesn't exactly make sense. However, when I create a dialog containing a JTextPane inside a JScrollPane and setText to a long string, it grows to the entire width of the screen and a single row, which I want to prevent.

setMaximumSize doesn't seem to have an effect and is not recommended at any rate (see Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?).

Upvotes: 2

Views: 1129

Answers (1)

Alexey Romanov
Alexey Romanov

Reputation: 170733

My current solution, which seems quite ugly, is to extend JTextPane, borrowing code from JTextArea implementation:

textArea = new JTextPane() {
    int maxWidth;
    int rowHeight;

    void init(Font font) {
        FontMetrics fontMetrics = getFontMetrics(font);
        maxWidth = fontMetrics.charWidth('M') * 80;
        rowHeight = fontMetrics.getHeight();
    }

    {
        initFont(getFont());
    }

    @Override
    public void setFont(Font font) {
        init(font);
        super.setFont(font);
    }

    @Override
    public Dimension getPreferredScrollableViewportSize() {
        Dimension base = super.getPreferredSize();
        Insets insets = getInsets();
        int width = Math.min(maxWidth, base.width) + insets.left + insets.right;
        int estimatedRows = Math.max(1, (int) Math.ceil(base.getWidth() / maxWidth));
        int height = estimatedRows * rowHeight + insets.top + insets.bottom;
            return new Dimension(width, height);
    }
};

Upvotes: 3

Related Questions