11

If I use a JTextArea with MigLayout like this:

MigLayout thisLayout = new MigLayout("", "[][grow]", "[]20[]");
   this.setLayout(thisLayout);
   {
jLabel1 = new JLabel();
this.add(jLabel1, "cell 0 0");
jLabel1.setText("jLabel1");
  }
  {
 jTextArea1 = new JTextArea();
this.add(jTextArea1, "cell 0 1 2 1,growx");
jTextArea1.setText("jTextArea1");
jTextArea1.setLineWrap(false);
   } 

then the JTextArea grows and shrinks perfectly when resizing the window. When I set the linewrap to true the JTextArea is not shrinking when I make the window smaller again.

Yu Hao
  • 119,891
  • 44
  • 235
  • 294
Marcel Menz
  • 1,075
  • 7
  • 17
  • 25

2 Answers2

23

I just discovered that this can simply be resolved by changing the line

this.add(jTextArea1, "cell 0 1 2 1,growx");

to

this.add(jTextArea1, "cell 0 1 2 1,growx, wmin 10");

and no extra panels are needed. Setting an explicit minimum size is what does the trick.

Explanation: see the note under the section on padding in the MiGLayout whitepaper:

http://www.migcalendar.com/miglayout/whitepaper.html

Datoraki
  • 1,223
  • 13
  • 26
  • +1 This seems to solve problems with other stubborn components, too. In my case my chromium browser frame wouldn't shrink until adding a minimum size. – Daniel Rikowski Nov 30 '11 at 10:02
  • 1
    Confirmed, this works, and much easier to use than the accepted answer. You can specify `"wmin 0"` which in my opinion makes it clear that is added to work around an issue. +1 for your minimal fix. – Timmos Apr 10 '14 at 12:32
  • Works perfectly. In my case, I had to make sure the component had both a minimum size _and_ a preferred size. – FWDekker Jan 10 '20 at 13:07
8

This is because JTextArea's automatically have their minimum width set anytime they resize. Details are available on the MigLayout forum. To roughly summarize, create a panel that contains the JTextArea and gives you further control over the resize behavior. Here's an excerpt from the above forum post:

static class MyPanel extends JPanel implements Scrollable
{
  MyPanel(LayoutManager layout)
  {
     super(layout);
  }

  public Dimension getPreferredScrollableViewportSize()
  {
     return getPreferredSize();
  }

  public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction)
  {
     return 0;
  }

  public boolean getScrollableTracksViewportHeight()
  {
     return false;
  }

  public boolean getScrollableTracksViewportWidth()
  {
     return true;
  }

  public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction)
  {
     return 0;
  }
}

Then, wherever you would use the JTextArea, use the panel containing the text area:

MigLayout thisLayout = new MigLayout("", "[][grow]", "[]20[]");
this.setLayout(thisLayout);
{
    jLabel1 = new JLabel();
    this.add(jLabel1, "cell 0 0");
    jLabel1.setText("jLabel1");
}
{
    JPanel textAreaPanel = new MyPanel(new MigLayout("wrap", "[grow,fill]", "[]"));
    jTextArea1 = new JTextArea();
    textAreaPanel.add(jTextArea1);
    this.add(textAreaPanel, "cell 0 1 2 1,grow,wmin 10");
    jTextArea1.setText("jTextArea1");
    jTextArea1.setLineWrap(false);
} 
Kaleb Pederson
  • 45,767
  • 19
  • 102
  • 147