如何在一个JPanel中的动作中交换另一个JPanel

3

我对Java Swing还比较新,但是我一直没有找到一个优雅的解决方案来解决我的问题,所以我想在这里提出一个问题。

我正在尝试根据当前JPanel中的按钮单击事件将其更改为另一个JPanel。本质上只是隐藏一个面板并显示另一个面板。我觉得这可以在我的MainFrame类中完成,但我不知道如何将其传回该类。无论我尝试什么,似乎都不能如预期地执行,我将非常感激任何支持。谢谢

App.java

public static void main(final String[] args) {
    MainFrame mf = new MainFrame();
}

MainFrame.java

public class MainFrame extends JFrame {

    public MainFrame(){
        setTitle("Swing Application");
        setSize(1200, 800);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setVisible(true);

        // First Page Frame switch
        getContentPane().add(new FirstPage());

    }
}

FirstPage.java

public class FirstPage extends JPanel {

    public FirstPage() {
        setVisible(true);
        JButton clickBtn = new JButton("Click");
        clickBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                // Change to SecondPage JPanel here.
            }
        });
        add(clickBtn);
    }
}

SecondPage.java

public class SecondPage extends JPanel {

    public SecondPage() {
        setVisible(true);
        add(new JLabel("Welcome to the Second Page"));

    }
}

如果需要更多信息,请问,谢谢 :)


你可以使用jPanel.setVisible(true);或jPanel.setVisible(false);来控制组件的可见性,请根据需要进行更改并使用jPanel.setVisible(true);或jPanel.setVisible(false);方法。我更喜欢在JPanel中定义按钮,您可以在MainFrame类中使用切换按钮,然后在MainFrame中初始化您的jpanel,然后控制其可见性。 - Noman ali abbasi
1
我认为你的问题已经被问过并回答了几次,例如如何在JFrame内实时更改JPanel?如何在同一位置用另一个JPanel替换一个JPanel? - Abra
2个回答

4
我认为最好的方法是使用CardLayout。 它是专门用于这种情况的。 可以查看我的示例:
public class MainFrame extends JFrame {
    private CardLayout cardLayout;

    public MainFrame() {
        super("frame");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        cardLayout = new CardLayout();
        getContentPane().setLayout(cardLayout);

        getContentPane().add(new FirstPage(this::showPage), Pages.FIRST_PAGE);
        getContentPane().add(new SecondPage(this::showPage), Pages.SECOND_PAGE);

        setLocationByPlatform(true);
        pack();
    }

    public void showPage(String pageName) {
        cardLayout.show(getContentPane(), pageName);
    }

    public static interface PageContainer {
        void showPage(String pageName);
    }

    public static interface Pages {
        String FIRST_PAGE = "first_page";
        String SECOND_PAGE = "second_page";
    }

    public static class FirstPage extends JPanel {
        public FirstPage(PageContainer pageContainer) {
            super(new FlowLayout());

            JButton button = new JButton("next Page");
            button.addActionListener(e -> pageContainer.showPage(Pages.SECOND_PAGE));
            add(button);
        }
    }

    public static class SecondPage extends JPanel {
        public SecondPage(PageContainer pageContainer) {
            super(new FlowLayout());

            add(new JLabel("This is second page."));

            JButton button = new JButton("Go to first page");
            button.addActionListener(e -> pageContainer.showPage(Pages.FIRST_PAGE));
            add(button);
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> new MainFrame().setVisible(true));
    }
}

我建议将“Pages”更改为枚举(最佳)或常规类,而不是接口。+1 - c0der
这也是一个很好的解决方案,可以工作,谢谢 :) - GarethR
2
@c0der 听起来更好。是的! - George Z.

3

CardLayout 是完成此任务的正确工具。 您可以在 JFrame 类中简单地创建用于交换页面的 ActionListener,并将其引用传递给 FirstPage

import java.awt.CardLayout;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;


public class MainFrame extends JFrame {

    public MainFrame(){
        setTitle("Swing Application");
        setSize(1200, 800);
        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        setLocationByPlatform(true);

        //Create card layout and set it to the content pane 
        CardLayout cLayout = new  CardLayout();
        setLayout(cLayout);

        //create and add second page to the content pane 
        JPanel secondPage = new SecondPage();
        add("SECOND",secondPage);

        //create an action listener to swap pages 
        ActionListener listener = actionEvent ->{
            cLayout.show(getContentPane(), "SECOND");
        };

        //use the action listener in FirstPage
        JPanel firstPage = new FirstPage(listener);
        add("FIRST", firstPage);
        cLayout.show(getContentPane(), "FIRST");
        setVisible(true);
    }

    public static void main(String[] args) {
        new MainFrame();
    }
}

class FirstPage extends JPanel {

    public FirstPage(ActionListener listener) {
        JButton clickBtn = new JButton("Click");
        clickBtn.addActionListener(listener);
        add(clickBtn);
    }
}

class SecondPage extends JPanel {
    public SecondPage() {
        add(new JLabel("Welcome to the Second Page"));
    }
}

这正是我正在寻找的完美解决方案!非常感谢 :) - GarethR
1
我很高兴它有所帮助。请注意,我尽可能缩小了解决方案的范围,以使其更简单。George Z.提供的解决方案略微更广泛和更一般化。 - c0der

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接