Reputation: 1085
I have a ListView<String> list
. I can easily get the next item in the ListView with a button using this code:
public void toNext(){
list.getSelectionModel().selectNext();
}
But if I want to go through the ListView automatically with a button, it won't work. I tried the following code:
public void play(){
try {
for (int i = 0; i < list.getItems().size() ; i++) {
list.getSelectionModel().select(i);
Thread.sleep(500);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
This code doesn't select the different strings in the list but just skips to the last string after the given waittime. How can I get it to select each string in the list with a delay of 500 ms?
Upvotes: 0
Views: 221
Reputation: 209340
Consider using an animation:
Timeline animation = new Timeline(
new KeyFrame(Duration.millis(500), e -> list.getSelectionModel().selectNext()));
list.getSelectionModel().select(0);
animation.setCycleCount(list.getItems().size()-1);
animation.play();
Advantages to this approach include
Upvotes: 3
Reputation: 3518
The problem is, your loop completely runs in FxApplicationThread.
So, the UI won't update during the loop.
Better would be something like:
public void play(){
Thread t = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < lijst.getItems().size(); i++) {
final int idx = i;
Platform.runLater(new Runnable() {
@Override
public void run() {
lijst.getSelectionModel().select(idx);
}
});
try {
Thread.sleep(1000);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
});
t.start();
}
Upvotes: 3
Reputation: 7496
You have to wrap the call that makes the UI update in the UI thread otherwise all the updates are done in one bunch at the end, hence it jumps to the end of the list.
public void play(){
try {
for (int i = 0; i < list.getItems().size() ; i++) {
final int index = i;
Platform.runLater(() -> {
list.getSelectionModel().select(index)
});
Thread.sleep(500);
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
Upvotes: 0