2015-05-08 2 views
0

У меня есть редактируемый JavaFX ComboBox. пользователь должен только быть в состоянииКак использовать JavaFX KeyListeners?

  1. алфавитов типа («а» до «Z»), пространства и круглые скобки («(», «)»), чтобы ввести строку,
  2. нажмите вкладку, чтобы выйти
  3. нажмите клавишу ВВОД, чтобы выйти из

Как отфильтровать любой другой ключ, модификаторы и т.д.?

Я прочитал и использовал обработчики событий, такие как 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

Кроме того, ваш сегмент кода не содержит вызовов 'потреблять()'. Если вы не потребляете сообщение о событии в своем фильтре, оно будет продолжать передаваться элементу управления. Если вы хотите определить пользовательские поведения, отличные от поведения элемента управления по умолчанию, вам нужно будет использовать событие, чтобы элемент управления не обрабатывал событие. – scottb

ответ

1

Вы можете получить редактор, который является TextField в вашем случае, и добавить к нему TextFormatter, который ограничивает вход.

Вкладка работает из коробки, но клавиша «enter» - это другое дело, я просто запрашиваю фокус в этом примере. Обычно вы переходите к следующему элементу в списке обхода фокуса, но для 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); 
    } 

} 
Смежные вопросы