在 JPanel 之间切换



我正在尝试制作一个游戏。游戏中有几个不同的屏幕,例如主菜单和实际的游戏屏幕。这些中的每一个都是一个单独的 jpanel 扩展。我已经将它们中的每一个都添加到我的JFrame中,这是一个叫做Game的类。在我的游戏课上,我有以下方法

public void addPanel( JPanel p ) {
    panels.add( p ); // An array of all the different panels I need
    this.getContentPane().add( p );
}
public void switchToPanel( JPanel p ) {
    for ( JPanel somePanel : panels ) {
        somePanel.setVisible( false );
    }
    p.setVisible( true );
    repaint();
}

这样做的重点是我有许多不同的面板,当我需要显示特定的面板时,例如菜单屏幕,我调用 switchToPanel( myPanel )。基本上只是隐藏每个面板,然后取消隐藏我需要看到的面板。唯一的问题是当我切换到它们时,这些面板没有显示。唯一会出现的是我上次添加的面板。在Objective C中,我一直使用这种技术在视图之间切换,我从来没有遇到过任何问题。这种事情在java中是不允许的吗?

编辑:现在我在切换后调用 repaint(),但它仍然不起作用

您可以执行许多不同的操作来达到相同的效果。

我提出的第一个建议是使用CardLayout(如何使用CardLayout),因为这是它的设计目的。

另一种是使用JTabbedPane(如何使用Tabbed Panes)

如果您正在制作游戏,则可以在与EDT不同的单独线程中制作它。大多数游戏通过不更改面板来显示不同的屏幕,但它们使用单个面板,并根据GameState在其上渲染。

下面是一个示例。

public class MyGame extends JPanel implements Runnable {
    public static enum GameState {
        MENU, INTRO, LEVELS, END, TITLES
    }
    GameState state = GameState.MENU;
    public MyGame(){
        setDoubleBuffered(true);
        // Initialize the resources
        new Thread(this).start();
    }
    public void update(long elapsedTime){
        switch (state){
            case MENU:
                // Show the menu
                break;
            ....
        }
    }
    private void GameLoop(){
        // Game Loop goes here
    }
    public void run(){
        GameLoop();
    }
    public void paint(Graphics g){
        // switch and draw your game
    }
    public static void main(String[] args){
        JFrame f = new JFrame("MyGame");
        f.setSize(640, 480);
        f.add(new MyGame());
        f.setVisible(true);
    }

}

如果一个状态,即菜单已完成,则更改state变量。在自己制作之前,先学习使用GameEngine

如果要在两个面板之间切换,请将这些面板添加到另一个 JPanel 并使用 cardLayout。然后,在添加JPanel之前删除当前。喜欢这个:

parentPanel.removeAll();
parentPanel.repaint();
parentPanel.revalidate();
parentPanel.add(childPanel1);
parentPanel.repaint();
parentPanel.revalidate();
同样,对

其他子面板执行相同的操作。

    public static void main(String[] args) {
        JFrame jFrame = new JFrame("Test");
        jFrame.setSize(500, 500);
        jFrame.setLocationRelativeTo(jFrame.getOwner());
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setLayout(new BorderLayout());
        var jPanel = new JPanel(new BorderLayout());

        jFrame.add(jPanel, BorderLayout.CENTER);
        AtomicBoolean b = new AtomicBoolean(false);
        jFrame.add(new JButton("Switch") {
            {
                addActionListener(e -> {
                    b.set(!b.get());
                    jPanel.removeAll();
                    jPanel.repaint();
                    jPanel.revalidate();
                    jPanel.add(b.get() ? new JPanel() {
                        @Override
                        protected void paintComponent(Graphics g) {
                            setBackground(Color.RED);
                            super.paintComponent(g);
                        }
                    } : new JPanel() {
                        @Override
                        protected void paintComponent(Graphics g) {
                            setBackground(Color.GREEN);
                            super.paintComponent(g);
                        }
                    });
                    jPanel.repaint();
                    jPanel.revalidate();
                });
            }
        }, BorderLayout.SOUTH);
        jFrame.setVisible(true);
    }

最新更新