2015-05-08 20 views
0

我有一個可編輯的JavaFX組合框。 用戶必須只能如何使用JavaFX KeyListeners?

  1. 類型的字母(「a」到「Z」),空間和圓形括號(「(」,「)」),以輸入的字符串
  2. 按標籤來退出
  3. 按Enter鍵退出

如何過濾掉所有其他鍵,改性劑等?

我已閱讀並使用了Key_Pressed,Key_Released等事件處理函數,但我無法找出實現上述的直接方法。 我使用的是Mac OS Yosemite,Java 8,最新版本的JavaFX和
public static final EventType<KeyEvent> KEY_TYPED根本不起作用。 下面的代碼是我的嘗試。變量typedText存儲所需的值。

comboBox.addEventHandler(KeyEvent.KEY_RELEASED, new EventHandler<KeyEvent>() { 
     private final String[] allowedItems = new String[]{"a","b","c","d","e","f", 
     "g","h","i","j","k","l","m","n","o","p","q","r", 
     "s","t","u","v","w","x","y","z"," ","(",")"}; 
     private final List data = Arrays.asList(allowedItems); 
     private String tempInput; 
     public boolean containsCaseInsensitive(String s, List<String> l){ 
      for (String string : l) { 
       if (string.equalsIgnoreCase(s)){ 
        return true; 
       } 
      } 
      return false; 
     } 
     public void handle(KeyEvent event) { 
      boolean b; 
      b = event.isShiftDown(); 
      if (b) { 
       if (event.getText().equals("(")) { 
        tempInput = "("; 
       } else if (event.getText().equals(")")){ 
        tempInput = ")"; 
       } 
      } else { 
       tempInput = event.getCode().toString().toLowerCase(); 
      } 
      System.out.println("tempInput:"+tempInput); 
      if (containsCaseInsensitive(tempInput, data)) { 
      typedText = tempInput; 
      System.out.println("typedText:"+typedText); 
      } 
     } 
    }); 
} 
+2

請分享您的成就。 – async

+1

JavaFX事件循環是雙向的,即事件消息從系統調度並滲透到您的控制中......然後從控制系統中迴流到系統。 FX爲處理事件定義的兩個抽象是「過濾器」和「處理程序」。過濾器捕獲到達控件的消息,處理程序在返回時捕獲消息。對於你的情況,你可能希望使用過濾器。否則,事件將由控件處理,然後由處理程序處理。 – scottb

+1

此外,您的代碼段不包含任何對'consume()'的調用。如果您沒有在過濾器中使用事件消息,則它將繼續傳遞給控件。當您希望定義與控件的默認行爲不同的自定義行爲時,您需要使用該事件,以便控件不會處理該事件。 – scottb

回答

1

你可以得到編輯器,它是你的案例中的TextField,並添加一個TextFormatter來限制輸入。

Tab可以直接使用,但「輸入」按鍵是另一回事,我只是在這個例子中請求重點。通常您會導航到焦點遍歷列表中的下一個項目,但在JavaFX中沒有適用於未來的api。

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.TextField; 
import javafx.scene.control.TextFormatter; 
import javafx.scene.input.KeyCode; 
import javafx.scene.input.KeyEvent; 
import javafx.scene.layout.HBox; 
import javafx.stage.Stage; 

public class ComboBoxSample extends Application { 

    @Override 
    public void start(Stage stage) { 

     ComboBox<String> comboBox = new ComboBox<>(); 
     comboBox.setEditable(true); 
     comboBox.getItems().addAll("A", "B", "C", "D", "E"); 
     comboBox.setValue("A"); 


     // restrict input 
     TextField textField = comboBox.getEditor(); 
     TextFormatter<String> formatter = new TextFormatter<String>(change -> { 
      change.setText(change.getText().replaceAll("[^a-z()]", "")); 
      return change; 

     }); 
     textField.setTextFormatter(formatter); 

     // dummy textfield to jump to on ENTER press 
     TextField dummyTextField = new TextField(); 

     comboBox.addEventFilter(KeyEvent.KEY_PRESSED, e -> { 
      if(e.getCode() == KeyCode.ENTER) { 
       dummyTextField.requestFocus(); 
       e.consume(); 
      } 
     }); 

     HBox root = new HBox(); 

     root.getChildren().addAll(comboBox, dummyTextField); 

     Scene scene = new Scene(root, 450, 250); 
     stage.setScene(scene); 
     stage.show(); 

    } 

    public static void main(String[] args) { 
     launch(args); 
    } 

}