【问题标题】:Is it possible to add new JPanel to JFrame, after JFrame is loaded?加载 JFrame 后,是否可以向 JFrame 添加新的 JPanel?
【发布时间】:2017-10-17 11:53:09
【问题描述】:

我正在用 Java 构建一个扫雷游戏。在 GUI 设计期间,我遇到了一个问题。这是我的游戏窗口。

应该包含实际雷区的灰色区域。我想要发生的是,在玩家点击开始游戏后,我想加载包含雷区实现的 JPanel。但是,似乎在 JFrame 加载后我无法再添加任何 JPanel,我是对的吗?我尝试在不同的线程中运行添加雷区(睡眠几秒钟,然后添加 JPanel),只是看看是否可能,没有结果。

public GameWindow(){

        super("Minesweeper");
        this.setLayout(new BorderLayout());

        this.gamePanel = new GamePanel(new GridLayout(BOARD_SIZE,BOARD_SIZE,1,1));

        this.timerPanel = new TimerPanel(new BorderLayout(15,15));

        this.timerPanel.initializeFlagLabel(8);

        this.mineField = new Button[BOARD_SIZE][BOARD_SIZE];
        int buttonCounter = 0;

        for(int i = 0; i < BOARD_SIZE; i ++){

            for(int j = 0; j < BOARD_SIZE; j++){

                mineField[i][j] = new Button();
                mineField[i][j].setName(Integer.toString(buttonCounter++));
                mineField[i][j].setBackground(Color.GRAY);
                mineField[i][j].setPreferredSize(new Dimension(10,10));
                mineField[i][j].addMouseListener(this);
                gamePanel.add(mineField[i][j]);
            }
        }
        Container container = getContentPane();

        container.add(timerPanel,BorderLayout.PAGE_START);

        container.add(new MenuPanel(this), BorderLayout.WEST);

        new Thread(new Runnable(){//Here I want to wait for the JFrame to 
                                  //load and then to add the gamePanel.
                 public void run(){
                     try {
                        Thread.sleep(4000);
                        container.add(gamePanel, BorderLayout.CENTER);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                    e.printStackTrace();
                }

             }
        }); 

        this.setSize(800,640);
        this.setLocationRelativeTo(null);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setResizable(false);
        this.setVisible(true);

    }

总结一下我的问题是,是否可以在运行时向 JFrame 添加新的 JPanel,如果可以,我该怎么做?

【问题讨论】:

    标签: java swing


    【解决方案1】:

    简短的回答是,是的。您需要调用revalidaterepaint 来触发您更新的容器的布局和绘制过程。

    更长的答案是,可能不是你这样做的方式。

    除了您实际上从未startThread 之外,Swing 不是线程安全的,您不应该在事件调度线程的上下文之外更新 UI。

    在您的情况下,另一种(更安全)的解决方案是使用 Swing Timer。更多详情请见How to use Swing Timers

    【讨论】:

    • 是不是让menuPanel实现Observable,JFrame实现observer,点击开始游戏时menuPanel会通知JFrame加载gamePanel?
    • 嗯,你基本上描述的是一个 MVC,所以是的,这不是一个坏主意
    【解决方案2】:

    在开始游戏的动作监听器中,您可以将 jpanel 添加到预先创建的帧中。您可能还需要repaint()revalidate()

    【讨论】:

    • 是不是让menuPanel实现Observable,JFrame实现observer,当点击开始游戏时menuPanel会通过repaint()通知JFrame加载gamePanel?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多