views:

619

answers:

2

I'm trying to get a JTextPane to adjust its height according to whatever content I feed it. All I can do is to set a fixed height in pixels using Dimension.

How do I make the JTextPane collapse/expand so it will fit to contents?

I might add that I use this in a GridBagLayout'ed JPanel that has been added to a JScrollPane.

+1  A: 

I don't know any direct way to do it, but this may give you some ideas:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class TextPanePerfectSize extends JFrame
{
    JTextField textField;
    JTextPane textPane;

    public TextPanePerfectSize()
    {
        textField = new JTextField(20);
        textField.setText("add text");
        getContentPane().add(textField, BorderLayout.NORTH );
        textField.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try
                {
                    Document doc = textPane.getDocument();
                    doc.insertString(doc.getLength(), " " + textField.getText(), null);
                    textField.setText("");
                    Dimension d = textPane.getPreferredSize();
                    Rectangle r = textPane.modelToView( textPane.getDocument().getLength() );
                    d.height = r.y + r.height;
                    textPane.setPreferredSize( d );
                    getContentPane().validate();
//                    pack();
                }
                catch(Exception e2) {}
            }
        });

        JLabel label = new JLabel("Hit Enter to Add Text to Text Pane");
        getContentPane().add(label);

        JPanel south = new JPanel();
        textPane = new JTextPane();
        textPane.setText("Some text");
        textPane.setEditable( false );
        textPane.setPreferredSize( new Dimension(120, 23) );

        south.add( textPane );
        getContentPane().add(south, BorderLayout.SOUTH);
    }

    public static void main(String[] args)
    {
        JFrame frame = new TextPanePerfectSize();
        frame.setSize(200, 200);
        frame.setLocationRelativeTo( null );
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
camickr
It sort of works and then not. modelToView returns null. According to the documentation the component must have been sized for it to work. I've tried validate(), repaint(), pack() but nothing helps. Do I need to call one of these methods on some ancestor component? The JTextPane is added to a JPanel which exists inside a JPanel which again is inside a JScrollPane added to a JFrame...
fiskeben
A: 

JTextPane tp = new JTextPane();

setLayout(new BorderLayout()); // set layout on parent

add(tp, BorderLayout.CENTER);

Seems to work for me.

Dan Howard