如何调用Java GUI的即时更新? (与Thread.sleep()冲突)

问题描述:

我正在制作游戏内存,当你选择两张牌时,如果它们匹配,则保留它们,否则将它们还原。如果你还记得你已经选择的牌,你可以更好地猜测下两张牌。我有问题repaint()方法不立即重新绘制。如何调用Java GUI的即时更新? (与Thread.sleep()冲突)

当我翻转第二张牌时,无论结果如何,我希望在丢弃或翻转它们之前将两张牌正面向上翻转。我通过拨打sleep()来完成此操作。

当然,如果我将它们翻过来的卡右侧向上等待一秒钟,然后再根据它们的值repaint(),有用的小Java将只重绘一次(我错过C!)。

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

因为我知道StackOverflow上的帮助人员很喜欢阅读代码,下面是我在下面提到的程序的一部分。类HitArea是卡对象,而cards[]数组包含的数量为HitArea(我没有得到重命名HitArea类)。 activeCard1activeCard2HitArea我用来跟踪用户的两个选择的实例,空白构造函数是一个保留的“不可见”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]); 
     } 
} 

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

不要在主Swing线程EDT上调用Thread.sleep(...)。 Ever。而是使用摆动计时器。

考虑使用JLabels来显示图像,然后通过简单地更换ImageIcons来“翻转”卡片。当第二张卡被翻转时,如果没有匹配,则启动一个不重复的Swing Timer,并延迟xxxx ms,并在Timer的ActionListener的actionCommand方法中将它恢复为默认的ImageIcon。

的javax.swing.Timer中的教程可以在这里找到:How to use 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(); 
+3

我会大胆并倾斜“永远”。 :) – fireshadow52

+0

我只是显示一些g.drawString(...)文本,没有图像。这同样适用吗? –

+0

谢谢,完成了。 :) –