我应该调用哪些不同的更新方法来使组件在添加到 JPanel 后出现?
Which of those different update methods should I call to make components appear after being added to a JPanel?
在这个简单的代码中,如果我点击按钮几次,几个 JCheckBoxes 将被添加到 JPanel。但是,除非在 add("TEST")
之后立即调用 revalidate()
(只是 invalidate()
不起作用)或 updateFrame()
,否则显示不会更新。此外,如果我使用 revalidate()
,则会出现 JCheckBoxes 但不会调整 JPanel 的大小。我也知道 repaint()
方法,但我不确定如何使用它或其他方法。
那些组件更新方法之间的关系是什么,以便我可以达到我想要的最小值(出现 JCheckBoxes 和调整 JPanel 的大小)?
如何简化代码?
public class UserInterface2 {
private final JFrame frame;
private JButton button;
private JPanel panel;
public UserInterface2() {
frame = new JFrame("Test App");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
createButton();
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
frame.getContentPane().add(button, BorderLayout.WEST);
frame.getContentPane().add(panel, BorderLayout.CENTER);
}
private void updateFrame() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createButton() {
button = new JButton("Text");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
add("TEST");
panel.revalidate();
//updateFrame();
}
});
}
public void show() {
updateFrame();
}
private void add(String text) {
panel.add(new JCheckBox(text));
}
public static void main(String [] args) {
SwingUtilities.invokeLater(() -> new UserInterface2().show());
}
}
JPanel 将调整大小,但您看不到它,因为它受到容纳它的 JFrame 的约束,如果没有明确指示它就无法调整大小。
建议:
- 将 JPanel 放在 JScrollPane 中,这将允许 JPanel 在添加组件时调整大小(并调用
revalidate()
)或
- 在封闭的 top-level window 上调用
pack()
,这里是一个 JFrame,在将组件添加到 JPanel 之后,这将 re-size 整个 GUI。
也考虑
- 为 JPanel 提供 GridLayout(0, 1)...
- ...将其嵌入另一个 BorderLayout-using JPanel 的 BorderLayout.PAGE_START 位置...
- ...然后将该 JPanel 添加到滚动窗格或 JFrame 的 contentPane 的 BorderLayout.CENTER 位置。这会将添加的组件压缩到 JPanel 的顶部。
例如:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class UserInterface3 {
private JPanel mainPanel = new JPanel(new BorderLayout());
private JPanel panel = new JPanel(new GridLayout(0, 1));
public UserInterface3() {
JPanel wrapperPanel = new JPanel(new BorderLayout());
wrapperPanel.add(panel, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(wrapperPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getViewport().setPreferredSize(new Dimension(300, 300));
JButton addCheckBoxBtn = new JButton("Add CheckBox");
addCheckBoxBtn.addActionListener(e -> addCheckBox());
addCheckBoxBtn.setMnemonic(KeyEvent.VK_A);
JPanel btnPanel = new JPanel();
btnPanel.add(addCheckBoxBtn);
mainPanel.add(scrollPane);
mainPanel.add(btnPanel, BorderLayout.PAGE_END);
}
private void addCheckBox() {
panel.add(new JCheckBox("Test"));
mainPanel.revalidate();
}
public JPanel getMainPanel() {
return mainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
UserInterface3 ui3 = new UserInterface3();
frame.add(ui3.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}
在这个简单的代码中,如果我点击按钮几次,几个 JCheckBoxes 将被添加到 JPanel。但是,除非在 add("TEST")
之后立即调用 revalidate()
(只是 invalidate()
不起作用)或 updateFrame()
,否则显示不会更新。此外,如果我使用 revalidate()
,则会出现 JCheckBoxes 但不会调整 JPanel 的大小。我也知道 repaint()
方法,但我不确定如何使用它或其他方法。
那些组件更新方法之间的关系是什么,以便我可以达到我想要的最小值(出现 JCheckBoxes 和调整 JPanel 的大小)?
如何简化代码?
public class UserInterface2 {
private final JFrame frame;
private JButton button;
private JPanel panel;
public UserInterface2() {
frame = new JFrame("Test App");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BorderLayout());
createButton();
panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
frame.getContentPane().add(button, BorderLayout.WEST);
frame.getContentPane().add(panel, BorderLayout.CENTER);
}
private void updateFrame() {
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private void createButton() {
button = new JButton("Text");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
add("TEST");
panel.revalidate();
//updateFrame();
}
});
}
public void show() {
updateFrame();
}
private void add(String text) {
panel.add(new JCheckBox(text));
}
public static void main(String [] args) {
SwingUtilities.invokeLater(() -> new UserInterface2().show());
}
}
JPanel 将调整大小,但您看不到它,因为它受到容纳它的 JFrame 的约束,如果没有明确指示它就无法调整大小。
建议:
- 将 JPanel 放在 JScrollPane 中,这将允许 JPanel 在添加组件时调整大小(并调用
revalidate()
)或 - 在封闭的 top-level window 上调用
pack()
,这里是一个 JFrame,在将组件添加到 JPanel 之后,这将 re-size 整个 GUI。
也考虑
- 为 JPanel 提供 GridLayout(0, 1)...
- ...将其嵌入另一个 BorderLayout-using JPanel 的 BorderLayout.PAGE_START 位置...
- ...然后将该 JPanel 添加到滚动窗格或 JFrame 的 contentPane 的 BorderLayout.CENTER 位置。这会将添加的组件压缩到 JPanel 的顶部。
例如:
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class UserInterface3 {
private JPanel mainPanel = new JPanel(new BorderLayout());
private JPanel panel = new JPanel(new GridLayout(0, 1));
public UserInterface3() {
JPanel wrapperPanel = new JPanel(new BorderLayout());
wrapperPanel.add(panel, BorderLayout.PAGE_START);
JScrollPane scrollPane = new JScrollPane(wrapperPanel);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
scrollPane.getViewport().setPreferredSize(new Dimension(300, 300));
JButton addCheckBoxBtn = new JButton("Add CheckBox");
addCheckBoxBtn.addActionListener(e -> addCheckBox());
addCheckBoxBtn.setMnemonic(KeyEvent.VK_A);
JPanel btnPanel = new JPanel();
btnPanel.add(addCheckBoxBtn);
mainPanel.add(scrollPane);
mainPanel.add(btnPanel, BorderLayout.PAGE_END);
}
private void addCheckBox() {
panel.add(new JCheckBox("Test"));
mainPanel.revalidate();
}
public JPanel getMainPanel() {
return mainPanel;
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
JFrame frame = new JFrame("GUI");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
UserInterface3 ui3 = new UserInterface3();
frame.add(ui3.getMainPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
});
}
}