如何立即调用Java GUI?(与Thread.sleep()冲突)

Eri*_*oma 7 java user-interface swingx repaint

我正在制作游戏记忆,当你选择两张牌时,如果匹配你就得保留它们,否则你会把它们转回去.如果你记得你已经选择过的牌,你可以对接下来的两张牌进行更好的猜测.

repaint()遇到的问题涉及不立即重新粉刷的方法.

当我翻转第二张卡片时,无论结果如何,我都要显示两张卡片在放弃或翻转之前向右翻转.我是通过打电话来做的sleep().

当然,如果我repaint()将卡片正面向上翻转,等待一秒钟,然后repaint()再根据它们的值,有用的小Java只会重绘一次(我想念C!).

基本上我想在我之前强制调用更新sleep().我已经阅读了一些其他线程,基本上说最好的方法是创建两个线程来保持逻辑和图形分离,然后你可以使用sleep()你的逻辑并保持你的GUI更新,但我在第一学期CS课程的第一学期在高中时,我希望将其保持在课程的水平上(尽管我花了很多时间在夏季网上开发和编写C语言).

因为我知道StackOverflow上有用的人喜欢阅读代码,所以这是我在下面提到的程序的一部分.该类HitArea是Card对象,cards[]数组包含一定数量HitArea的.(我没有重命名HitArea该类).activeCard1并且activeCard2HitArea我用来跟踪用户的两个选择的实例,并且空白构造函数是保留的"不可见" HitArea,尽管我稍后会将其更改为null.最后,cards.flip()反转一个toggle布尔值,确定卡是否正面朝上.

public void respond(HitArea choice)
{
    if(choice.inGame)
    {
        if(activeCard1.value == 0 && activeCard1.value == 0)
            activeCard1 = choice;
        else if((!(activeCard1.value == 0) && activeCard2.value == 0) && (activeCard1.id != choice.id))
        {
            activeCard2 = choice;
            check();
        }

    }
}
public void check()
{
    update();
    pause(250);
    if(activeCard2.value == activeCard1.value)
    {
        score += 2;
        activeCard1.inGame = false;
        activeCard2.inGame = false;
    }
    activeCard1.flip();
    activeCard2.flip();
    activeCard1 = new HitArea();
    activeCard2 = new HitArea();
}
public void pause(int milliseconds)
{
    try{
      Thread.currentThread().sleep(milliseconds);
    }
    catch(InterruptedException e){
        System.out.println("Exception: " + e);
    }
}

public void mousePressed(MouseEvent e)
{
    int x = e.getX();
    int y = e.getY();

    for (int i = 0; i < cardNum; i++)
        if(cards[i].boundsCheck( x, y ) )
        {
            repaint();
            cards[i].flip();
            respond(cards[i]);
        }
}
Run Code Online (Sandbox Code Playgroud)

我毫不怀疑我的代码中存在一些问题,所以请随意指出它们.我认为我的基本结构没问题,我宁愿不为这个项目创建多个线程(记住,这是基本的!).

Hov*_*els 14

不要在主Swing线程EDT上调用Thread.sleep(...).曾经.而是使用Swing Timer.

考虑使用JLabel来显示您的图像,然后您只需更换ImageIcons就可以"翻转"您的卡片.当第二卡已经翻转,如果没有匹配,启动一个不重复的秋千定时器与XXXX毫秒的延迟,并且在定时器的的ActionListener的actionCommand方法有它恢复双方JLabel的回默认的ImageIcon.

可以在此处找到javax.swing.Timer教程:如何使用Swing Timers

编辑:
关于你使用g.drawString的评论:现在更容易,因为所有你需要做的就是换掉你的JLabel文本.但是后来如果您决定升级程序以显示图像,那么您已经完成了这一切.

编辑2:
关于创建一个新的ActionListener类的问题:我将使用匿名内部类.例如:

  int delayTime = 2 * 1000;
  javax.swing.Timer myTimer = new Timer(delayTime, new ActionListener() {

     @Override
     public void actionPerformed(ActionEvent e) {
        // TODO: put in the code you want called in xxx mSecs.
     }
  });
  myTimer.setRepeats(false);
  myTimer.start();
Run Code Online (Sandbox Code Playgroud)

  • 我会大胆和斜体"永远".:) (3认同)