我们如何从单个服务更新多个控件。现在Service中只有一个Base
,其值只能绑定到一个控件,因此只更新。我们如何更新多个控件的值?
我的服务类实例:
Child
这只更新一条消息,即我只能绑定一个标签。有什么办法可以从同一个线程更新多个消息,这样我就可以在我的UI中绑定多个标签了吗?
已编辑 - 根据评论提供更多信息
我的运行是:
updateMessage()
我运行一个线程来改变//run a background thread
threadTimeChecker = new Service<Void>() {
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
while (!isDone) {
DataHelper.setCurrentDate(LocalDate.now());
if(!DataHelper.getOldDate().equals(DataHelper.getCurrentDate())) {
DataHelper.setIntIndex(DataHelper.getIntIndex()+1);
DataHelper.setOldDate(DataHelper.getCurrentDate());
DataHelper.saveData();
System.out.println("Saved!");
}
//Thread.currentThread().sleep(2000);
updateMessage(wordString.getValue());
}
return null;
}
};
}
};
threadTimeChecker.restart();
//bind string properties to labels
word.textProperty().bind(threadTimeChecker.messageProperty());
,它调用一个监听器,根据索引改变'String Property':
@Override
protected Task<Void> createTask() {
return new Task<Void>() {
@Override
protected Void call() throws Exception {
//loop run until the program is closed
while (!isDone) {
DataHelper.setCurrentDate(LocalDate.now());
if (!DataHelper.getOldDate().equals(DataHelper.getCurrentDate())) {
Platform.runLater(new Runnable(){
@Override
public void run() {
DataHelper.setIntIndex(DataHelper.getIntIndex()+1);
}
});
DataHelper.setOldDate(DataHelper.getCurrentDate());
DataHelper.saveData();
}
Thread.currentThread().sleep(5000);
}
return null;
}
};
}
我已经使用这些'String Properties'来绑定三个不同的标签,如:
DataHelper.IntIndex
现在我想做的是使用更多 JavaFX 倾斜 //listener to detect change in index and assign strings of word,meaning, and sentence, accordingly
DataHelper.intIndexProperty().addListener(
(v, oldValue, newValue) -> {
wordString.setValue(DataHelper.getListOfWords().get((int) newValue).get("word"));
meaningString.setValue(DataHelper.getListOfWords().get((int) newValue).get("meaning"));
sentenceString.setValue(DataHelper.getListOfWords().get((int) newValue).get("sentence"));
System.out.print("kjbmmj");
}
);
来实现同样目标。
答案 0 :(得分:3)
我们只需要更新DataHelper
的单个实例,而不是更新多条消息。 DataHelper具有将更新多个标签的内容。例如,让我们考虑在每次服务调用后我们要更新以下标签:
为了简单起见,让我们考虑一下你有一个DataHelper
类,它有三个属性词,含义和句子。
private class DataHelper {
public DataHelper(String word, String meaning, String sentence) {
this.word.setValue(word);
this.meaning.setValue(meaning);
this.sentence.setValue(sentence);
}
StringProperty word = new SimpleStringProperty();
StringProperty meaning = new SimpleStringProperty();
StringProperty sentence = new SimpleStringProperty();
// setters and getters
}
我们将服务称为后台任务,每当使用后台任务完成服务时,它都会返回更新的DataHelper。
Service<DataHelper> service = new Service<DataHelper>() {
@Override
protected Task<DataHelper> createTask() {
return new Task<DataHelper>() {
@Override
protected DataHelper call() throws Exception {
i.incrementAndGet(); // Don't worry about i here
return new DataHelper("Word " + i, "Meaning " + i, "Sentence " + i);
}
};
}
};
现在,每当我们调用服务器时,我们都会获得一个更新的DataHelper,我们希望在标签上显示。
为了解决这个问题,我们声明了一个变量dataHelper
并将其属性绑定到各种标签的textProperty()
:
DataHelper dataHelper = new DataHelper("Word", "Meaning", "Sentence");
wordLabel.textProperty().bind(dataHelper.wordProperty());
meaningLabel.textProperty().bind(dataHelper.meaningProperty());
sentenceLabel.textProperty().bind(dataHelper.sentenceProperty());
现在您一定想知道,我们将如何更新dataHelper
,对吧?嗯,这是最简单的部分。这可以在setOnSucceeded()
服务中谨慎处理,其中getValue()
会向我们返回DataHelper
的新实例,其中 已更新 值
service.setOnSucceeded(event -> {
dataHelper.setWord(service.getValue().getWord());
dataHelper.setMeaning(service.getValue().getMeaning());
dataHelper.setSentence(service.getValue().getSentence());
});
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.concurrent.Service;
import javafx.concurrent.Task;
import javafx.concurrent.Worker;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.concurrent.atomic.AtomicInteger;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
// Properties
DataHelper dataHelper = new DataHelper("Word", "Meaning", "Sentence");
AtomicInteger i = new AtomicInteger(0);
// UI elements
Label wordLabel = new Label();
Label meaningLabel = new Label();
Label sentenceLabel = new Label();
Button startService = new Button("Start");
Service<DataHelper> service = new Service<DataHelper>() {
@Override
protected Task<DataHelper> createTask() {
return new Task<DataHelper>() {
@Override
protected DataHelper call() throws Exception {
i.incrementAndGet();
return new DataHelper("Word " + i, "Meaning " + i, "Sentence " + i);
}
};
}
};
startService.setOnAction(e -> {
if(service.getState().equals(Worker.State.READY) || service.getState().equals(Worker.State.SUCCEEDED)) {
service.restart();
}
});
service.setOnSucceeded(event -> {
dataHelper.setWord(service.getValue().getWord());
dataHelper.setMeaning(service.getValue().getMeaning());
dataHelper.setSentence(service.getValue().getSentence());
});
wordLabel.textProperty().bind(dataHelper.wordProperty());
meaningLabel.textProperty().bind(dataHelper.meaningProperty());
sentenceLabel.textProperty().bind(dataHelper.sentenceProperty());
VBox box = new VBox(10, wordLabel, meaningLabel, sentenceLabel, startService);
box.setAlignment(Pos.CENTER);
Scene scene = new Scene(box, 200, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
private class DataHelper {
StringProperty word = new SimpleStringProperty();
StringProperty meaning = new SimpleStringProperty();
StringProperty sentence = new SimpleStringProperty();
public DataHelper(String word, String meaning, String sentence) {
this.word.setValue(word);
this.meaning.setValue(meaning);
this.sentence.setValue(sentence);
}
public String getMeaning() {
return meaning.get();
}
public StringProperty meaningProperty() {
return meaning;
}
public void setMeaning(String meaning) {
this.meaning.set(meaning);
}
public String getSentence() {
return sentence.get();
}
public StringProperty sentenceProperty() {
return sentence;
}
public void setSentence(String sentence) {
this.sentence.set(sentence);
}
public String getWord() {
return word.get();
}
public StringProperty wordProperty() {
return word;
}
public void setWord(String word) {
this.word.set(word);
}
}
public static void main(String[] args) {
launch(args);
}
}