从外部类更新 JPanel 只会添加另一个但不会替换它 [英] Updating JPanel from external class will just add another one but dont replace it
问题描述
我的主 Java 程序 (MyFrame) 应根据单击的 JMenuItem 和传递新 JPanel 的参数,使用由其他类 (MyPanel) 启动的其他 JPanel 更新其 JFrame 中的现有 ContentPanel.当我单击 JMenuItem 时,JPanel 不会更新,它在第一个之后而不是在前台,直到我调整窗口大小.请问你能帮我解决这个问题吗?
My main Java program (MyFrame) should update an existing ContentPanel in its JFrame with an other JPanel initiated by an other class (MyPanel) depending on what JMenuItem is clicked and a parameter for the new JPanel will be passed. When I click the JMenuItem, the JPanel dont update, it is behind the first one and not in foreground until I resize the window. Please can you help me solve this?
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
public class MyFrame extends JFrame {
private Container contentContainer;
public static void main(String[] args) {
new MyFrame();
}
public MyFrame() {
setTitle("MyFrame");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setJMenuBar(createMenu());
MyPanel panel = makePanel(new String("Test oO"));
contentContainer = this.getContentPane();
setVisible(true);
}
public JMenuBar createMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
JMenuItem menuItem = new JMenuItem("Test");
menuItem.setMnemonic(KeyEvent.VK_E);
menuItem.setToolTipText("Test");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
MyPanel dynamicPanel = makePanel(new String("Test"));
contentContainer.add(dynamicPanel);
contentContainer.revalidate();
contentContainer.repaint();
}
});
menu.add(menuItem);
JMenuItem menuItem1 = new JMenuItem("Test 1");
menuItem1.setMnemonic(KeyEvent.VK_E);
menuItem1.setToolTipText("Test 1");
menuItem1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
MyPanel dynamicPanel1 = makePanel(new String("Test 1"));
contentContainer.add(dynamicPanel1);
revalidate();
repaint();
}
});
menu.add(menuItem1);
JMenuItem menuItem2 = new JMenuItem("Dialog");
menuItem2.setMnemonic(KeyEvent.VK_E);
menuItem2.setToolTipText("Dialog");
menuItem2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
makeDialog(new String("Zur Info"), new String("Du hast Edit geklickt"));
}
});
menu.add(menuItem2);
menuBar.add(menu);
return menuBar;
}
public JDialog makeDialog(String title, String content) {
JDialog meinJDialog = new JDialog();
meinJDialog.setTitle(title);
JTextArea contentArea = new JTextArea(content);
contentArea.setEditable(false);
meinJDialog.add(contentArea);
meinJDialog.setSize(200,200);
meinJDialog.setModal(true);
meinJDialog.setLocationRelativeTo(null);
meinJDialog.setVisible(true);
return meinJDialog;
}
public MyPanel makePanel(String config) {
MyPanel panel = new MyPanel(config);
panel.revalidate();
panel.repaint();
return panel;
}
}
class MyPanel extends JPanel {
public MyPanel(String config) {
JButton testButton = new JButton(config);
add(testButton);
setVisible(true);
revalidate();
repaint();
return;
}
}
推荐答案
当我添加 removeAll
调用时,它似乎有效.
When I add removeAll
calls, it seems to work.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class MyFrame extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new MyFrame();
}
});
}
private final Container contentContainer;
public MyFrame() {
setTitle("MyFrame");
setSize(300, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setJMenuBar(createMenu());
contentContainer = getContentPane();
contentContainer.add(new MyPanel("Test oO"));
setVisible(true);
}
public JMenuBar createMenu() {
JMenuBar menuBar = new JMenuBar();
JMenu menu = new JMenu("Menu");
JMenuItem menuItem = new JMenuItem("Test");
menuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
MyPanel dynamicPanel = new MyPanel("Test");
contentContainer.removeAll();
contentContainer.add(dynamicPanel);
contentContainer.revalidate();
contentContainer.repaint();
}
});
menu.add(menuItem);
JMenuItem menuItem1 = new JMenuItem("Test 1");
menuItem1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
contentContainer.removeAll();
contentContainer.add(new MyPanel("Test 1"));
contentContainer.revalidate();
contentContainer.repaint();
}
});
menu.add(menuItem1);
menuBar.add(menu);
return menuBar;
}
}
class MyPanel extends JPanel {
public MyPanel(String config) {
JButton testButton = new JButton(config);
add(testButton);
setVisible(true);
revalidate();
repaint();
}
}
- 我还将您的 main 方法封装在
EventQueue.invokeLater
调用中,以确保所有 Swing 操作都发生在 EDT 上 - 我删除了与对话框相关的所有代码,因为这不需要演示问题.内联了一些其他方法以进一步减少代码片段的长度
- I also wrapped your main method in an
EventQueue.invokeLater
call to make sure all Swing operations happen on the EDT - I removed all the code related to the dialog, as this was unneeded to demonstrate the problem. Inlined some other methods to reduce the length of the code snippet further
还有黄金提示,如果你需要调试这样的情况:按下ctrlshiftF1JFrame
聚焦.这将打印出该组件的 Swing 层次结构.使用原始代码执行此操作清楚地表明内容窗格包含多个 MyPanel
实例.
And the golden tip if you need to debug situations like that: press ctrlshiftF1 when your JFrame
is focused. This will print out the Swing hierarchy of that component. Doing this with your original code clearly shows that the content pane contains multiple MyPanel
instances.
这篇关于从外部类更新 JPanel 只会添加另一个但不会替换它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!