There is simple application on JavaFx with SplitPane on Stage.
On SplitPane there are two StackPane. On Each there is one Label.
I want to update text on each Label's in cycle every per/sec. How can i do that in one Thread(one Task)? Is it real?
在舞台上使用SplitPane在JavaFx上有简单的应用程序。在SplitPane上有两个StackPane。每个都有一个标签。我希望每秒每秒更新每个Label的文本。我怎么能在一个线程(一个任务)中做到这一点?这是真的吗?
For example, i want to see text in labelUp = key of Map, and labelDw = value of Map.
例如,我想在Label的labelUp = key中看到文本,而labelDw = Map的值。
package com.javarush.test.MyTry;
import javafx.application.*;
import javafx.concurrent.Task;
import javafx.geometry.Orientation;
import javafx.scene.*;
import javafx.scene.control.Label;
import javafx.scene.control.SplitPane;
import javafx.stage.*;
import javafx.scene.layout.*;
import java.io.*;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
public class Main extends Application
{
Map<String, Integer> dictionary = new HashMap<>();
public static void main(String[] args)
{
launch(args);
}
public void init()
{
String filePath = "F:\\Java\\!Folder4Test\\test2.txt";
try
{
BufferedReader reader = new BufferedReader(new FileReader(filePath));
int cnt = 0;
while (reader.ready())
{
String line = new String(reader.readLine().getBytes(), Charset.forName("UTF-8"));
dictionary.put(line, cnt++);
}
}
catch (FileNotFoundException e)
{
System.out.println("Не найден файл " + filePath);
e.printStackTrace();
}
catch (IOException e)
{
System.out.println("Ошибка чтения файла " + filePath);
e.printStackTrace();
}
}
public void start(Stage myStage)
{
myStage.setTitle("JavaFXSkeleton.");
SplitPane sp = new SplitPane();
sp.setOrientation(Orientation.VERTICAL);
Label labelUp = new Label("test");
Label labelDw = new Label("тест");
Scene scene = new Scene(sp, 800, 800);
myStage.setScene(scene);
final StackPane sp1 = new StackPane();
sp1.getChildren().add(labelUp);
final StackPane sp2 = new StackPane();
sp2.getChildren().add(labelDw);
sp.setOnMouseClicked(event -> {
Task<Void> task = new Task<Void>()
{
@Override
public Void call() throws Exception
{
for (Map.Entry<String, Integer> pair : dictionary.entrySet())
{
updateMessage(pair.getKey());
System.out.println(pair.getKey());
Thread.sleep(250);
}
return null;
}
};
task.messageProperty().addListener((obs, oldMessage, newMessage) -> labelUp.setText(newMessage));
//there i want to update text on labelDw in same time
//task.messageProperty().addListener((a1,a2,a3)->labelDw.setText());
new Thread(task).start();
});
sp.getItems().addAll(sp1, sp2);
sp.setDividerPositions(0.5f, 0.5f);
myStage.show();
}
public void stop()
{
System.out.println("B теле метода stop().");
}
}
(Sorry for my bad English)
(对不起,我的英语不好)
1 个解决方案
#1
1
Use the Animation API. E.g. using a timeline:
使用动画API。例如。使用时间表:
sp.setOnMouseClicked(event -> {
Timeline timeline = new Timeline();
int step = 250 ;
int millis = 0 ;
for (Map.Entry<String, Integer> entry : dictionary.entrySet()) {
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(millis), e -> {
labelUp.setText(entry.getKey());
labelDw.setText(entry.getValue().toString());
}));
millis += step ;
}
timeline.play();
});
If you want to use a thread, you can do so with:
如果要使用线程,可以使用以下命令:
sp.setOnMouseClicked(event -> {
Task<Void> task = new Task<Void>()
{
@Override
public Void call() throws Exception
{
for (Map.Entry<String, Integer> pair : dictionary.entrySet())
{
Platform.runLater(() -> {
labelUp.setText(pair.getKey());
labelDw.setText(pair.getValue().toString());
});
System.out.println(pair.getKey());
Thread.sleep(250);
}
return null;
}
};
new Thread(task).start();
});
but I recommend using a timeline here.
但我建议在这里使用时间表。
#1
1
Use the Animation API. E.g. using a timeline:
使用动画API。例如。使用时间表:
sp.setOnMouseClicked(event -> {
Timeline timeline = new Timeline();
int step = 250 ;
int millis = 0 ;
for (Map.Entry<String, Integer> entry : dictionary.entrySet()) {
timeline.getKeyFrames().add(new KeyFrame(Duration.millis(millis), e -> {
labelUp.setText(entry.getKey());
labelDw.setText(entry.getValue().toString());
}));
millis += step ;
}
timeline.play();
});
If you want to use a thread, you can do so with:
如果要使用线程,可以使用以下命令:
sp.setOnMouseClicked(event -> {
Task<Void> task = new Task<Void>()
{
@Override
public Void call() throws Exception
{
for (Map.Entry<String, Integer> pair : dictionary.entrySet())
{
Platform.runLater(() -> {
labelUp.setText(pair.getKey());
labelDw.setText(pair.getValue().toString());
});
System.out.println(pair.getKey());
Thread.sleep(250);
}
return null;
}
};
new Thread(task).start();
});
but I recommend using a timeline here.
但我建议在这里使用时间表。