gpt4 book ai didi

java - 如何将 BorderLayout 放入 CardLayout 中?

转载 作者:行者123 更新时间:2023-12-01 12:56:17 25 4
gpt4 key购买 nike

问题可能不正确,但我不知道如何正确提问。对此我感到很抱歉。

问题在这里:

我的 JFrame 将 CardLayout 作为布局管理器。我有三个 JPanel,我在它们之间切换。一切都很好,直到我不得不将 2 个 JPanel 添加到其中一个中。现在,我的一个 JPanel 应该包含另外两个 JPanel。我在某处读到这是可能的。所以这个JPanel应该有BorderLayout。应该是这样的: enter image description here

这是我之前的:

  • 我的JFrame类:

    public class JavaGame2 extends JFrame {

    public JavaGame2(){

    CardLayout layout = new CardLayout();
    setLayout(layout);
    GameController controller = new CardLayoutGameController(getContentPane(), layout);

    gamePanel = new GamePanel(controller);
    menuPanel = new MenuPanel(controller);
    lvlPanel = new LvlEndPanel(controller);

    add(gamePanel, CardLayoutGameController.GAME_PANEL);
    add(menuPanel, CardLayoutGameController.MENU_PANEL);
    add(lvlPanel, CardLayoutGameController.LEVEL_PANEL);


    controller.showMenu();
    }
  • CardLayoutGameController 正在切换所有 JPanel:

    public class CardLayoutGameController implements GameController {
    public static final String GAME_PANEL = "GamePanel";
    public static final String MENU_PANEL = "MenuPanel";
    public static final String LEVEL_PANEL = "LvlPanel";

    private Container container;
    private CardLayout cardLayout;

    public CardLayoutGameController(Container parent, CardLayout layout) {
    container = parent;
    cardLayout = layout;
    }

    @Override
    public void showMenu() {
    cardLayout.show(container, MENU_PANEL);
    }

    @Override
    public void showGame() {
    cardLayout.show(container, GAME_PANEL);
    }

    @Override
    public void showEndLvl(){
    cardLayout.show(container, LEVEL_PANEL);
    }
    }

然后我添加了两个 JPanelInterfacePanelGameMainPanel(其中应该包括这个 InterfacePanel 和我的旧游戏面板)

现在的样子:

UPD可运行示例:

  • 可运行类:

    public class Mcve extends JFrame {

    private GamePanel gamePanel;
    private LvlEndPanel lvlPanel;
    private GameMainPanel gameMainPanel;


    Mcve(){
    CardLayout layout = new CardLayout();

    setLayout(layout);
    GameController controller = new CardLayoutGameController(getContentPane(), layout);

    gamePanel = new GamePanel(controller);
    lvlPanel = new LvlEndPanel(controller);
    gameMainPanel = new GameMainPanel(controller,this.getContentPane());

    add(gamePanel, CardLayoutGameController.GAME_PANEL);
    add(lvlPanel, CardLayoutGameController.LEVEL_PANEL);
    add(gameMainPanel, CardLayoutGameController.GAME_MAIN_PANEL);
    controller.showMenu();

    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    pack();
    setLocationRelativeTo(null);
    setTitle("JavaGame2");
    setResizable(false);
    }
    /**
    * @param args the command line arguments
    */
    public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
    public void run() {
    JFrame jgame = new Mcve();
    jgame.setVisible(true);
    }
    });
    }
    }
  • 游戏 Controller :

    public interface GameController {
    public void showMenu();
    public void showGame();
    public void showEndLvl();
    }
  • CardLayoutGameController:

    public class CardLayoutGameController implements GameController {
    public static final String MENU_PANEL = "MenuPanel";
    public static final String LEVEL_PANEL = "LvlPanel";
    public static final String GAME_MAIN_PANEL = "GameMainPanel";

    private Container container;
    private CardLayout cardLayout;

    public CardLayoutGameController(Container parent, CardLayout layout) {
    container = parent;
    cardLayout = layout;
    }

    @Override
    public void showMenu() {
    cardLayout.show(container, MENU_PANEL);
    }

    @Override
    public void showGame() {
    cardLayout.show(container, GAME_MAIN_PANEL);
    }

    @Override
    public void showEndLvl(){
    cardLayout.show(container, LEVEL_PANEL);
    }
    }
  • GameMainPanel - 包括 2 个 JPanel:

    public class GameMainPanel extends JPanel {

    private Container container;
    private GameController controller;
    private BorderLayout layout;

    private GamePanel gamePanel;
    private InterfacePanel interfacePanel;

    GameMainPanel(GameController contrl,Container parent){
    controller = contrl;
    container = parent;
    setFocusable(true);
    setBackground(Color.WHITE);
    getPreferredSize();

    gamePanel = new GamePanel(contrl);
    interfacePanel = new InterfacePanel(contrl);

    layout = new BorderLayout();
    setLayout(layout);
    add(gamePanel, BorderLayout.LINE_START);
    add(interfacePanel, BorderLayout.LINE_END);

    addComponentListener(new ComponentAdapter() {
    public void componentShown(ComponentEvent e) {
    requestFocusInWindow();
    }
    });
    }

    @Override
    public void addNotify() {
    super.addNotify();
    requestFocusInWindow();
    }

    public void paint(Graphics g) {
    super.paint(g);
    }

    public Dimension getPreferredSize() {
    return new Dimension(800, 600);
    }

    }
  • 游戏面板:

    public class GamePanel extends JPanel {

    private GameController controller;

    public GamePanel (GameController contrl){
    controller = contrl;

    addKeyListener(new GameAdapter(contrl));
    setFocusable(true);
    setBackground(Color.BLACK);
    getPreferredSize();
    addComponentListener(new ComponentAdapter() {

    public void componentShown(ComponentEvent e) {
    requestFocusInWindow();
    }
    });
    }

    @Override
    public void addNotify() {
    super.addNotify();
    requestFocusInWindow();
    }

    public Dimension getPreferredSize() {
    return new Dimension(650, 600);
    }

    @Override
    public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D)g;

    Font small = new Font("Helvetica", Font.BOLD, 24);
    FontMetrics metr = this.getFontMetrics(small);
    g.setColor(Color.GREEN);
    g.setFont(small);
    g.drawString("game",300,300);
    }

    private class GameAdapter extends KeyAdapter{

    private GameController controller;

    GameAdapter(GameController contrl){
    controller = contrl;
    }
    public void keyPressed(KeyEvent e) {
    if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
    controller.showEndLvl();
    }
    }
    }
    }
  • 界面面板

    public class InterfacePanel extends JPanel {

    private GameController controller;

    InterfacePanel(GameController contrl){
    setFocusable(true);
    setBackground(Color.WHITE);
    getPreferredSize();
    setSize(150,600);

    addComponentListener(new ComponentAdapter() {
    public void componentShown(ComponentEvent e) {
    requestFocusInWindow();
    }
    });
    }

    @Override
    public void addNotify() {
    super.addNotify();
    requestFocusInWindow();
    }

    public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D)g;

    Font small = new Font("Helvetica", Font.BOLD, 24);
    FontMetrics metr = this.getFontMetrics(small);
    g.setColor(Color.GREEN);
    g.setFont(small);
    g.drawString("interface",10,300);
    }

    public Dimension getPreferredSize() {

    return new Dimension(150, 600);
    }
    }
  • LvlEndPanel:

    public class LvlEndPanel extends JPanel{

    private GameController controller;

    public LvlEndPanel(GameController contrl){
    controller = contrl;

    setFocusable(true);
    setBackground(Color.BLACK);
    getPreferredSize();
    addComponentListener(new ComponentAdapter() {

    public void componentShown(ComponentEvent e) {
    requestFocusInWindow();
    }
    });

    addKeyListener(new KeyListener() {

    @Override
    public void keyPressed(KeyEvent e) {
    if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
    controller.showMenu();
    }
    }
    @Override
    public void keyTyped(KeyEvent e) {
    }
    @Override
    public void keyReleased(KeyEvent e) {
    }

    });
    }

    @Override
    public void addNotify(){
    super.addNotify();
    requestFocusInWindow();
    }

    public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D)g;

    Font small = new Font("Helvetica", Font.BOLD, 24);
    FontMetrics metr = this.getFontMetrics(small);
    g.setColor(Color.GREEN);
    g.setFont(small);
    g.drawString("Level Panel",300,300);
    }

    public Dimension getPreferredSize() {
    return new Dimension(800, 600);
    }
    }
  • 菜单面板:

    public class MenuPanel extends JPanel{

    private GameController controller;

    public MenuPanel(GameController contrl){

    setFocusable(true);
    setBackground(Color.WHITE);
    getPreferredSize();
    controller = contrl;

    addComponentListener(new ComponentAdapter() {
    public void componentShown(ComponentEvent e) {
    requestFocusInWindow();
    }
    });

    addKeyListener(new KeyListener() {

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
    if ((e.getKeyCode() == KeyEvent.VK_ENTER)) {
    controller.showGame();
    }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    });

    }

    @Override
    public void addNotify() {
    super.addNotify();
    requestFocusInWindow();
    }


    public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D)g;

    Font small = new Font("Helvetica", Font.BOLD, 24);
    FontMetrics metr = this.getFontMetrics(small);
    g.setColor(Color.GREEN);
    g.setFont(small);
    g.drawString("Game Menu", 300,300);
    }

    public Dimension getPreferredSize() {
    return new Dimension(800, 600);
    }
    }

