У меня есть приложение JavaFX, которое читает теги и затем помещает их в список VBox с помощью HBox (метка и кнопка). Однако приложение работает очень медленно, когда нужно обработать много тегов. Как я могу оптимизировать этот процесс? Другая проблема, с которой я сталкиваюсь, заключается в том, что курсор и приложение застряли / спят при загрузке / обработке новых тегов. Могу ли я как-то это исправить, чтобы поток работал в фоновом режиме, и я все еще мог использовать свое приложение?
Моя собственная тема:
package nl.fermrfid.application.rfidreader;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.scene.Node;
import org.json.simple.JSONArray;
import java.io.IOException;
import java.net.Socket;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;
public class RFIDThread implements Runnable
{
/**
* The socket for the connection to the LLRP Reader
*/
private Socket socket;
private JSONArray valid_tags;
private JSONArray found_tags;
private TagsListController controller;
private RFIDSet rfidset;
/**
* Thread for constant reading of the stream
*
* @param socket
* @param controller
* @param tags
*/
public RFIDThread(Socket socket, TagsListController controller, JSONArray tags, RFIDSet rfidset) {
this.socket = socket;
this.controller = controller;
this.rfidset = rfidset;
this.found_tags = new JSONArray();
this.valid_tags = tags;
}
/**
* Runnable for this thread.
* First get all the found tags from the xml controller
* Then loop over the rfid set to find any new tags.
* If there are any, display them.
*/
@Override
public void run()
{
if (socket.isConnected()) {
while (!socket.isClosed()) {
CopyOnWriteArrayList<Tag> set = new CopyOnWriteArrayList<>();
set.addAll(this.rfidset.getSet());
Collection<String> found_set = FXCollections.observableSet();
this.found_tags.clear();
for(Node n : this.controller.found_tags_box.getChildren()) {
this.found_tags.add(n.getId());
}
for (Tag found_tag : set) {
String tag_id = found_tag.getId();
if (found_tags.indexOf(tag_id) < 0) {
found_tags.add(tag_id);
found_set.add(tag_id);
}
}
Platform.runLater(() -> controller.addAllFoundTags(found_set));
pause(2000);
}
}
}
/**
* Close the socket
*/
public void shutdown()
{
try {
this.socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void pause(long ms)
{
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Метод запуска потока, чтобы начать мой собственный поток:
/**
* Start the rfid thread
* @param rfidset
* @param action
* @param textOrder
*/
public void startThread(RFIDSet rfidset, Action action, String textOrder)
{
String readerId = RFIDApplication.getContext().getProperties().getProperty(SETTINGS_READERS);
String host = RFIDApplication.getContext().getProperties().getProperty(String.format(SETTINGS_READER_HOST, readerId));
String port = RFIDApplication.getContext().getProperties().getProperty(String.format(SETTINGS_READER_PORT, readerId));
this.rfidset = rfidset;
this.action = action;
this.textOrder = textOrder;
// Preparing management server instance ...
this.server = RFIDApplication.server;
// Preparing RFID reader instance ...
this.reader = RFIDApplication.reader;
try {
thread = new RFIDThread(new Socket(host, Integer.parseInt(port)), this, valid_tags, rfidset);
new Thread(thread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
Метод, который вызывается при обнаружении новых тегов, которые необходимо поместить в список. Это очень уродливый метод.
public void addAllFoundTags(Collection<String> tags)
{
for(String tag_id : tags) {
Integer index = valid_tags.indexOf(tag_id);
Label label = new Label(tag_id);
label.setTextFill(index >= 0 ? Color.GREEN : Color.RED);
Image cancel = new Image("/cancel.png", 14, 14, false, false);
Button butt = new Button();
butt.setGraphic(new ImageView(cancel));
butt.setStyle("-fx-background-color: transparent;");
butt.setOnAction(event -> {
for (Tag tag : rfidset.getSet()) {
if (tag.getId().equals(tag_id)) {
rfidset.remove(tag);
for(Node n : found_tags_box.getChildren()) {
if(n.getId().equals(tag_id)) {
found_tags_box.getChildren().remove(n);
break;
}
}
tags_amount.setText(Integer.toString(Integer.parseInt(tags_amount.getText()) - 1));
return;
}
}
});
HBox hBox = index >= 0 ? new HBox(label) : new HBox(label, butt);
if (even) hBox.setStyle("-fx-background-color: #F9F9F9");
hBox.setId(tag_id);
hBox.setPrefHeight(25.0);
hBox.setMinHeight(25.0);
hBox.setMaxHeight(25.0);
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.setPadding(new Insets(0, 0, 0, 10));
even = !even;
this.found_tags_box.getChildren().add(hBox);
}
tags_amount.setText(Integer.toString(this.found_tags_box.getChildren().size()));
this.scroll_pane.setVvalue(1.0);
}