5

I am new in Java, and I just found this piece of code in StackOverflow: ResizeTextArea.

I want to use JTextPane instead of JTextArea. In JTextPane, there is no setRows() method to change the number of the lines. Any help would be appreciated.

Community
  • 1
  • 1
user2049371
  • 189
  • 1
  • 2
  • 16
  • *"I want to use jTextPane instead of jTextArea"* Why? Note also that both those class names start with an upper case `J`. Please stop 'talking like your IDE' and put the *correct* names. – Andrew Thompson Feb 23 '13 at 11:25
  • What facilities? trashgod's answer below assumes you want lines of varying heights. I'm thinking maybe you want to use the text pane for lines of varying colors, in which case the Font of the text pane could be used to calculate a line height. The more information your provide, the better the answer. – camickr Feb 23 '13 at 20:46

1 Answers1

9

The height of individual lines in a StyledDocument can vary, so the notion of limiting rows in a JTextPane is not useful. You can limit the preferred size of the scroll pane's viewport to some useful fraction of main panel's size, as shown here and below.

Addendum: As @camickr comments, it's a little easier to override getPreferredSize() in JScrollPane. I've also updated the code to limit growth to a fraction of the current size: 1/3.

image

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.border.EmptyBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

/**
 * @see https://stackoverflow.com/a/15042241/230513
 * @see https://stackoverflow.com/a/14858272/230513
 */
public class LimitTextPaneSize {

    private static final int SIZE = 200;
    private static final double LIMIT = 1 / 3d;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                display();
            }
        });
    }

    private static void display() {
        final JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
        mainPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
        JPanel topPanel = new JPanel() {
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(SIZE, SIZE);
            }
        };
        final JTextPane chatArea = new JTextPane();
        final JScrollPane scrollPane = new JScrollPane(chatArea){
            @Override
            public Dimension getPreferredSize() {
                Dimension d = super.getPreferredSize();
                int desired = (int) (mainPanel.getSize().height * LIMIT);
                int limit = Math.min(desired, d.height);
                return new Dimension(SIZE, limit);
            }
        };
        chatArea.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                updateSize();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateSize();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateSize();
            }

            private void updateSize() {
                mainPanel.revalidate();
            }
        });
        mainPanel.add(topPanel, BorderLayout.CENTER);
        mainPanel.add(scrollPane, BorderLayout.SOUTH);

        JFrame f = new JFrame("LimitTextPaneSize");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(mainPanel);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}
Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 1
    +1, interesting approach. I'm wondering why you choose to override the JViewport? Code seems to work when you override the getPreferredSize() method of the JScrollPane. This would be a little easier to use since you don't need the setViewport() method. – camickr Feb 23 '13 at 21:01
  • 1
    @camickr: You're right! Thank you for commenting; code updated. – trashgod Feb 24 '13 at 02:52
  • @camickr:Thanks for your comments. – user2049371 Feb 24 '13 at 05:21