2016-10-25 34 views
0

將應用程序從JavaFX 2.2移植到JavaFX 8後,缺少可編輯ComboBox的插入符號。在選擇項目時應將ComboBox切換爲可編輯。 我使用Oracle JDK 1.8 Update 102和Update 112在Windows 8.1下對其進行了測試。JavaFX 8:在可切換的編輯框中缺少插入符號ComboBox

當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迴歸bug?

PS:如果沒有Platform.runLater,ComboBox會拋出java.lang.IndexOutOfBoundsException,因爲在修改模型的同時正在進行其他修改。

回答

0

我找到了解決此問題的解決方法。

組合框上的組合框的內部實現有一個稱爲FakeFocusTextField的專用類,該類擴展了javafx.scene.control.TextField。撥打ComboBox::getEditor時會返回此類的一個實例。

令人驚訝的是,FakeFocusTextField類有一個名爲setFakeFocus的公共方法,它將焦點放在文本字段上。該類中的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)。