JPanel 不会更新
JPanel won't update
我在更新 JPanel 时遇到了问题。
我的简单程序使用显示标签和文本字段的自定义 JPanel。主面板上的 Jbutton 用于用新的 JPanel 替换 JPanel。初始面板显示正常,但是当按下按钮时,面板不会更新为新的 MyPanel。我可以看出随着计数的增加正在创建一个新对象。
public class SwingTest extends JFrame{
private JPanel mp;
private JPanel vp;
private JButton button;
public static void main(String[] args) {
SwingTest st = new SwingTest();
}
public SwingTest() {
vp = new MyPanel();
mp = new JPanel(new BorderLayout());
mp.add(vp, BorderLayout.CENTER);
button = new JButton("Change");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
mp.add(button, BorderLayout.SOUTH);
this.add(mp);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setSize(250, 150);
pack();
setVisible(true);
}
}
和我的自定义面板....
public class MyPanel extends JPanel{
private JLabel label;
private JTextField tf;
static int count = 0;
public MyPanel(){
count++;
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
setPreferredSize(new Dimension(400, 200));
c.gridx = 0;
c.gridy = 0;
label = new JLabel(String.valueOf(count));
tf = new JTextField(10);
add(label,c);
c.gridx = 1;
add(tf, c);
}
}
您说:
A Jbutton on the main panel is used to replace the JPanel with a new JPanel.
还有这段代码:
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
然而这段代码根本没有这样做。它所做的只是通过 vp 变量更改 JPanel referenced,但对 GUI 显示的 JPanel 绝对没有影响,这表明您正在混淆 引用变量与引用或对象。要更改显示的 JPanel,您必须完全按照以下步骤操作:将新的 JPanel 添加到容器 JPanel 到 BorderLayout.CENTER(默认)位置,然后在容器上调用 revalidate()
和 repaint()
.
例如,
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
// vp = new MyPanel();
// vp.revalidate();
mp.remove(vp); // remove the original MyPanel from the GUI
vp = new MyPanel(); // create a new one
mp.add(vp, BorderLayout.CENTER); // add it to the container
// ask the container to layout and display the new component
mp.revalidate();
mp.repaint();
}
});
或者更好——使用 CardLayout 交换视图。
或者更好 - 只需清除 JTextField 持有的值。
更多关于引用变量和对象之间的区别,请查看 Jon Skeet 对这个问题的回答:What is the difference between a variable, object, and reference?
我在更新 JPanel 时遇到了问题。
我的简单程序使用显示标签和文本字段的自定义 JPanel。主面板上的 Jbutton 用于用新的 JPanel 替换 JPanel。初始面板显示正常,但是当按下按钮时,面板不会更新为新的 MyPanel。我可以看出随着计数的增加正在创建一个新对象。
public class SwingTest extends JFrame{
private JPanel mp;
private JPanel vp;
private JButton button;
public static void main(String[] args) {
SwingTest st = new SwingTest();
}
public SwingTest() {
vp = new MyPanel();
mp = new JPanel(new BorderLayout());
mp.add(vp, BorderLayout.CENTER);
button = new JButton("Change");
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
mp.add(button, BorderLayout.SOUTH);
this.add(mp);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
setLocationRelativeTo(null);
setSize(250, 150);
pack();
setVisible(true);
}
}
和我的自定义面板....
public class MyPanel extends JPanel{
private JLabel label;
private JTextField tf;
static int count = 0;
public MyPanel(){
count++;
setLayout(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
setPreferredSize(new Dimension(400, 200));
c.gridx = 0;
c.gridy = 0;
label = new JLabel(String.valueOf(count));
tf = new JTextField(10);
add(label,c);
c.gridx = 1;
add(tf, c);
}
}
您说:
A Jbutton on the main panel is used to replace the JPanel with a new JPanel.
还有这段代码:
button.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent ae) {
vp = new MyPanel();
vp.revalidate();
}
});
然而这段代码根本没有这样做。它所做的只是通过 vp 变量更改 JPanel referenced,但对 GUI 显示的 JPanel 绝对没有影响,这表明您正在混淆 引用变量与引用或对象。要更改显示的 JPanel,您必须完全按照以下步骤操作:将新的 JPanel 添加到容器 JPanel 到 BorderLayout.CENTER(默认)位置,然后在容器上调用 revalidate()
和 repaint()
.
例如,
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
// vp = new MyPanel();
// vp.revalidate();
mp.remove(vp); // remove the original MyPanel from the GUI
vp = new MyPanel(); // create a new one
mp.add(vp, BorderLayout.CENTER); // add it to the container
// ask the container to layout and display the new component
mp.revalidate();
mp.repaint();
}
});
或者更好——使用 CardLayout 交换视图。
或者更好 - 只需清除 JTextField 持有的值。
更多关于引用变量和对象之间的区别,请查看 Jon Skeet 对这个问题的回答:What is the difference between a variable, object, and reference?