Search code examples
javaswingjscrollpanejtextareaautoresize

How to limit the height of an auto-resizing JTtextArea


I have several text areas aligned vertically. I want them to expand as more text is typed, but put a limit on how tall they'll become.

I've tried setting the max size, but that seems to be ignored. Any ideas?

    _recipients = new JTextArea();
    _recipients.setBorder( BorderFactory.createEtchedBorder() );
    _recipients.setLineWrap( true );
    _recipients.setWrapStyleWord( true );
    _recipients.setMaximumSize( new Dimension( 111, 55 ) );

    _subject = new JTextArea();
    _subject.setBorder( BorderFactory.createEtchedBorder() );
    _subject.setLineWrap( true );
    _subject.setWrapStyleWord( true );
    _subject.setMaximumSize( new Dimension( 111, 55 ) );

    //JComponent area = LAF.Area.clear(  );
    JPanel area = new JPanel( new GridLayout( 1, 2, 6, 0 ) );
    area.setOpaque( false );
    area.add( _recipients );
    area.add( _subject );

    add( area, BorderLayout.CENTER );

I recieved advice that i should use a scroll pain, but that just created an uneditable area

        JScrollPane pain = new JScrollPane();
        pain.add( _recipients );
        area.add( pain );

        pain = new JScrollPane();
        pain.add( _subject );
        area.add( pain );

EDIT

not much more to it, but

public class TestFrame extends JFrame
{
  TestFrame()
  {
    setSize( new DimensionUIResource( 800, 668 ) );
    JPanel area = new JPanel( new FlowLayout( 0, 0, 0 ) );

    Stuff thing = new Stuff();
    area.add( thing );

    add( area );
  }

  public static void main( String args[] )
  {
    TestFrame frame = new TestFrame();
    frame.show();
  }

  private static class Stuff extends JComponent
  {
    private final JTextArea _subject;

    Stuff()
    {
        setLayout( new BorderLayout() );

        _subject = new JTextArea();
        _subject.setBorder( BorderFactory.createEtchedBorder() );
        _subject.setLineWrap( true );
        _subject.setWrapStyleWord( true );
        _subject.setSize( new Dimension( 111, 55 ) );
        _subject.setMaximumSize( new Dimension( 111, 55 ) );

        JPanel area = new JPanel( new GridLayout( 1, 2, 6, 0 ) );
        area.setOpaque( false );
        area.add( _subject );

        add( area, BorderLayout.CENTER );
      }
  }
}

Solution

  • Personally, I prefer not to limit my JTextArea's size lest I prevent the user from adding as much information as needed. Again, I feel you're better off wrapping the JTextArea in a JScrollPane and limiting the JScrollPane vewport's size. This can be done explicitly or implicitly by telling the JTextArea how many rows and columns to start out with. For example:

    import java.awt.BorderLayout;
    import java.awt.GridLayout;
    
    import javax.swing.*;
    
    public class TestPanel extends JPanel {
    
       private static final int AREA_COUNT = 4;
    
       public TestPanel() {
          setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
          setLayout(new GridLayout(0, 1, 0, 5));
          for (int i = 0; i < AREA_COUNT; i++) {
             JTextArea area = new JTextArea(5, 30);
             area.setLineWrap(true);
             area.setWrapStyleWord(true);
             JPanel wrapPanel = new JPanel(new BorderLayout());
             wrapPanel.add(new JLabel("JTextArea " + i), BorderLayout.PAGE_START);
             wrapPanel.add(new JScrollPane(area), BorderLayout.CENTER);
             add(wrapPanel);
          }
       }
    
       private static void createAndShowUI() {
          JFrame frame = new JFrame("TestPanel");
          frame.getContentPane().add(new TestPanel());
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                createAndShowUI();
             }
          });
       }
    }