Swing - GridLayout 组件未填满所有可用 space
Swing - GridLayout components not filling up all available space
我搜索了 Whosebug,但所有问题似乎都问了与我的问题完全相反的问题。
我正在编写动态添加 JLabels
到 JPanel
和 GridLayout
的代码,所有代码都包含在 JScrollPane
中。这是一个 SSCCE:
private JFrame frame;
private JPanel panel;
static Test window;
private JScrollPane scrollPane;
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
window = new Test();
window.frame.setVisible(true);
} catch (final Exception e) {
e.printStackTrace();
}
}
});
for (int i = 0; i < 100; i++) {
try {
EventQueue.invokeAndWait (new Runnable() {
@Override
public void run() {
final JLabel label = new JLabel("Test");
label.setSize(160, 40);
label.setHorizontalAlignment(SwingConstants.CENTER);
// Finalise GUI
window.panel.add(label);
window.panel.revalidate();
window.panel.repaint();
try {
Thread.sleep(100);
} catch (final Exception e) {
e.printStackTrace();
}
}
});
} catch (final Exception e) {
e.printStackTrace();
}
}
}
public Test() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 500, 200);
frame.getContentPane().setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(new GridLayout(0, 3));
final JPanel outerPanel = new JPanel();
outerPanel.setLayout(new FlowLayout());
outerPanel.add(panel);
scrollPane = new JScrollPane(outerPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBounds(12, 0, 460, 160);
frame.getContentPane().add(scrollPane);
}
据我了解,在GridLayouts
、"each component takes all the available space within its cell."中,然而在这里,JLabels
实际上并没有占用[=13=中所有可用的space ].
我不确定我的错误在哪里。是在GridLayout
还是在周围Components
没有给GridLayout
足够space?
谢谢大家
您的 JLabel 占用了所有可用的 space。是你的 JPanel 很小。用边框自己测试一下:
panel = new JPanel();
panel.setLayout(new GridLayout(0, 3));
// **** add this to see ****
panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
如果您希望标签填满顶部,请对外部面板使用不同的布局。注意用 // !!
注释标记的更改:
final JPanel outerPanel = new JPanel();
// !! outerPanel.setLayout(new FlowLayout());
outerPanel.setLayout(new BorderLayout()); // !!
// !! outerPanel.add(panel);
outerPanel.add(panel, BorderLayout.PAGE_START); // !!
此外,Thread.sleep(...)
是 Swing GUI 中的危险代码。如果您想延迟添加组件,请使用最适合该工作的 Swing 工具:a Swing Timer。例如
final int timerDelay = 100;
final int maxLabelCount = 100;
new Timer(timerDelay, new ActionListener() {
private int labelCount = 0;
@Override
public void actionPerformed(ActionEvent evt) {
if (labelCount < maxLabelCount) {
final JLabel label = new JLabel("Test");
// !! label.setSize(160, 40); // NO!
label.setHorizontalAlignment(SwingConstants.CENTER);
// Finalise GUI
window.panel.add(label);
window.panel.revalidate();
window.panel.repaint();
} else {
// stop this timer
((Timer) evt.getSource()).stop();
}
labelCount++;
}
}).start();
我搜索了 Whosebug,但所有问题似乎都问了与我的问题完全相反的问题。
我正在编写动态添加 JLabels
到 JPanel
和 GridLayout
的代码,所有代码都包含在 JScrollPane
中。这是一个 SSCCE:
private JFrame frame;
private JPanel panel;
static Test window;
private JScrollPane scrollPane;
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
window = new Test();
window.frame.setVisible(true);
} catch (final Exception e) {
e.printStackTrace();
}
}
});
for (int i = 0; i < 100; i++) {
try {
EventQueue.invokeAndWait (new Runnable() {
@Override
public void run() {
final JLabel label = new JLabel("Test");
label.setSize(160, 40);
label.setHorizontalAlignment(SwingConstants.CENTER);
// Finalise GUI
window.panel.add(label);
window.panel.revalidate();
window.panel.repaint();
try {
Thread.sleep(100);
} catch (final Exception e) {
e.printStackTrace();
}
}
});
} catch (final Exception e) {
e.printStackTrace();
}
}
}
public Test() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 500, 200);
frame.getContentPane().setLayout(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(new GridLayout(0, 3));
final JPanel outerPanel = new JPanel();
outerPanel.setLayout(new FlowLayout());
outerPanel.add(panel);
scrollPane = new JScrollPane(outerPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setBounds(12, 0, 460, 160);
frame.getContentPane().add(scrollPane);
}
据我了解,在GridLayouts
、"each component takes all the available space within its cell."中,然而在这里,JLabels
实际上并没有占用[=13=中所有可用的space ].
我不确定我的错误在哪里。是在GridLayout
还是在周围Components
没有给GridLayout
足够space?
谢谢大家
您的 JLabel 占用了所有可用的 space。是你的 JPanel 很小。用边框自己测试一下:
panel = new JPanel();
panel.setLayout(new GridLayout(0, 3));
// **** add this to see ****
panel.setBorder(BorderFactory.createLineBorder(Color.BLUE));
如果您希望标签填满顶部,请对外部面板使用不同的布局。注意用 // !!
注释标记的更改:
final JPanel outerPanel = new JPanel();
// !! outerPanel.setLayout(new FlowLayout());
outerPanel.setLayout(new BorderLayout()); // !!
// !! outerPanel.add(panel);
outerPanel.add(panel, BorderLayout.PAGE_START); // !!
此外,Thread.sleep(...)
是 Swing GUI 中的危险代码。如果您想延迟添加组件,请使用最适合该工作的 Swing 工具:a Swing Timer。例如
final int timerDelay = 100;
final int maxLabelCount = 100;
new Timer(timerDelay, new ActionListener() {
private int labelCount = 0;
@Override
public void actionPerformed(ActionEvent evt) {
if (labelCount < maxLabelCount) {
final JLabel label = new JLabel("Test");
// !! label.setSize(160, 40); // NO!
label.setHorizontalAlignment(SwingConstants.CENTER);
// Finalise GUI
window.panel.add(label);
window.panel.revalidate();
window.panel.repaint();
} else {
// stop this timer
((Timer) evt.getSource()).stop();
}
labelCount++;
}
}).start();