从外部 class 更新 JPanel 只会添加另一个,但不会替换它
Updating JPanel from external class will just add another one but dont replace it
我的主要 Java 程序 (MyFrame) 应该根据单击的 JMenuItem 和新的 JPanel 将被传递。当我单击 JMenuItem 时,JPanel 不更新,它在第一个后面并且不在前景中,直到我调整 window 的大小。请问你能帮我解决这个问题吗?
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
个调用时,它似乎起作用了。
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();
}
}
- 我还将您的主要方法包装在
EventQueue.invokeLater
调用中,以确保所有 Swing 操作都发生在 EDT
- 我删除了与对话框相关的所有代码,因为这不需要演示问题。内联了一些其他方法以进一步减少代码片段的长度
还有黄金提示如果你需要调试这样的情况:按ctrlshiftF1 当您的 JFrame
处于焦点时。这将打印出该组件的 Swing 层次结构。使用您的原始代码执行此操作清楚地表明内容窗格包含多个 MyPanel
个实例。
我的主要 Java 程序 (MyFrame) 应该根据单击的 JMenuItem 和新的 JPanel 将被传递。当我单击 JMenuItem 时,JPanel 不更新,它在第一个后面并且不在前景中,直到我调整 window 的大小。请问你能帮我解决这个问题吗?
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
个调用时,它似乎起作用了。
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();
}
}
- 我还将您的主要方法包装在
EventQueue.invokeLater
调用中,以确保所有 Swing 操作都发生在 EDT - 我删除了与对话框相关的所有代码,因为这不需要演示问题。内联了一些其他方法以进一步减少代码片段的长度
还有黄金提示如果你需要调试这样的情况:按ctrlshiftF1 当您的 JFrame
处于焦点时。这将打印出该组件的 Swing 层次结构。使用您的原始代码执行此操作清楚地表明内容窗格包含多个 MyPanel
个实例。