【发布时间】:2018-02-21 14:32:05
【问题描述】:
我正在尝试创建以下概念:每当启动特定屏幕时启动一个线程。该线程应该收到一条称为“标签”的消息,该消息尚未工作,因此我对其进行了硬编码。 然后根据标签的验证显示一个 AnchorPane:showError 或 showValid 函数。但是,应用程序首先运行该函数,然后显示 AnchorPane 和更新后的 ListView。
我想在特定屏幕启动时启动以下线程。
public class RFIDThread extends Thread{
private static final Logger logger = Logger.getLogger(RFIDApplication.class);
/**
* The incoming data stream from the LLRP reader connection
*/
private DataInputStream inStream = null;
/**
* The socket for the connection to the LLRP Reader
*/
private Socket socket = null;
/**
* A queue to store incoming LLRP Messages
*/
private LinkedBlockingQueue<LLRPMessage> queue = null;
private String[] found_tags = new String[5];
private JSONArray valid_tags;
private TagsListController controller;
/**
* Thread for constant reading of the stream
*
* @param socket
* @param controller
* @param tags
* @param orderNumber
* @throws java.io.IOException
*/
public RFIDThread(Socket socket, TagsListController controller, JSONArray tags, String orderNumber) throws IOException {
this.socket = socket;
this.controller = controller;
this.queue = new LinkedBlockingQueue<LLRPMessage>();
try {
this.inStream = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
logger.error("Cannot get input stream", e);
}
valid_tags = tags;
found_tags[0] = "aga9jrjahr";
found_tags[1] = "agahs4suj";
found_tags[2] = "a79gtvaTGBQG";
found_tags[3] = "at3anit08av9agq4";
//found_tags[4] = "4a05355d0000000000017cc0";
//start();
}
@Override
public void run()
{
super.run();
if (socket.isConnected()) {
for (String found_tag : found_tags) {
Integer index = valid_tags.indexOf(found_tag);
if (index > 0) {
Platform.runLater(() -> {
controller.showValid(found_tag);
});
} else {
Platform.runLater(() -> {
controller.showError(found_tag);
});
}
}
}
}
}
线程应该运行函数:showError 或 showValid 基于它接收到的标签。目前我设置了一些无效的硬编码标签,因此它应该运行 showError() 函数。此功能:将标签添加到ListView,将标签设置为标签的文本,显示AnchorPane,休眠1秒,隐藏AnchorPane,然后休眠1秒。在此之后,必须处理下一个标签。
/**
* Display red screen
* @param tag
*/
public void showError(String tag) {
this.found_tags_list.getItems().add(tag);
this.errorTag.setText(tag);
System.out.println(errorTag.getText());
this.errorPane.setVisible(true);
pause(1000);
this.validPane.setVisible(false);
pause(1000);
}
【问题讨论】:
-
如果
pause(...)做了我认为的那样,你正在阻塞 FX 应用程序线程(因为showError(...)在该线程上执行)。这将阻止 UI 被渲染,直到整个showError(...)方法(包括它的暂停)完成。如果你想在暂停后做一些基于 UI 的事情,那么使用PauseTransition。不清楚第二次停顿的目的是什么,因为之后什么都没有发生。 (另外,你大概是指this.errorPane.setVisible(false);?) -
您也可以将暂停移动到后台线程并在控制器中使用
hideError()和hideValid()方法,您可以从该线程通过Platform.runLater(...)调用它们。 -
方法在控制器中,这就是为什么我将控制器传递给线程以便它可以调用这些方法。
-
这与我的评论有什么关系?
-
当我回到我的电脑前。但是我很难理解为什么你不能只遵循简单的指令“将暂停移动到后台线程”。
标签: java multithreading javafx