如何通过另一个面板更改CardLayout面板

时间:2015-02-26 02:08:12

标签: java swing cardlayout

在我的程序中,我有一个基于向导的布局。由CardLayout实施。所以有一组扩展JPanel的类。我希望每个面板中都有按钮导航到其他面板。例如,当程序显示第一个面板时,我想要一个按钮来显示面板2.

我厌倦了在主cardlayout面板支架中创建一个方法,所以任何其他类都可以通过这种方法更改显示面板,但是它不起作用并且出现了stackoverflow错误。

这是我的课程

基本框架:

public class Base {
        JFrame frame = new JFrame("Panel");
        BorderLayout bl = new BorderLayout();

    public Base(){
        frame.setLayout(bl);
        frame.setSize(800, 600);
        frame.add(new LeftBar(), BorderLayout.WEST);
        frame.add(new MainPanel(), BorderLayout.CENTER);

        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        new Base();
    }
}

保存子面板的主类:

public class MainPanel extends JPanel {
    private CardLayout cl = new CardLayout();
    private JPanel panelHolder = new JPanel(cl);

    public MainPanel() {
        NewSession session = new NewSession();
        ChooseSource chooseSource = new ChooseSource();

        panelHolder.add(session, "Session");
        panelHolder.add(chooseSource, "ChooseSource");

        cl.show(panelHolder, "Session");
        add(panelHolder);
    }

    public void showPanel(String panelIdentifier){
        cl.show(panelHolder, panelIdentifier);
    }
}

子面板1

public class NewSession extends JPanel {
    MainPanel ob2 = new MainPanel();

    public NewSession(){
        JButton newSessionBTN = new JButton("Create A New Session");

        newSessionBTN.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                System.out.println("HI");

                ob2.showPanel("ChooseSource");
            }
        });

        add(newSessionBTN);
    }
}

子面板2

public class ChooseSource extends JPanel {

    public ChooseSource(){
        JLabel showMe = new JLabel("Show Me");
        JButton back = new JButton("Back");
        //MainPanel ob = new MainPanel();

        back.addActionListener(new ActionListener(){
            @Override
            public void actionPerformed(ActionEvent e){
                //ob.showPanel("start");
            }
        });

        add(back);
        add(showMe);
    }
}

如您所见,我在每个子面板中都有按钮,这些按钮必须在单击后显示另一个面板。稍后他们也会将数据从一个传输到另一个。

ERROR:

Exception in thread "main" java.lang.StackOverflowError
    at java.awt.Component.setFont(Component.java:1899)
    at java.awt.Container.setFont(Container.java:1748)
    at javax.swing.JComponent.setFont(JComponent.java:2751)
    at javax.swing.LookAndFeel.installColorsAndFont(LookAndFeel.java:208)
    at javax.swing.plaf.basic.BasicPanelUI.installDefaults(BasicPanelUI.java:66)
    at javax.swing.plaf.basic.BasicPanelUI.installUI(BasicPanelUI.java:56)
    at javax.swing.JComponent.setUI(JComponent.java:663)
    at javax.swing.JPanel.setUI(JPanel.java:153)
    at javax.swing.JPanel.updateUI(JPanel.java:126)
    at javax.swing.JPanel.<init>(JPanel.java:86)
    at javax.swing.JPanel.<init>(JPanel.java:109)
    at javax.swing.JPanel.<init>(JPanel.java:117)
    at InnerPanels.NewSession.<init>(NewSession.java:21)
    at StrongBaseLayout.MainPanel.<init>(MainPanel.java:22)

错误比此更长,重复最后两行。

我怎样才能让它发挥作用?

此外,我还有另一个想法,在页面底部有一个下一个和上一个按钮来切换面板。但我不确定哪一个是最佳的。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

每当你看到一个意外的StackOverflowError总是寻找无意递归的存在,事实上,这正是你在这里所发生的事情,因为MainPanel创建了一个NewSession对象,然后创建一个新的MainPanel对象然后创建一个新的NewSession对象,然后创建一个新的MainPanel对象....无限重复ad或直到堆栈内存(因此堆栈溢出)耗尽。

这里:

public class NewSession extends JPanel {
    MainPanel ob2 = new MainPanel();  // *****

在这里:

public class MainPanel extends JPanel {
    private CardLayout cl = new CardLayout();
    private JPanel panelHolder = new JPanel(cl);

    public MainPanel() {
        NewSession session = new NewSession();  // *****

不要那样做。而是注意创建每个对象中的一个且仅一个。使用setter方法或构造函数参数来帮助您完成此任务。

例如,更改为:

public class NewSession extends JPanel {
    MainPanel ob2;

    NewSession(MainPanel mainPanel) {
       this.ob2 = mainPanel;

和此:

public class MainPanel extends JPanel {
    private CardLayout cl = new CardLayout();
    private JPanel panelHolder = new JPanel(cl);

    public MainPanel() {
        NewSession session = new NewSession(this);

关于:

  

此外,我还有另一个想法,在页面底部有一个下一个和上一个按钮来切换面板。但我不确定哪一个是最佳的。有什么想法吗?

我不确定你的意思。定义“最佳”。