当前位置: 首页 > 面试题库 >

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

陈飞语
2023-03-14
问题内容

我正在制作“记忆”游戏,当您选择两张卡并且如果它们匹配时,您将保留它们,否则将它们退回。如果您还记得已经选择的卡,则可以对下两张卡进行更好的猜测。

repaint()遇到的问题涉及该方法无法立即重绘。

当我翻转第二张卡时,无论结果如何,我都希望显示两张卡都朝上翻转,然后丢弃它们或将它们翻转过来。我通过打电话来做到这一点sleep()

当然,如果我repaint()将这些卡向右翻转,请稍等片刻,然后repaint()再根据它们的值再次使用,那么有用的Java只会重涂一次(我想念C!)。

基本上,我想在我之前强制调用更新sleep()。我读过其他一些线程,这些线程基本上说最好的方法是创建两个线程以使逻辑和图形保持分离,然后可以进行sleep()逻辑处理并保持GUI更新,但是我处于CS一年级课程的第一学期在高中时,我希望将其保持在课程水平上(尽管暑假期间我花了很多时间来开发和编写C语言代码)。

因为我知道StackOverflow的乐于助人的人喜欢阅读代码,所以这是我在下面引用的程序的一部分。该类HitArea是Card对象,并且cards[]数组包含一定数量HitArea的。(我还没有重命名HitArea该类)。activeCard1activeCard2HitArea我用来跟踪用户的两个选择的情况下,空白的构造是一个保留“看不见”的HitArea,虽然我会在以后更改为空。最后,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(…)。 曾经 。而是使用Swing计时器。

考虑使用JLabel显示图像,然后可以通过简单地换出ImageIcons来“翻转”卡片。翻转第二张卡后,如果不匹配,则启动一个非重复的Swing计时器,延迟时间为xxxx
ms,并在Timer的ActionListener的actionCommand方法中将两个JLabel的状态都还原为默认的ImageIcon。

可以在这里找到javax.swing.Timer教程:如何使用Swing计时器

编辑:
关于您对使用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();


 类似资料:
  • 问题内容: 码: 当我在中输入内容时,以下内容将立即更改。是否可以配置它仅在输入所有字符并保留输入后才更新? 问题答案: 更新资料 正如许多人提到的那样,Angular现在使用指令对此提供了内置支持。在这里查看更多。 下面的旧答案: ng-model没有内置选项来更改该行为,但是您可以编写一个自定义指令来执行此操作。@Gloopy 写了这样的指令。你可以在这里看看小提琴。 该指令从和事件中注销,这

  • 下面是我的代码的一个片段。调用filteredData()时,状态未更新。在状态更新之前,我必须单击按钮两次。这是一个旧项目,我正在使用钩子更新它。我以前在设置状态后使用了回调函数,但我不能用钩子实现。 }

  • 问题内容: 我试图在针对ElasticSearch进行测试的套件上提高性能。 测试需要很长时间,因为Elasticsearch在更新后不会立即更新其索引。例如,以下代码在运行时不会引发断言错误。 目前,针对该问题的解决方案是将调用放到代码中,以给ElasticSearch一些时间来更新其索引。 显然,这并不是一件好事,因为它很容易出现故障,假设如果ElasticSearch花费多于一秒钟的时间来更

  • 问题内容: 我正在做一个待办事项应用程序。这是违规代码的非常简化的版本。我有一个复选框: 这是调用复选框的函数: updateItem是映射为分派到redux的函数 我的问题是,当我调用updateItem操作并在console.log状态时,它总是落后1步。如果未选中该复选框且该复选框不为true,则仍将状态为true传递给updateItem函数。我是否需要调用另一个函数来强制状态更新? 问题

  • 重试时间:io.reactivex.subjects.serializedsubject@35fb3008 subscribeNext 进程已完成,退出代码为0

  • 问题内容: 我有一个包含10个元素的div,这些元素将被逐个更新,延迟时间为2秒。下面是相同的代码 但是,当我运行它时,所有元素都会一起更新。该程序只是添加一个延迟添加一个开始,并且所有元素都一起更新(被标记)。如何制作代码来逐一标记元素? 问题答案: 您正在打破React的两个基本规则: 不要直接改变状态 如果根据现有状态更新状态,请使用回调形式,因为状态更新可能是异步的(无论如何,在您的示例中