【问题标题】:How do I Switch JPanels inside a JFrame如何在 JFrame 中切换 JPanel
【发布时间】:2014-02-22 22:42:50
【问题描述】:

关于 javas 组件的东西等非常绿色,如果我提供的信息不够,请见谅!

考虑下面的代码。添加菜单和菜单显示在框架中,没问题。 我想在调用 gameOn() 时删除菜单并开始游戏。 下面的代码只使 Frames 表面“空白”,没有添加游戏面板。

关于如何解决它的任何想法/建议? MenuPanel 有一个鼠标监听器。

public class GameFrame extends JFrame {

private MenuPanel mp; //extends JPanel
private GamePanel gp; //extends JPanel

public GameFrame() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(new Dimension(GameFrame.XSIZE, GameFrame.YSIZE));
    setLocationRelativeTo(null);
    setVisible(true);
    mp = new MenuPanel(this);

    add(mp);
}
public void gameOn() {
    remove(mp);
    GamePanel gp = new GamePanel(5);
    add(gp);
}
}

【问题讨论】:

  • 尝试做一个“repaint();”添加后(gp);
  • 尝试调用 pack();添加面板后!

标签: java swing jframe jpanel


【解决方案1】:

不要尝试添加删除组件,而是使用CardLayout

CardLayout cardLayout = new CardLayout();
JPanel mainPanel = new JPanel(cardLayout);

MenuPanel menu = new MenuPanel();
GamePanel game = new GamePanel();
mainPanel.add(menu, "menu");
mainPanel.add(game, "game");

...
public void gameOn() {
    cardLayout.show(mainPanel, "game");
}

gameOn() 被调用时,menu 将被推到后面,game 被推到前面。

这样你就不必一直添加和删除

这是您可以运行的示例

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class GameFrame extends JFrame implements ActionListener{

    CardLayout cardLayout;
    JPanel mainPanel;
    MenuPanel menu;
    GamePanel game;

    public GameFrame() {
        cardLayout = new CardLayout();
        mainPanel = new JPanel(cardLayout);
        menu = new MenuPanel();
        game = new GamePanel();
        mainPanel.add(menu, "menu");
        mainPanel.add(game, "game");


        JButton goGame = new JButton("Go TO Game");
        goGame.addActionListener(this);

        add(mainPanel);
        add(goGame, BorderLayout.SOUTH);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationByPlatform(true);
        setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        gameOn();
    }

    public void gameOn() {
        cardLayout.show(mainPanel, "game");
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                GameFrame gameFrame = new GameFrame();
            }
        });
    }
}

class MenuPanel extends JPanel {

    public MenuPanel() {
        setBackground(Color.GREEN);
        add(new JLabel("Menu"));
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }
}

class GamePanel extends JPanel {

    public GamePanel() {
        setBackground(Color.BLUE);
        add(new JLabel("Game"));
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 300);
    }
}

【讨论】:

    【解决方案2】:

    添加GamePanel后,validate();

    public void gameOn() {
    remove(mp);
    gp = new GamePanel(5);
    add(gp);
    validate();
    

    }

    【讨论】:

    • 很好,成功了!但是,完成后,我在 GamePanel 中的 keyListener 似乎无法正常工作。对此有什么想法吗?
    • 在您的第一篇文章中添加 GamePanel 类,看看有什么问题。
    • 发现另一个关于这件事的问题,应该先检查一下!在验证()之后;我打电话给 gp.requestFocusInWindow() 并且它起作用了。感谢您的帮助!
    • 没问题。希望您不会遇到任何其他问题。
    【解决方案3】:

    删除一个面板并添加另一个面板后,您需要repaint()setVisible(true) 应该在您添加组件后完成 ts 到框架,我建议在 EDT 线程上进行大量的 UI 更改以避免干扰。

    【讨论】:

    • repaint() 没有区别。抱歉,我现在对线程很陌生。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    相关资源
    最近更新 更多