我正在使用 GroupLayout 观察到一些奇怪的行为。我有一个包含在 JScrollPane 内的 JTextArea,它正在调整大小并将其他组件推出 JFrame。奇怪的是,如果我重新排列布局以使 JTextArea 在其上方或下方没有任何内容(也没有间隙),它可以正常工作。就好像文本区域是在询问容器,容器中有多少空间,然后就占去 100% 的空间,而不管其他组件。另一个奇怪的事情是,它似乎只发生在 JTextArea(不是 JScrollPane)大小加上容器内的其他组件高度达到 Short.MAX_VALUE 时。
如果我将滚动窗格的垂直组中的最大大小(将组件添加到布局中时)指定为小于 Short.MAX_VALUE 的值,它似乎可以解决问题(只要值和 Short.MAX_VALUE 之间的差异)。 MAX_VALUE 大于所有其他组件的高度)。例如
.addComponent(textArea, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE - 500)
此外,如果我将首选大小设置为一个小的正值,而不是 GroupLayout.PREFERRED_SIZE 或 GroupLayout.DEFAULT_SIZE,它似乎也会使这种行为消失。例如
.addComponent(textArea, 0, 1, Short.MAX_VALUE)
GroupLayout 上的 Java 教程似乎没有提到任何关于此的内容,并且倾向于在所有地方使用 Short.MAX_VALUE。我尝试用谷歌搜索找到答案,但我发现这个问题很难用搜索词来描述。
我是否发现了一个错误,或者我只是不了解 GroupLayout?后者当然似乎更有可能。
此示例将创建一个简单的文本区域。按下下方按钮以使用文本填充它(并调整 JScrollPane 内的 JTextArea 的大小)。然后,您可以在文本区域内单击并添加或删除行。添加一些额外的行后,单击重绘按钮(或调整框架大小)以查看奇怪的行为。
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();
}
}