我通常不需要问Java问题,但我现在比以往任何时候都更加困难,而且我认为我只是一遍又一遍地错过了一些东西..
我有一个JMrame应用程序,它有一个JMenuBar。菜单栏中的项目将我的类PageManager作为其ActionListener。调试显示这一切都很好。整个批次都是这样初始化的:
public static void main(String[] args) {
UI ui = new UI(); //The JFrame
PageManager pm = new PageManager(ui); //Menu ActionListener
MenuBar mb = new MenuBar(pm); //MenuBar
ui.setJMenuBar(mb);
ui.setDefaultCloseOperation(0);
ui.setVisible(true);
ui.setPage(new Home().getPanel()); //a View
}
在UI类中,我有以下方法:
public void setPage(JPanel p) {
System.out.println("Set page");
this.remove(page);
System.out.println("Removed");
this.add(p);
System.out.println("Added " + p);
}
ui.setPage(new Home().getPanel());
方法调用正常。如果我将它移动到PageManager的构造函数,它也可以工作。如果我用ui.setPage(new Preferences().getPanel());
替换它,它也可以。 Home和Preferences类是创建JPanel并使用getPanel方法返回它的视图。
但是,使用actionlistener更改页面似乎不起作用。所有System.out.println行打印正常,但页面不会更改。我在PageManager中使用它:
private void changePage(String s, int i) {
if(s.equals("P")) {
//Program options
System.out.println("program options");
if(i == 1) {
ui.setPage(pref.getPanel());
}
} else if(s.equals("C")) {
//Connection options
} else if(s.equals("A")) {
//Add rule
}
}
(ActionListener获取事件,检查源并使用它调用changePage)。
事情是,根据控制台输出,一切都运行并且似乎工作正常,但页面不会改变我做的任何事情(包括小修改)。
任何帮助都会受到极大的欢迎!!!
亲切的问候, 标记
答案 0 :(得分:4)
通常,为了实现这种行为,更容易的方法是使用CardLayout。
此外,一旦您将新面板添加到现有的JFrame,通过删除旧面板,尝试revalidate()
和repaint()
,以便可以实现新的添加。
如果您的JDK是1.6或更低,那么重新验证框架将无法工作,而是使用frameObject.getRootPane().revalidate();
revalidate() on JFrame is directly used with JDK 7+
以下是一个示例代码段,可帮助您解决问题,并添加了JMenuBar:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FrameTest extends JFrame
{
public FrameTest()
{
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationByPlatform(true);
final JPanel panel1 = new JPanel();
panel1.setBackground(Color.BLUE);
final JPanel panel2 = new JPanel();
panel2.setBackground(Color.DARK_GRAY);
JMenuBar menuBar = new JMenuBar();
JMenu menu1 = new JMenu("MENU 1");
JMenu menu2 = new JMenu("MENU 2");
JMenu menu3 = new JMenu("MENU 3");
JMenuItem menuItem1 = new JMenuItem("CHANGE PANELS");
JMenuItem menuItem2 = new JMenuItem("MENU ITEM 2");
JMenuItem menuItem3 = new JMenuItem("MENU ITEM 3");
menuItem1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (panel1.isShowing())
{
remove(panel1);
add(panel2, BorderLayout.CENTER);
}
else if (panel2.isShowing())
{
remove(panel2);
add(panel1, BorderLayout.CENTER);
}
// for getRootPane().revalidate();
revalidate(); // For JDK 7+
repaint();
}
});
menu1.add(menuItem1);
menu2.add(menuItem2);
menu3.add(menuItem3);
menuBar.add(menu1);
menuBar.add(menu2);
menuBar.add(menu3);
JButton button = new JButton("CHANGE");
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
if (panel1.isShowing())
{
remove(panel1);
add(panel2, BorderLayout.CENTER);
}
else if (panel2.isShowing())
{
remove(panel2);
add(panel1, BorderLayout.CENTER);
}
// for getRootPane().revalidate();
revalidate(); // For JDK 7+
repaint();
}
});
add(panel1, BorderLayout.CENTER);
add(button, BorderLayout.PAGE_END);
setJMenuBar(menuBar);
setSize(200, 200);
setVisible(true);
}
public static void main(String... args)
{
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
new FrameTest();
}
});
}
}
答案 1 :(得分:2)
更改可见组件的组件层次结构时,必须验证层次结构才能使更改可见。见JavaDoc of the remove() method:
此方法更改与布局相关的信息,因此使组件层次结构无效。如果已显示容器,则必须在此后验证层次结构以反映更改。