【问题标题】:How to have one JPanel show up and the second one disappear on button click?如何在单击按钮时显示一个 JPanel 而第二个消失?
【发布时间】:2022-01-18 03:48:08
【问题描述】:

所以我有 3 个单独的类,主菜单类上的设置按钮应该切换到主菜单,但它只是隐藏了第一个面板,当我在另一个菜单上单击返回时也是如此,我想找到一个简单的解决方案不使用布局管理器,因为我不知道如何让卡片布局与 2 个类进行通信,但这就是解决方案,如果有人能给我一些关于如何实现它的指示,那就太好了:

public class Game extends JFrame {
    MainMenu mainMenu;
    Settings settings;

    public Game(){
        setSize(900,900);
        setDefaultCloseOperation(3);
        mainMenu = new MainMenu();
        settings = new Settings();

        mainMenu.setSettings(settings);
        settings.setMainMenu(mainMenu);

        add(settings,BorderLayout.CENTER);
        add(mainMenu, BorderLayout.CENTER);


    }

    public static void main(String[] args) {
        Game game = new Game();
        game.setVisible(true);
    }
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class MainMenu extends JPanel {
    Settings settings;

    public void setSettings(Settings settings) {
        this.settings = settings;
    }

    public MainMenu() {
        setLayout(new GridLayout(1,3));
        JButton Newgame = new JButton("New Game");
        JButton Cont = new JButton("Continue");
        JButton Sett = new JButton("Settings");
        add(Newgame);
        add(Cont);
        SwitchMenu1 switchMenu1 = new SwitchMenu1();
        Sett.addActionListener(switchMenu1);
        add(Sett);
    }



    class SwitchMenu1 implements ActionListener{
        @Override

        public void actionPerformed(ActionEvent e) {
            if(isVisible()){
                settings.setVisible(true);
                setVisible(false);

            }

        }
    }


}
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Settings extends JPanel {
    MainMenu mainMenu;

    public void setMainMenu(MainMenu mainMenu) {
        this.mainMenu = mainMenu;
    }

    public Settings(){
        JButton Return = new JButton("Return");
        SwitchMenu2 switchMenu2 = new SwitchMenu2();
        Return.addActionListener(switchMenu2);
        add(Return, BorderLayout.SOUTH);
    }
    class SwitchMenu2 implements ActionListener{

        @Override
        public void actionPerformed(ActionEvent e) {
            if(isVisible()){
                mainMenu.setVisible(true);
                setVisible(false);

            }
        }
    }
}

我希望在单击按钮时显示另一个 JPanel,但它不起作用,第一个 JPanel 就消失了。我该如何解决这个问题?

非常感谢!

【问题讨论】:

  • 简单的答案是使用CardLayout
  • 另一个用户this question中的代码和这个有很多共同点是巧合吗?
  • 我想知道为什么代码从问题中删除。和我之前的评论有关系吗?
  • “如果有人能给我一些关于如何实现它的指示,那就太好了:” 嗯,第一件事是创建一个CardLayout 来显示你朝着目标努力。 SO 不是代码生成服务或帮助台。

标签: java swing class actionlistener


【解决方案1】:

这听起来是CardLayout 的用例。您有一个 JPanel,例如命名为 cards,它使用 CardLayout 管理器。您将所有面板(卡片)添加到该面板,并为其指定唯一名称(例如,“MAIN_MENU”、“SETTINGS”等)。然后,您只需传递卡片面板,而不是传递每个面板中的所有其他面板,该面板可用于显示您想要的卡片,例如,cl.show(cards, "SETTINGS"); 在单击按钮时。

更新

根据@c0der 的建议(参见下面的cmets 部分),代码结构已经更新。

Game.java

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Game extends JFrame {
    JPanel cards;
    CardLayout cardLayout;
    
    public Game(){
        MainMenu mainMenu = new MainMenu();
        Settings settings = new Settings();
        cardLayout = new CardLayout();
        cards = new JPanel(cardLayout);
        cards.add(mainMenu, "MAIN_MENU");
        cards.add(settings, "SETTINGS");
        mainMenu.setSetBtnActionListener(new BtnController("SETTINGS"));
        settings.setReturnBtnActionListener(new BtnController("MAIN_MENU"));
        add(cards);
        setSize(640,480);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }

    class BtnController implements ActionListener {
        String cardName;
        public BtnController(String cardName) {
            this.cardName = cardName;
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            cardLayout.show(cards, cardName);
        }
    }
    
    public static void main(String[] args) {
        new Game();
    }
}

MainMenu.java

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

public class MainMenu extends JPanel {
    JButton setBtn;
    
    public MainMenu() {
        setLayout(new GridLayout(1, 3));
        JButton newGameBtn = new JButton("New Game");
        JButton contBtn = new JButton("Continue");
        setBtn = new JButton("Settings");
        add(newGameBtn);
        add(contBtn);
        add(setBtn);
    }

    public void setSetBtnActionListener(ActionListener al) {
        setBtn.addActionListener(al);
    }
}

Settings.java

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

public class Settings extends JPanel {
    JButton returnBtn;
    
    public Settings() {
        returnBtn = new JButton("Return");
        setLayout(new BorderLayout());
        add(returnBtn, BorderLayout.SOUTH);
    }

    public void setReturnBtnActionListener(ActionListener al) {
        returnBtn.addActionListener(al);
    }
}

【讨论】:

  • ` CardLayout` 确实是正确的工具。我建议更改结构以避免SettingsMainMenu 之间的耦合。一种简单的方法是使用public void setActionListene(ActionListene al) { returnBtn.addActionListener(al); } 而不是setCards
  • 最终修饰:从 MainMenu 中删除 Settings settings; 和从 Settings 中删除 MainMenu 引用
猜你喜欢
  • 1970-01-01
  • 2014-03-16
  • 1970-01-01
  • 1970-01-01
  • 2015-09-30
  • 2023-03-22
  • 2018-04-04
  • 1970-01-01
  • 2023-04-09
相关资源
最近更新 更多