将应用程序从 JavaFX 2.2 移植到 JavaFX 8 后,可编辑组合框的插入符号丢失。在选择项目时,组合框应切换为可编辑状态。 我在 Windows 8.1 下使用 Oracle JDK 1.8 Update 102 和 Update 112 对其进行了测试。
当 ComboBox 失去焦点并重新获得焦点时,插入符号可见。
将 lambda 更改为接口(interface)实现并删除 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
,因为它的模型在另一个修改正在进行时被修改。
最佳答案
我找到了解决此问题的方法。
类com.sun.javafx.scene.control.skin.ComboBoxPopupControl
中ComboBox的内部实现有一个专门的类叫做 FakeFocusTextField
延伸javafx.scene.control.TextField
。调用 ComboBox::getEditor
时会返回此类的实例。 .
令人惊讶的是FakeFocusTextField
类有一个名为 setFakeFocus
的公共(public)方法这将焦点集中到文本字段。 requestFocus
此类中的方法将焦点赋予其父级。
解决方法是更改将组合框设置为可编辑的代码行:
Platform.runLater(() -> comboBox.setEditable(true));
至
Platform.runLater(() -> {
comboBox.setEditable(true);
if (this.getEditor() instanceof FakeFocusTextField){
((FakeFocusTextField) this.getEditor()).setFakeFocus(true);
}
}
不幸的是,此解决方法使用 JavaFX 8 API 之外的 JavaFX 类。如果实现发生更改,它可能会中断,并且可能无法在未来的版本(如 Java 9)中工作。
关于JavaFX 8 : Missing caret in switch-editable ComboBox,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40239400/