java - JFrame 不等待 JOptionPane 执行

标签 java swing jframe joptionpane

我正在开发一个项目,在其中创建一个简单的乒乓球游戏。如果玩家获胜,我希望弹出一个 JOptionPane 询问用户是否想玩新游戏或停止玩。当我添加 JOptionPane 时,该方法不会等待用户选择按钮,而是继续创建 JOptionPane,直​​到返回堆栈溢出错误。控制它的代码是

int rightMinLeft = Right_Player_Score.getNumber()-Left_Player_Score.getNumber();
boolean rightWon = Right_Player_Score.getNumber() > 20 && rightMinLeft > 1;
if(rightWon)
{
  Object[] options = {"New Game", "Finish"};
  int i = JOptionPane.showOptionDialog(null, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
  if(i == 0)
  {
    reset();
  }
  else
  {
    GameOver = true;
  }
}
else if(Left_Player_Score.getNumber() > 20 && Left_Player_Score.getNumber()-Right_Player_Score.getNumber()>1)
{
  Object[] options = {"New Game", "Finish"};
  int i = JOptionPane.showOptionDialog(null, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
  if(i == 0)
  {
    reset();
  }
  else
  {
    GameOver = true;
  }
}

有什么建议吗?

编辑: 完整方法如下:

public void update(Graphics window)
 {
  paint(window);
 }

 public void paint(Graphics window)
 {
   try{
   if(pause)
   {
     Right_Player_Score.draw("Right Player Score", window, 600, 20);
     Left_Player_Score.draw("Left Player Score", window,  0, 20);
     leftPaddle.draw(window);
     rightPaddle.draw(window);
     if(U.LELatch(keys[4]))
     {
       pause = false;
     }
   }
   else
   {
     ball.moveAndDraw(window);
     leftPaddle.draw(window);
     Right_Player_Score.draw("Right Player Score", window, Color.WHITE, 600, 20);
    Left_Player_Score.draw("Left Player Score", window,  Color.WHITE, 0, 20);
    int LeftPaddleBottom = leftPaddle.getY()+(leftPaddle.getHeight());
    int RightPaddleBottom = rightPaddle.getY()+(rightPaddle.getHeight());
    int LeftPaddleTop = leftPaddle.getY();
    int RightPaddleTop = rightPaddle.getY();
    boolean inRangeLeft = ball.getY() > LeftPaddleTop && ball.getY() < LeftPaddleBottom;
    boolean inRangeRight = ball.getY() > RightPaddleTop && ball.getY() < RightPaddleBottom;
    if(ball.getX()<=10)
    {
     ball.setXSpeed(-ball.getXSpeed());
     Right_Player_Score.increment();
    }
    else if(ball.getX()>=790)
    {
      ball.setXSpeed(-ball.getXSpeed());
      Left_Player_Score.increment();
    }
    else if((inRangeLeft && ball.getX()<=leftPaddle.getX()+leftPaddle.getWidth()))
    {
      ball.setXSpeed(-ball.getXSpeed());
      numTimes ++;
    }
    else if(inRangeRight && ball.getX()>=rightPaddle.getX())
    {
      ball.setXSpeed(-ball.getXSpeed());
      numTimes ++;
    }

    if(!(ball.getY()>=10 && ball.getY()<=450))
    {
     ball.setYSpeed(-ball.getYSpeed());
    }

    if(keys[0] == true)
    {
     leftPaddle.moveUpAndDraw(window);
    }
    else if(keys[1] == true)
    {
     leftPaddle.moveDownAndDraw(window);
    }
    else
    {
      leftPaddle.draw(window);
    }
    if(keys[2] == true)
    {
      rightPaddle.moveUpAndDraw(window);
    }
    else if(keys[3] == true)
    {
      rightPaddle.moveDownAndDraw(window);
    }
    else
    {
      rightPaddle.draw(window);
    }
    int rightMinLeft = Right_Player_Score.getNumber()-Left_Player_Score.getNumber();
    boolean rightWon = Right_Player_Score.getNumber() > 20 && rightMinLeft > 1;
    if(rightWon)
    {
      Object[] options = {"New Game", "Finish"};
      int i = JOptionPane.showOptionDialog(frame, "Right Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
      //window.setColor(Color.BLACK);
      //window.drawString("Right Player has won",200,400);
      //Thread.currentThread().sleep(2000);
      //int i = 1;
      if(i == 0)
      {
        reset();
      }
      else
      {
        GameOver = true;
      }
    }
    else if(Left_Player_Score.getNumber() > 20 && Left_Player_Score.getNumber()-Right_Player_Score.getNumber()>1)
    {
      Object[] options = {"New Game", "Finish"};
      int i = JOptionPane.showOptionDialog(frame, "Left Player has won", "Game Over", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE, null, options, options[0]);
      //window.setColor(Color.BLACK);
      //window.drawString("Left Player has won",200,400);
      //Thread.currentThread().sleep(2000);
      //int i = 1;
      if(i == 0)
      {
        reset();
      }
      else
      {
        GameOver = true;
      }
    }
    Right_Player_Score.draw("Right Player Score", window, 600, 20);
    Left_Player_Score.draw("Left Player Score", window, 0, 20);
    if(numTimes == 10)
    {
      numTimes = 0;
      if(ball.getXSpeed() == Math.abs(ball.getXSpeed()))
      {
        ball.setXSpeed(ball.getXSpeed() + 1);
      }
      else
      {
        ball.setXSpeed(ball.getXSpeed() - 1);
      }
      if(ball.getXSpeed()>MAXSPEED)
      {
        ball.setXSpeed(MAXSPEED);
      }
    }
    pause = U.LELatch(keys[4]);
   }
   }
   catch(Exception e)
   {
   }
 }

这用于“public class GUI_Controller extends Canvas Implements KeyListener, Runnable”

注意:注释部分是让用户至少看到某些内容的权宜之计。

最佳答案

您看到的行为是因为您重载了 paint(Graphics g) 方法。

来自paint(Graphics g) Java文档

This method is called when the contents of the component should be painted; such as when the component is first being shown or is damaged and in need of repair.

就您而言,可能发生的情况是调用 JOptionPane.showOptionDialog() 会导致 JDialog 显示在您的 Canvas 上,其中触发对 paint() 的另一次调用。这反过来又会导致对 JOptionPane.showOptionDialog() 的另一次调用,进而触发对 paint() 的另一次调用,依此类推...这将持续下去,直到您获得 StackOverflowErrorOutOfMemoryError

实际上,paint() 被频繁调用,因此它应该非常高效。通常,只有您的自定义绘图应该在 paint() 方法中完成。

其他逻辑应该存在于不同的方法中。您应该将评分和用户交互的逻辑移到 paint() 方法之外,只保留绘图。

编辑:在没有看到更多代码的情况下,我无法向您提供将与绘画不直接相关的逻辑移动到何处的具体建议。您可能会发现查看Java Swing tutorial很有帮助。 Performing Custom Painting 部分.

关于java - JFrame 不等待 JOptionPane 执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15549679/

相关文章:

java - <f :convertNumber> use the right number separator when using patterns to format currency?

java - 向 JTextArea 添加滚动条

java - 使用netbeans在java中更改密码程序

java - 如何在 Java GUI 中隐藏输入

Java Swing 用鼠标移动 JFrame

java - 框架和按钮

java - 正确使用 JavaFX setUserData?

java - 在android中有效清理opengl动画?

java - 总计未加起来

java - 在 jframe 运行时添加删除面板