I'm observing some strange behavior using GroupLayout. I've got a JTextArea that is contained inside of a JScrollPane that is resizing and pushing other components out of the JFrame. Oddly, if I rearrange the layout so that the JTextArea has nothing above or below it (no gaps, either), it works fine. It is as if the text area is asking the container how much space is in the container, and then taking 100% of it, regardless of other components. The other strange thing is that it appears to happen only when the JTextArea (not JScrollPane) size plus the other component heights within the container reach Short.MAX_VALUE.
If I specify the max size in the vertical group for the scroll pane (when adding the component to the layout) to a value less than Short.MAX_VALUE, it seems to fix the problem (as long as the difference between the value and Short.MAX_VALUE is greater than the heights of all the other components). e.g.
.addComponent(textArea, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE - 500)
Also, if I set the preferred size to a small positive value and instead of GroupLayout.PREFERRED_SIZE or GroupLayout.DEFAULT_SIZE, it also seems to make this behavior go away. e.g.
.addComponent(textArea, 0, 1, Short.MAX_VALUE)
The Java Tutorials on GroupLayout don't seem to mention anything about this and tend to use Short.MAX_VALUE all over the place. I tried Googling to find an answer, but I found this problem very difficult to describe in search terms.
Have I found a bug, or do I just not understand GroupLayout? The latter certainly seems more likely.
This example will create a simple text area. Push the lower button to populate it with text (and resize the JTextArea inside the JScrollPane). You can then click inside the text area and add or remove lines. After adding some extra lines, click the redraw button (or resize the frame) to see the odd behavior.
public class GroupLayoutTest {
public GroupLayoutTest() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
final JFrame frame = new JFrame("GroupLayout test");
Container panel = frame.getContentPane();
GroupLayout layout = new GroupLayout(panel);
panel.setLayout(layout);
JButton addBtn = new JButton("Add Lines");
JButton redrawBtn = new JButton("Redraw");
final JTextArea textArea = new JTextArea();
final JScrollPane textPane = new JScrollPane(textArea);
layout.setHorizontalGroup(layout.createParallelGroup()
.addComponent(redrawBtn)
.addComponent(textPane)
.addComponent(addBtn));
layout.setVerticalGroup(layout.createSequentialGroup()
.addComponent(redrawBtn)
.addComponent(textPane)
.addComponent(addBtn));
addBtn.addActionListener(new ActionListener() {
int m = 0;
@Override
public void actionPerformed(ActionEvent e) {
for (int i = m; m < i + 2044; ++m) {
textArea.append("Line " + m + "\n");
}
// redraw the frame
frame.validate();
}
});
redrawBtn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
frame.validate();
}
});
frame.setPreferredSize(new Dimension(640, 480));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static void main(String[] args) {
new GroupLayoutTest();
}
}