向上倾斜

当我启动这个时,我只有黑框。我怎样才能解决这个问题?我做错了什么?

提前致谢。

感谢您的编辑。

最佳答案

您的 Controller 定义 showMenu作为

public void showMenu() {
cardLayout.show(container, MENU_PANEL);
}

但是你永远不会添加任何名称为 MENU_PANEL 的内容

add(gamePanel, CardLayoutGameController.GAME_PANEL);
add(lvlPanel, CardLayoutGameController.LEVEL_PANEL);
add(gameMainPanel, CardLayoutGameController.GAME_MAIN_PANEL);

更改 gameMainPanel 使用的名称至MENU_PANEL或更改 showMenu使用GAME_MAIN_PANEL相反

根据示例代码进行更新

实际上你的布局没有任何问题,(主要)问题是你的MenuPanel paint方法。如果可能,您应该避免在 paint 中加载字体。方法,加载字体的过程可能非常耗时,这会妨碍您的面板及时绘制。

相反,可以在构造函数中预加载字体,并在绘制时应用它,例如......

public class MenuPanel extends JPanel {
//...
public MenuPanel(GameController contrl) {
//...
Font small = new Font("Helvetica", Font.BOLD, 24);
setFont(small);
}

public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;

g.setFont(getFont());
FontMetrics metr = g.getFontMetrics();
g.setColor(Color.GREEN);
g.drawString("Game Menu", 300, 300);
}
}

这适用于LvlEndPanel , InterfacePanel ,和GamePanel还有...

旁注

  • addNotify将不再按照您配置的方式工作,因为组件仅添加一次,而您应该依赖 ComponentListener (你就是)。更好的解决方案是使用 the key bindings API这可以让您克服 KeyListener 的焦点限制.
  • 通常情况下,您会覆盖 paintComponent而不是paintpaint做了很多很容易被破坏的工作,并且其他子组件在重新绘制时可能会导致问题......

关于java - 如何将 BorderLayout 放入 CardLayout 中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23864045/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com