Created
June 10, 2015 12:38
-
-
Save TheItachiUchiha/06bdf4ad3039616834a1 to your computer and use it in GitHub Desktop.
ComboSample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import javafx.application.Application; | |
import javafx.beans.binding.Bindings; | |
import javafx.beans.property.ObjectProperty; | |
import javafx.beans.property.SimpleObjectProperty; | |
import javafx.concurrent.Task; | |
import javafx.scene.Cursor; | |
import javafx.scene.Scene; | |
import javafx.scene.control.ComboBox; | |
import javafx.scene.control.Label; | |
import javafx.scene.layout.HBox; | |
import javafx.scene.layout.VBox; | |
import javafx.stage.Stage; | |
import java.util.concurrent.ExecutorService; | |
import java.util.concurrent.Executors; | |
/** | |
* Steps to reproduce issues: | |
* 1. Select "DEV" from first dropdown - it will run for 20s | |
* 2. Immediately select "TEST" from 2nd dropdown - it will run for 5s | |
* | |
* Expected result | |
* 1. Cursor remains WAIT until both tasks have completed | |
* 2. When both tasks have completed Cursor should remain at DEFAULT | |
* when placed over 2nd comboxbox drop down | |
* | |
* Actual result | |
* 1. Cursor changes to DEFAULT before 1st task has completed | |
* 2. (Intermittent): After both tasks have completed, clicking on 2nd combo | |
* and placing mouse pointer over dropdown list, causes cursor to change | |
* back to WAIT. | |
*/ | |
public class ComboSample extends Application { | |
public static void main(String[] args) { launch(args); } | |
private final ExecutorService pool = Executors.newFixedThreadPool(4); | |
final ObjectProperty<Cursor> CURSOR_DEFAULT = new SimpleObjectProperty<>(Cursor.DEFAULT); | |
final ObjectProperty<Cursor> CURSOR_WAIT = new SimpleObjectProperty<>(Cursor.WAIT); | |
@Override public void start(final Stage primaryStage) { | |
primaryStage.setTitle("Combo Sample"); | |
Label label1 = new Label(); | |
Label label2 = new Label(); | |
ComboBox<String> from = new ComboBox<>(); | |
from.getItems().addAll("DEV", "TEST", "PROD"); | |
from.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { | |
pool.submit(task1); | |
label1.textProperty().bind(task1.messageProperty()); | |
}); | |
ComboBox<String> to = new ComboBox<>(); | |
to.getItems().addAll("DEV", "TEST", "PROD"); | |
to.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> { | |
pool.submit(task2); | |
label2.textProperty().bind(task2.messageProperty()); | |
}); | |
HBox layout = new HBox(10); | |
layout.getChildren().addAll(new VBox(from, label1), new VBox(to, label2)); | |
primaryStage.setScene(new Scene(layout)); | |
primaryStage.setWidth(400); | |
primaryStage.setHeight(200); | |
primaryStage.show(); | |
primaryStage.getScene().cursorProperty().bind(Bindings.when(Bindings.or(task1.runningProperty(), task2.runningProperty())) | |
.then(CURSOR_WAIT).otherwise(CURSOR_DEFAULT)); | |
primaryStage.setOnCloseRequest(event -> { | |
pool.shutdownNow(); | |
}); | |
} | |
Task<Void> task1 = new Task<Void>() { | |
@Override protected Void call() throws Exception { | |
System.out.println("selectFrom - Start"); | |
for(int i=1; i<=20; i++) { | |
updateMessage(String.valueOf(i)); | |
Thread.sleep(1000); | |
} | |
System.out.println("selectFrom - End"); | |
return null; | |
} | |
}; | |
Task<Void> task2 = new Task<Void>() { | |
@Override | |
protected Void call() throws Exception { | |
System.out.println("selectTo - Start"); | |
for(int i=1; i<=5; i++) { | |
updateMessage(String.valueOf(i)); | |
Thread.sleep(1000); | |
} | |
System.out.println("selectTo - End"); | |
return null; | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for this. Note as Task is a one-shot class the selection event wont run a 2nd time - also is it possible to bind dynamically if we don't define all the tasks up front? I'm looking for a solution where I can pass any task through this Cursor.WAIT pattern.