单击按钮时 Java GUI 在面板之间切换

问题描述 投票:0回答:2

我正在学习 Java,我必须使用 GUI 开发一个应用程序。我已经让应用程序在命令行中运行了,但是 GUI 快把我逼疯了,让我花费了数小时的时间进行头部撞击和研究,但毫无进展。您能否帮助我打好基础工作,以便我可以进一步发展。我想要一个单框架应用程序,可以通过单击按钮在框架之间切换。我创建了一个框架并添加了三个面板 P1-P3。这些被设置为卡片布局(来自我从论坛上读到的内容)。然后我向这些面板添加了额外的面板,并为其设置了颜色和按钮。

'''

public class MyMainForm extends JFrame{
    private JPanel P1;
    private JPanel P2;
    private JPanel P3;
    private JButton btnFrame1;
    private JButton btnFrame2;
    private JButton button1;
    private JTextField thisIsPanel3TextField;
    private JButton btn2Frame1;
    private final JFrame frame = new JFrame("MyMain Frame");

    public MyMainForm() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setContentPane(P1);
        pack();
        setSize(1000,800);
        //setLocation(null);
        btnFrame1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                P1.setVisible(false);
                setContentPane(new MyMainForm().P2); 
            }
        });

        btnFrame2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                P2.setVisible(false);
                setContentPane(new MyMainForm().P3); 
            }
        });

        button1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                P3.setVisible(false);
                setContentPane(new MyMainForm().P2); 

            }
        });
        btn2Frame1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                P1.setVisible(false);
                setContentPane(new MyMainForm().P3); 
            }
        });
    }


    public static void main(String[] args) {
        MyMainForm MyMainForm = new MyMainForm();
        MyMainForm.setVisible(true);

    }

}

''' 我可以使用上面的新代码示例显示 P2 或 P3。当我尝试从 P2 或 P3 返回 P1 时,内容窗格不显示?我是否需要重新验证内容窗格才能正常工作?我真的需要能够从 P1 转到 P2

java swing user-interface
2个回答
1
投票

最简单的方法是使用

CardLayout
。只需按照这个例子:

JFrame frame = new JFrame();
            
JPanel p1 = new JPanel();
p1.setBackground(Color.RED);
JPanel p2 = new JPanel();
p2.setBackground(Color.WHITE);
JPanel p3 = new JPanel();
p3.setBackground(Color.BLUE);
        
//Create the panel that contains the "cards".
JPanel cards = new JPanel(new CardLayout());
cards.add(p1, "Panel 1");
cards.add(p2, "Panel 2");
cards.add(p3, "Panel 3");

// Add your card container to the frame
Container pane = frame.getContentPane();
pane.add(cards, BorderLayout.CENTER);
JButton btn = new JButton("Click me!");
btn.addActionListener(new ActionListener() {

    @Override
    public void actionPerformed (ActionEvent e) {
        CardLayout cl = (CardLayout)(cards.getLayout());
        cl.next(cards);
    }       
});
JPanel btnPanel = new JPanel();
btnPanel.add(btn);
pane.add(btnPanel, BorderLayout.SOUTH);
            
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);

或者,您可以通过调用

cl.show(cards, "Panel X")
切换到特定面板,其中 X 是面板编号。这是因为 swing 参数是我分配给每个“卡片”的名称,并且
show
方法会调用按名称添加到
CardLayout
的面板。对于您的示例,每个按钮都应该有一个侦听器,该侦听器使用此方法来“显示”其分配的面板。


0
投票

CardLayout
是一个不错的选择,但是在 swing 应用程序中的面板之间切换的更通用/可维护的解决方案是使用 State 设计模式。这将允许您将一个 JFrame 作为“上下文”,并且可以通过在各种“状态”实现之间切换来配置不同的面板。结果是使用各种状态对整个应用程序进行更通用的控制,此外,您最终将获得更清晰的代码和关注点分离。

这是一个使用可以具有不同状态的仪表板的简单示例:

首先,我们将创建一个 Dashboard 类,它作为我们的主应用程序,其中包含单击按钮时要更改的框架/面板。

Dashboard.java

public class Dashboard {

    private JFrame mainFrame;
    private JPanel mainPanel;
    private JButton changeStateButton("Click me");

    // Initialize the DashboardState as NullState to avoid NPE
    private DashboardState state = new NullDashboardState();

    public Dashboard() {
        // Configure all your buttons to change state to the desired state
        changeStateButton.addActionListener(event -> {
            changeState(new ExampleDashboardState(this)));
        });
    }

    private void changeState(DashboardState state) {
        this.state.clear();
        this.state = state;
        this.state.render();
    }

    // Use these accessors to make modifications from the state class
    public JFrame getMainFrame() {
        return mainFrame;
    }

    public JPanel getMainPanel() {
        return mainPanel;
    }

}

接下来,定义一个简单的 State 接口。

DashboardState.java

public interface DashboardState {
    
    // Render the dashboard state
    void render();
    
    // Clear the dashboard state to make room for the next state
    void clear();

}

接下来,定义

DashboardState
接口的实现。
ExampleDashboardState.java

public class ExampleDashboardState implements DashboardState {
    
    private Dashboard dashboard;
    private JPanel dashboardPanel;

    public DashboardState(Dashboard dashboard) {
        this.dashboard = dashboard;
    }

    public void render() {
        dashboardPanel = dashboard.getMainPanel();
        // Do stuff with dashboardPanel
        dashboardPanel.revalidate();
        dashboardPanel.repaint();
    }

    public void clear() {
        dashboardPanel.removeAll()
        // Any other cleanup code runs here
    }
}

最后,创建

DashboardState
接口的 Null 实现。
NullDashboardState.java

public class NullDashboardState implements DashboardState {
   
    public void render() {
        // Do nothing
    }

    public void clear() {
        // Do nothing
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.