Javafx - 如何在textarea中延迟显示新行?

时间:2017-07-16 16:27:28

标签: java javafx

所以我得到了这个我正在编码的新游戏。 长话短说,我的GUI中有一个textarea作为事件显示器。当你对抗一个怪物时,这个textarea用于显示文本行,例如"你对骨架造成3点伤害"或者" Skeleton向你施放火球并击中你,造成5点伤害"。

代码以某种方式工作,以便怪物攻击你。所以一旦你点击'#34;攻击"按钮,两行都说你做了什么,以及说明怪物在textarea中同时出现的行。就像怪物在你击中它之后可以以光速击中你一样。

我想要做的是延迟怪物线的显示。所以当我点击'#34;攻击"按钮,textarea显示我所做的行,然后等待一秒,然后显示怪物的行。

我尝试使用Thread.sleep()方法,但它只是将UI暂停1秒,然后两行显示在textarea中。

private void attackBareFists() {

    if (initPJ > enemyINIT) { // Player has more initiative ->
                                // Player attacks first
        turnPlayerBareFists(); // This method will display the player's line

        if (!endTurn()) { // endTurn() checks that the player or the monster 
                          // are still alive before continuing the fight
            delay();
            turnMonster(); // This method will display the monster's line
            endTurn();
        }
    } ... // The code continues, but it's the same as above except monster attacks first
}

/**
 * Wait for some time
 */
private void delay(){

}

我应该延迟什么()?这是我尝试过Thread.sleep(1000)的地方。就像我说的那样,这样做会导致turnPlayerBareFists()和turnMonster()的代码在delay()之后执行。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

我认为实现这一目标的更好/更一致的方法是使用计时器。你可以使用任何java实现,尽管javafx本身为定时事件提供了几种机制。

一种方法是TimeLine

onAudioFocusChange()

以上方式也是javafx animations (as you can read in the documentation)

的基础知识

This blog显示了一些如何完成定时任务的示例。 (Ps。它也使用reactFX!)

答案 1 :(得分:0)

好问题!我建议使用这样的东西:

public static void delay(long delayMs, Runnable toRun){
    Thread t = new Thread(() ->{
        try { Thread.sleep(delayMs); }catch(InterruptedException ignored){}
        Platform.runLater(toRun);
    });
    t.setDaemon(true);
    t.start();
}

这样,您可以准确指定调用delay()与执行代码之间的延迟时间。基本上你传递一个Runnable包含你想要运行的任何代码作为方法的第二个参数。

例如,这意味着你的怪物将被表示为:

if(!endTurn())
    delay(1000, ()->{ turnMonster(); endTurn(); });

如果出于某种原因,您不想使用lambdas(“() - >”事物),您可以使用:

public static void delay(long delayMs, Runnable toRun){
    Thread t = new Thread(new Runnable(){
        public void run(){
            try { Thread.sleep(delayMs); }catch(InterruptedException ignored){}
            Platform.runLater(toRun);
        }
    });
    t.setDaemon(true);
    t.start();
}

你的怪物代码看起来像这样:

if(!endTurn())
    delay(1000, new Runnable(){ public void run(){ turnMonster(); endTurn(); } });

如果您想知道,Platform引用javafx.application.Platform并且runLater()方法将始终将给定的Runnable发布到JavaFX线程,因此可以安全地传递操作它的代码UI。