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

how to change a panel of CardLayout through another panel

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

我厌倦了在主卡片布局面板支架中创建一个方法,因此任何其他 class 都可以通过此方法更改显示面板,但它不起作用并且出现了 Whosebug 错误。

这是我的 classes

基础框架:

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();
    }
}

包含子面板的主 class:

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);
    }
}

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

错误:

Exception in thread "main" java.lang.WhosebugError
    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)

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

如何让它工作?

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

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

此处:

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);

关于:

Also I had another idea to have a next and previous buttons at the bottom of the page to switch panels. But am not sure which one is optimal. Any idea?

我不确定你在这里的意思。定义 "optimal".