将应用程序从JavaFX 2.2移植到JavaFX 8后,可编辑ComboBox的插入符号丢失。在选择项目时,应将ComboBox切换为可编辑。 我在Windows 8.1下使用Oracle JDK 1.8 Update 102和Update 112对其进行了测试。
当ComboBox失去焦点并重新获得焦点时,可以看到插入符号。
在将lambda更改为接口实现并删除Platform.runLater
之后,它实际上适用于JavaFX 2.2。
我加入了一个SSCCE进行测试:
import javafx.application.Application;
import javafx.application.Platform;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class TestEditableComboBox extends Application{
@Override
public void start(Stage primaryStage) throws Exception{
ComboBox<String> comboBox = new ComboBox<String>(FXCollections.observableArrayList("item 1",
"item 2",
"editable"));
comboBox.setMinWidth(100D);
comboBox.setMaxWidth(100D);
comboBox.valueProperty().addListener((observable,
oldValue,
newValue) -> {
if (newValue != null){
if ("editable".equals(newValue)){
// JavaFX 2.2: comboBox.setEditable(true);
Platform.runLater(() -> comboBox.setEditable(true));
}
else{
// JavaFX 2.2: comboBox.setEditable(true);
Platform.runLater(() -> {
comboBox.setEditable(false);
comboBox.getSelectionModel().select(newValue);
});
}
}
});
VBox vBox = new VBox(new Label("Broken caret"),
comboBox);
Scene scene = new Scene(vBox);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args){
Application.launch(args);
}
}
任何人都有想法解决这个问题吗?或者这是一个JavaFX 8回归错误?
PS:如果没有Platform.runLater
,ComboBox会抛出java.lang.IndexOutOfBoundsException
因为其模型被修改而另一个修改正在进行中。
答案 0 :(得分:0)
我没有找到比火和燃料更好的策略,但是,我将在非标准API调用周围添加一些额外的防护措施。只有在JavaFX版本为8的情况下,才尝试使用“ bodge”,并带有try catch,以最大程度地减少JavaFX未来版本失败的机会。
同样有趣的是,如果将setFakeFocus称为“ bodge”到两个ComboBoxes,则它们中的两个都有可能具有选择权。我的解决方法是在应用“凸出部分”之前先以正常方式请求焦点。
这是我在Kotlin的完整解决方案:
val javaFXVersion by lazy { System.getProperties().getProperty("javafx.runtime.version") }
fun ComboBox<*>.requestFocusWithCaret() {
requestFocus()
if (javaFXVersion.startsWith("8.")) {
try {
val theEditor = editor
if (theEditor is FakeFocusTextField) {
theEditor.setFakeFocus(true)
}
} catch (e: Exception) {
}
}
}
然后可以使用:
myComboBox.requestFocusWithCaret()