Рассмотрите следующий MCVE. Конечно, функциональность этого MCVE совершенно бессмысленна, но мне нужно, чтобы он работал таким образом в реальной реализации.Stage.show() изменяет значение ComboBox
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
@SuppressWarnings("all")
public class MCVE extends Application {
private static final String OPTION_1 = "Option 1 (www.option1.com)";
private static final String OPTION_2 = "Option 2 (www.option2.com)";
private static final String OPTION_3 = "Option 3 (www.option3.com)";
private static final String OPTION_4 = "Option 4 (www.option4.com)";
private static final String OPTION_5 = "Option 5 (www.option5.com)";
ComboBox<String> cb;
@Override
public void start(Stage primaryStage) throws Exception {
VBox outer = new VBox();
cb = new ComboBox<String>();
outer.getChildren().add(cb);
Scene scene = new Scene(outer, 640, 480);
primaryStage.setScene(scene);
Task<Void> task = new Task<Void>() {
@Override
public Void call() {
cb.getItems().addAll(OPTION_1, OPTION_2, OPTION_3, OPTION_4, OPTION_5);
cb.setEditable(true);
// Adds a listener to the selectedItemProperty that gets the
// value inside the parenthesis of the selected item and sets
// this as the text of the ComboBox.
cb.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
String[] valSplit = newValue.split("[\\(\\)]");
if (valSplit.length > 1) {
Platform.runLater(() -> cb.getEditor().setText(valSplit[1]));
}
});
cb.getEditor().textProperty().addListener((obs, oldValue, newValue) -> {
System.out.println("CB value: " + newValue);
});
setURL("www.option2.com");
return null;
}
};
task.setOnSucceeded(e -> {
primaryStage.show();
});
new Thread(task).start();
}
public void setURL(String url) {
// First we check if the classValue is the URL of one of the options in
// the ComboBox. If it is we select that option.
for (String option : cb.getItems()) {
// We retrieve the URL of the option.
String opURL = option.split("[\\(\\)]")[1];
// If the URL of the option is equals to the provided URL, we select
// this option and break the for loop.
if (opURL.equals(url)) {
cb.getSelectionModel().select(option);
break;
}
}
}
public static void main(String[] args) {
launch(args);
}
}
Поскольку я призываю setURL("www.option2.com")
, я ожидаю, что сначала выбрать опцию в ComboBox
с этим URL, а затем получить значение внутри скобок и установить, что в тексте ComboBox
. Поэтому я исключаю окончательное значение ComboBox
как «www.option2.com». Но этого не происходит. Вместо этого конечным значением является «Вариант 2 (www.option2.com)».
Поскольку я добавил слушателя в textProperty
из ComboBox
, я вижу, что это значение является первым ожидаемым «www.option2.com», но затем возвращается к «Варианту 2 (www.option2.com) ». После некоторого дальнейшего исследования я обнаружил, что это вызов primaryStage.show()
, который изменяет значение. Более конкретно, это вызов устаревшего Parent.impl_processCSS
, который изменяет значение.
Так что, если я установил URL-адрес после primaryStage.show()
, все работает как я, кроме. Но если я хочу выполнить всю работу до того, как я покажу диалог, как и сейчас, это не так.
Так почему же primaryStage.show()
измените значение моего ComboBox
и как я могу предотвратить это? Должен ли я использовать другой подход при попытке установить значение ComboBox
?