2014-04-22 132 views
1

我正在使用javaFX + java编写的Omaha在线扑克客户端。JavaFX:任务不会更新UI

我需要在control.call()完成执行后显示包含3个按钮的anchorPane。 我知道一个事实,即control.call()完成执行但由于某种原因task.setOnSucceeded(new EventHandler() {的处理方法更新用户界面。

我在做什么错?

public void newRound() { 

    sog = StateOfGame.PREFLOP;  

    ControlGameOnNewThread control = new ControlGameOnNewThread(); 

    Task task = new Task() { 

     @Override 
     protected Object call() throws Exception { 
      control.call(); 
      return null; 
     } 
    }; 

    task.setOnSucceeded(new EventHandler() { 

     @Override 
     public void handle(Event event) { 
      if (client.getAction() == FirstToAct.me) { 
       System.out.println("Task finsished"); 
        showOptions(client.getToCall()); 
        opponentBetField.setText(new Integer(opp.chipsInvested).toString()); 
        myBetField.setText(new Integer(client.chipsInvested).toString()); 
        System.out.println("Task finsished"); 

      } 
    } 
    }); 


    new Thread(task).start(); 


} 
+0

您确定您的'call(...)'方法成功了,而不是抛出异常吗?尝试使用'task.getException()。printStackTrace()'注册一个'setOnFailed(...)'处理程序来查看是否抛出了一些东西。 –

回答

1

的问题是,你正在更新中的其他线程的用户界面。如果你在其他线程和要更新的用户界面

你需要调用


Platform.runLater(new Runnable() { 
    @Override public void run() { 
    //Update UI here  
    } 
}); 

调用这将调用主线程,并更新所有必要的更新到用户界面

编辑

public void newRound() { 

    sog = StateOfGame.PREFLOP;  

    ControlGameOnNewThread control = new ControlGameOnNewThread(); 

    Task task = new Task() { 

     @Override 
     protected Object call() throws Exception { 
      control.call(); 
      return null; 
     } 
    }; 

    task.setOnSucceeded(new EventHandler() { 

     @Override 
     public void handle(Event event) { 

      if (client.getAction() == FirstToAct.me) { 

       Platform.runLater(new Runnable() { 
        @Override public void run() { 
        System.out.println("Task finsished"); 
        showOptions(client.getToCall()); 
        opponentBetField.setText(new Integer(opp.chipsInvested).toString()); 
        myBetField.setText(new Integer(client.chipsInvested).toString()); 
        System.out.println("Task finsished");  
        } 
       }); 
      } 
    } 
    }); 


    new Thread(task).start(); 


} 
+0

我试图实现你所说的,但我遇到了同样的问题。这里是新的代码:http://pastebin.com/zcvybKik – zeroRooter

+0

@zeroRooter更新了我的答案..我的意思是只把用户界面更新不是类实例 –

+0

感谢您的帮助到目前为止,但用户界面仍然在实现你的解决方案后没有更新,我一直认为Platform.runLater()无论如何创建了一个新的线程。无论如何,这是一个链接到整个文档https://github.com/zeroRooter/Omaha-Poker/blob/master/src/huclient/ClientControl.java(函数newRound在310行) – zeroRooter

1

当你重写call()方法,您可以覆盖succeeded()方法:(见任务的javadoc的最后一个例子。)

@Override protected void succeeded() { 
    super.succeeded(); 
    updateMessage("Done!"); 
} 

succeeded()已经呼吁JavaFX应用程序线程,所以你不需要为自己做这件事。

你确定,你的句柄方法中的代码没有被调用吗?也许会抛出一个NullPointerException,你可能看不到?比较是否按预期工作?

尝试将if (client.getAction()...的代码移入覆盖的succeeded()方法,并在if语句之前放置println以查看它是否被调用。

(编辑:错别字)

+0

行347 ish https://github.com/zeroRooter/Omaha-Poker/blob/master/src/huclient/ClientControl.java 是的,代码肯定没有得到执行,我已经完成了你对println所说的话,并且我已经将它上传到了git。重写成功应该做同样的事情,我做对了吗? – zeroRooter

+0

@zeroRooter yes - 将if语句及其块放入覆盖的succeeded()方法中。它应该这样做。当你在它的时候,也覆盖失败()和取消(),并把println语句也放在那里。您还应该在call()方法的return语句之前放置一个print语句。所以你可以看到调用方法是通过还是在两者之间得到一个异常。异常将存储在'exceptionProperty'中,您可以在'failed()'方法中查看。 –

-1

你的信息是有帮助的,但我想建议将一直工作方法(包括我最初的一个)。问题是,任务从来没有结束这就是为什么onTaskSucceded从未被执行。为了让任务在完成后退出,我必须将守护进程设置为true:

Thread thread = new Thread(task); 
     thread.setDaemon(true); 
     thread.start(); 
+0

即使这样做,我认为它可能会隐藏您如何使用任务的一些基本问题。是否真的调用onTaskSucceeded任务应该与线程的守护进程状态无关。 – jewelsea

+0

在插入'setDaemon(true)'的调用之后,你的“成功”代码被执行了吗? –

+0

是的,但我认为如果您仍然留下更新不同线程上UI的代码,它也会有点困惑。事实上,您需要将Deamon设置为true并移除,并且在任何其他非main-javaFX线程上更新UI的所有代码。 – zeroRooter