JavaFX是单线程编程,所有对界面的操作都会交给唯一的线程Application Thread去处理。因此需要使用线程同步技术来避免异常。在实际应用中,我们房间是在开始游戏之前创建的,而游戏开始后又要处理传来的倒计时,图像,答案,聊天等数据并显示。这就需要java与javaFX线程的同步。
Platform.runLater(...)是javafx.application包里自带的任务队列,原理是把你要执行的动作添加到类似队列中,等Application Thread线程空闲时处理,还是主线程(Application Thread)处理的,你的那个线程只是放在等待队列了。
使用时传入参数需要继承 runnable
我们在游戏中使用还加入了Timer来定时刷新数据。
代码结构如下
new Timer().schedule(new TimerTask() { public void run() { Platform.runLater(new Runnable() { public void run() { //子线程代码 } }); } }, 2000);
Timer timer = new Timer(); timer.schedule(new TimerTask() { public void run() { synchronized (flag) { if (flag) { NewIo.send(ClientPost.Type.IM_ALIVE, new HashMap<>()); ServerReturn sr = NewIo.send(ClientGet.Type.STATE, new HashMap<>()); ArrayList<TernaryTuple<Integer, String, Boolean>> infolist = (ArrayList<TernaryTuple<Integer, String, Boolean>>) sr.args .get("players"); ArrayList<BinaryTuple<String, String>> chatlist1 = (ArrayList<BinaryTuple<String, String>>) sr.args .get("chat_list"); //ai++; System.out.println("\n房主debug"+sr.args.toString()); Platform.runLater(new Runnable() { @Override public void run() { // 更新JavaFX的主线程的代码放在此处 if (chatlist1 != null) { for (BinaryTuple<String, String> cl : chatlist1) { chatlist.add(cl.first + " :" + cl.second); } } getchatlist.setItems(chatlist); VBox vb = OwnerGame.rebuildleft(sr); bp.setLeft(vb); if(sr.args.get("guessed")!=null) { answerlist.add("系统消息 "+sr.args.get("guessed")+"猜对了"); getanswerlist.setItems(answerlist); } if(sr.args.get("state").equals(State.CHOICE_TIME)) { answerlist.clear(); answerlist.add("游戏开始本界面用于答题"); getanswerlist.setItems(answerlist); } if(sr.args.get("drawed") != null) { dngdc.addDraw((List<TernaryTuple<Object, Object, List<BinaryDoubleTuple>>>) sr.args.get("drawed")); } bp.setCenter(rebuilddng(dngbp,sr)); } }); } else { NewIo.send(ClientPost.Type.QUIT, new HashMap<>()); } } } }, 1,1000);
这种方法实质是使用 JavaFx 自带的一个任务队列, vafx.application.Platform.runlater。将 gui 更新任务放到队列里待更新, 传入参数需要继承 runnable。
用这种方法就能避免子线程直接更新gui造成的异常。
使用Platform.runLater(...)构造工作队列即可实现java和javaFx的多线程同步。
阅读JavaFx文档,查Stack Overflow并在组里大佬的帮助下完成。