Java 加载JFrame后,是否可以向JFrame添加新的JPanel?

Java 加载JFrame后,是否可以向JFrame添加新的JPanel?,java,swing,Java,Swing,我正在用Java开发一个扫雷游戏。在GUI设计期间,我遇到了一个问题。这是我的游戏窗口 灰色区域应包含实际的矿区。我想做的是,在玩家点击开始游戏后,我想加载包含地雷场实现的JPanel。然而,在JFrame加载之后,我似乎无法添加更多的JPanel,对吗?我尝试在另一个线程中运行添加地雷字段(睡眠几秒钟,然后添加JPanel),只是想看看是否可能,但没有结果 public GameWindow(){ super("Minesweeper"); this.setL

我正在用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);

    }
公共游戏窗口(){
超级(“扫雷舰”);
此.setLayout(新的BorderLayout());
this.gamePanel=newgamepanel(新网格布局(BOARD_SIZE,BOARD_SIZE,1,1));
this.timerPanel=新的timerPanel(新的边界布局(15,15));
此.timerPanel.initializeFlagLabel(8);
this.mineField=新按钮[BOARD_SIZE][BOARD_SIZE];
int buttonCounter=0;
对于(int i=0;i

总而言之,我的问题是,在运行时是否可以向JFrame添加新的JPanel,如果可以,我该如何做?

简短的回答是,可以。您需要调用
revalidate
repaint
来触发已更新容器上的布局和绘制过程

较长的答案是,可能不是你现在做的方式

除了您从未真正启动
线程之外,Swing不是线程安全的,您不应该在事件调度线程的上下文之外更新UI


在您的情况下,另一种(更安全的)解决方案是使用Swing
计时器。有关更多详细信息,请参见

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

较长的答案是,可能不是你现在做的方式

除了您从未真正启动
线程之外,Swing不是线程安全的,您不应该在事件调度线程的上下文之外更新UI


在您的情况下,另一种(更安全的)解决方案是使用Swing
计时器。有关更多详细信息,请参见《开始游戏的动作侦听器》,您可以将jpanel添加到预创建的帧中。您可能还需要
重新绘制()
重新验证()。您可能还需要
repaint()
revalidate()

让menuPanel实现Observable和JFrame实现Observator是否是一个好主意,当单击开始游戏时,menuPanel将通知JFrame加载游戏面板?好的,您基本上描述的是MVC,是的,这不是个坏主意menuPanel实现Observable和JFrame实现Observable是个好主意,当点击开始游戏时,menuPanel会通知JFrame加载游戏面板?好吧,你基本上描述的是MVC,所以是的,这主意不错让menuPanel实现Observable和JFrame实现observer是个好主意,当点击开始游戏时,menuPanel会通知JFrame使用repaint()加载游戏面板?让menuPanel实现Observable和JFrame实现observer是个好主意吗,当点击开始游戏时,menuPanel会通知JFrame使用repaint()加载游戏面板?