【问题标题】:CardLayout for JFrames?JFrames的卡片布局?
【发布时间】:2016-01-25 23:53:45
【问题描述】:

我一直在四处寻找,包括在 Java 文档中,但我的问题没有找到明确的答案:我想通过单击按钮从一个 JFrame 切换到另一个;也就是说,在新的 JFrame 打开时关闭旧的 JFrame。我听说过“CardLayout”,但我不太确定它是如何工作的。有人介意解释一下,或者其他方法吗?

谢谢

【问题讨论】:

  • 简短的回答是,不要(切换帧) - 有关更多讨论,请参阅 The Use of Multiple JFrames, Good/Bad Practice?CardLayout 通常是在 UI 中的多个视图之间切换的更合适的解决方案,但依赖于基本组件(如 JPanel)而不是框架。作为一般经验法则,您应该避免直接从 JFrame 扩展,而是更喜欢使用其他容器,例如 JPanel,可以将其添加到您需要的任何容器中,并使用您想要的任何布局

标签: java swing jframe jpanel cardlayout


【解决方案1】:

这是CardLayout的示例

正如你听到其他人所说,don't use multiple JFrames.

import javax.swing.*;
import java.awt.*;

public class MainFrame
{
static JPanel homeContainer;
static JPanel homePanel;
static JPanel otherPanel;
static CardLayout cl;

public MainFrame()
{
    JFrame mFrame = new JFrame("CardLayout Example");
    JButton showOtherPanelBtn = new JButton("Show Other Panel");
    JButton backToHomeBtn = new JButton("Show Home Panel");

    cl = new CardLayout(5, 5);
    homeContainer = new JPanel(cl);
    homeContainer.setBackground(Color.black);

    homePanel = new JPanel();
    homePanel.setBackground(Color.blue);
    homePanel.add(showOtherPanelBtn);

    homeContainer.add(homePanel, "Home");

    otherPanel = new JPanel();
    otherPanel.setBackground(Color.green);
    otherPanel.add(backToHomeBtn);

    homeContainer.add(otherPanel, "Other Panel");

    showOtherPanelBtn.addActionListener(e -> cl.show(homeContainer, "Other Panel"));
    backToHomeBtn.addActionListener(e -> cl.show(homeContainer, "Home"));

    mFrame.add(homeContainer);
    cl.show(homeContainer, "Home");
    mFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    mFrame.setLocationRelativeTo(null);
    mFrame.setExtendedState(JFrame.MAXIMIZED_BOTH);
    mFrame.pack();
    mFrame.setVisible(true);
}

public static void main(String[] args)
{
    SwingUtilities.invokeLater(MainFrame::new);
}
}

【讨论】:

    【解决方案2】:

    在这种情况下,您不需要对任何东西使用 CardLayout。事实上,JFrame 没有布局。

    这里有一些代码来说明这个想法(假设您使用的是 Java 8;否则,将 final 修饰符添加到 oldFramenewFrame

    JFrame parent = new JFrame();
    
    JDialog oldFrame = new JDialog("My Old Frame's Title");
    JDialog newFrame = new JDialog("My New Frame's Title");
    
    JPanel panel = new JPanel();
    JButton myButton = new JButton();
    
    myButton.addActionListener(new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            oldFrame.dispose(); //closes your old frame
            newFrame.setVisible(true); //opens your new frame
        }
    });
    
    panel.add(myButton);
    oldFrame.add(panek);
    oldFrame.setVisible(true);
    

    每当您单击按钮时,旧框架会关闭,而新框架会打开。

    【讨论】:

    • The Use of Multiple JFrames, Good/Bad Practice? - 作为一般经验法则,CardLayout 将是显示多个视图然后切换帧的首选解决方案
    • @MadProgrammer JFrames 没有布局。或者至少直接将组件添加到JFrames 是不好的做法,因此不需要添加任何布局。
    • 好吧,那是错误的。当然JFrames 有布局。 JFameFrame 扩展而来,WindowContainer 扩展而来,Container 定义了 setLayoutJFrame 覆盖 setLayout 以便将呼叫转发到 contentPane,但原则仍然适用。 JFrame 的默认布局是 BorderLayout,您可以将其更改为您想要的任何内容,但我不建议直接从 JFrame 扩展,并首先使用 JPanel 作为基本 UI
    • “或者至少直接将组件添加到 JFrames 是不好的做法” - 但这正是您鼓励 OP 做的事情。 OP 应该有一个 JFrame 的单个实例,它充当 JPanel 之类的容器,核心 UI 建立在其上(使用 CardLayout 允许它们在视图之间切换)
    • @3.14ed_Piper:你不应该使用拖放。在您完全理解 Swing Layouts 的工作原理之前,您应该自己编写 Swing GUI。
    猜你喜欢
    • 2021-08-08
    • 2019-12-24
    • 2011-12-14
    • 2017-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多