2

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?).

Community
  • 1
  • 1
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • A JTextPane will automatically wrap when the line length is greater than the width of the viewport of the scrollpane. The layout manager you use will determine the size of the scrollpane based on the space available in the frame. Post your [mcve] that demonstrates the problem. – camickr Apr 12 '17 at 14:17
  • Check this : http://stackoverflow.com/questions/39455573/how-to-set-fixed-width-but-dynamic-height-on-jtextpane/39466255#39466255 – Sharcoux Apr 12 '17 at 23:19

1 Answers1

3

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);
    }
};
Alexey Romanov
  • 167,066
  • 35
  • 309
  • 487
  • 2
    Yes, this is the appropriate method to override if you want to suggest a preferred size for the scrollpane. Then the layout manager can use this information. – camickr Apr 12 '17 at 14:18