简体   繁体   English

Java Swing Button Listeners无法正常工作

[英]Java Swing Button Listeners not working

I have two button listeners for game board using java swing. 我有两个使用java swing的游戏板按钮监听器。

A tetris grid is created initially and then addition functionality within each button listener. 最初创建一个tetris网格,然后在每个按钮监听器中添加功能。

I set the board up like so in my Play.java: 我在我的Play.java中设置了这样的板:

final TetrisGame g = new TetrisGame(11,1);
final BoardGraphics graphics = new BoardGraphics(TetrisBoard.BOARD_WIDTH, 40, g);

The button listeners are then created in the same Play.java: 然后在同一个Play.java中创建按钮侦听器:

graphics.btnStart.addActionListener(new ActionListener()
        {
           public void actionPerformed(ActionEvent e)
           {
              Action arc = p.getAction(g);
              g.update(arc);
              graphics.colours.clear();
              graphics.setColor(g.getBoard().getGrid());
              while (arc instanceof Store){
                  arc = p.getAction(g);
                  g.update(arc);
                  graphics.colours.clear();
                  graphics.setColor(g.getBoard().getGrid());
              }

             graphics.tiles.redraw();
             System.out.println();
             System.out.println(g.toString());
             System.out.println();
           }

        });


        graphics.btnAuto.addActionListener(new ActionListener()
        {
           public void actionPerformed(ActionEvent e)
           {

               while (!g.gameEnded()){
                  Action arc = p.getAction(g);
                  g.update(arc);
                  graphics.colours.clear();
                  graphics.setColor(g.getBoard().getGrid());
                  while (arc instanceof Store){
                      arc = p.getAction(g);
                      g.update(arc);
                      //graphics.colours.clear();
                      graphics.setColor(g.getBoard().getGrid());
                  }
                  graphics.tiles.redraw();
                  System.out.println();
                  System.out.println(g.toString());
                  System.out.println();
                  /*try {
                    Thread.sleep(1000);
                } catch (InterruptedException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }*/

               }

           }

        });

The btnStart works perfectly, pressing it once, painting the tetrisboard according to the next move given by AI agent. btnStart完美地工作,按下它一次,根据AI代理给出的下一步动作绘制tetrisboard。

I would like the btnAuto to play each move out without the user pressing btnStart to generate move until the end. 我希望btnAuto能够在没有用户按下btnStart的情况下播放每个移动,直到结束。 However, my btnAuto does not paint anything on to the grid but the final state of the game, the finishing state. 但是,我的btnAuto不会在网格上绘制任何东西,而是游戏的最终状态,即完成状态。

Can anyone see why this might be not repainting the grid after each move is generated in the while loop? 任何人都可以看到为什么在while循环中生成每个移动后,这可能不会重新绘制网格?

Your while loop is being called on the Swing event thread and is thus preventing the the thread from doing its necessary actions including rendering the GUI and interacting with the user: 您的while循环正在Swing事件线程上调用,因此阻止线程执行必要的操作,包括呈现GUI并与用户交互:

while (!g.gameEnded()){
  Action arc = p.getAction(g);

  // ....

}

I would use a Swing Timer here instead of a while (true) loop. 我会在这里使用Swing Timer而不是while (true)循环。 Another option is to use a background thread, but since all you desire is a very simple game loop and don't need to run some long-running in the background, I think that this second option would be more complex with no additional benefit. 另一种选择是使用后台线程,但是因为你想要的只是一个非常简单的游戏循环而且不需要在后台运行一些长时间运行,我认为第二种选择会更复杂,没有额外的好处。

As an aside, I'm curious how you're doing your drawing and how you're getting your Graphics object to draw with. 顺便说一句,我很好奇你是如何做你的绘图以及你如何让你的Graphics对象绘制的。 You're not calling getGraphics() on a component, are you? 你不是在组件上调用getGraphics() ,不是吗?


Edit you state in a comment: 编辑你在评论中说明:

I currently have a class with a nested class that extends JPanel. 我目前有一个带有嵌套类的类,它扩展了JPanel。 The drawing of the grid and getGraphics() is done within the nested class.The parent class creates the component and sets the layout of the GUI as a whole grid和getGraphics()的绘制是在嵌套类中完成的。父类创建组件并将GUI的布局设置为一个整体

Don't get a Graphics object by calling getGraphics() on a GUI component as the Graphics object obtained will not persist. 不要通过在GUI组件上调用getGraphics()来获取Graphics对象,因为获得的Graphics对象不会持久存在。 To see that this is so, simply minimize and then restore your application and tell me what happens to your graphics after doing this. 要看到这一点,只需最小化然后恢复您的应用程序,并告诉我在执行此操作后图形会发生什么。 You should do all of your drawing in the JPanel's paintComponent override. 你应该在JPanel的paintComponent覆盖中完成所有绘图。 One option is to call getGraphics() on a BufferedImage and use it to draw to the BufferedImage, and then display the BufferedImage in the paintComponent override. 一种选择是在BufferedImage上调用getGraphics()并使用它绘制到BufferedImage,然后在paintComponent覆盖中显示BufferedImage。 If you use the second technique, don't forget to dispose of the BufferedImage's Graphics object after you are done using it so that you don't hog system resources. 如果您使用第二种技术,请不要忘记在完成使用后丢弃BufferedImage的Graphics对象,这样就不会占用系统资源。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM