2016-10-12 3 views
1

У меня есть графический интерфейс JavaFX, где я хочу перехватить нажатие SpaceBar и использовать его для вызова метода. Я написал EventFilter, который, кажется, делает трюк. Он включает в себя команду event.consume(), которая, как я полагаю, должна содержать KeyEvent от распространения на различные элементы управления.EventFilter потребляет() не мешает SpaceChars в TextField

Моя проблема заключается в том, что когда я добавил TextField, и это поле имеет фокус, пресса пробела не потребляется, как я думал. «» Захватываются TextField. Я хотел бы перехватить и предотвратить добавление «» в TextField.

Что я оставляю в приведенном ниже коде, чтобы «добраться до TextField»? Api, если я читаю его правильно, говорит, что фильтры, зарегистрированные в родительском элементе управления, могут перехватывать событие до того, как он достигнет дочерних узлов. Но даже при установке фильтра непосредственно на TextField у меня все еще есть «" символы в TextField.

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.input.KeyCode; 

import javafx.scene.input.KeyEvent; 

import javafx.stage.Stage; 


public class SpaceIntercept extends Application implements EventHandler <KeyEvent> 
{ 
    public static void main(String[] args) 
    { 
     Application.launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) 
    { 
     TextField textField = new TextField("asdf"); 
     Group root = new Group(); 
     Scene scene = new Scene(root, 200, 100); 
     scene.addEventFilter(KeyEvent.ANY, event -> handle(event));   
     // root.addEventFilter(KeyEvent.ANY, event -> handle(event)); 
     // textField.addEventFilter(KeyEvent.ANY, event -> handle(event)); 
     root.getChildren().add(textField); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    @Override 
    public void handle(KeyEvent event) 
    { 
     if (event.getCode() == KeyCode.SPACE) 
     { 
      if (event.getEventType() == KeyEvent.KEY_PRESSED) 
      { 
       System.out.println("Code that responds to SpaceBar"); 
      } 
      event.consume(); 
     } 
    }  
} 

ответ

2

текстовое поле, вероятно, прослушивание KEY_TYPED событий. Как есть well-documented, getCode() возвращает KeyCode.UNDEFINED за KEY_TYPED событие. Таким образом, вы не поймаете этот случай.

Вы можете проверить для character переменной, а также переменной code обрабатывать все случаи:

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.TextField; 
import javafx.scene.input.KeyCode; 

import javafx.scene.input.KeyEvent; 

import javafx.stage.Stage; 


public class SpaceIntercept extends Application implements EventHandler <KeyEvent> 
{ 
    public static void main(String[] args) 
    { 
     Application.launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) 
    { 
     TextField textField = new TextField("asdf"); 
     Group root = new Group(); 
     Scene scene = new Scene(root, 200, 100); 
     scene.addEventFilter(KeyEvent.ANY, event -> handle(event));   
     // root.addEventFilter(KeyEvent.ANY, event -> handle(event)); 
     // textField.addEventFilter(KeyEvent.ANY, event -> handle(event)); 
     root.getChildren().add(textField); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    @Override 
    public void handle(KeyEvent event) 
    { 
     if (event.getCode() == KeyCode.SPACE || " ".equals(event.getCharacter())) 
     { 
      if (event.getEventType() == KeyEvent.KEY_PRESSED) 
      { 
       System.out.println("Code that responds to SpaceBar"); 
      } 
      event.consume(); 
     } 
    }  
} 
1

Простое решение я могу думать, что, хотя не блокирует пространство от добавления в TextField, но он заменяет его после того, как он был добавлен почти мгновенно добавляет changeListener к TextProperty из TextField :

textField.textProperty().addListener((observable,oldValue,newValue)->{ 
    textField.setText(textField.getText().replace(" ", "")); 
}); 

Это также может быть полезным http://fxexperience.com/2012/02/restricting-input-on-a-textfield/

+0

@James_D Почти не видел it.Thanks, во всяком случае я редактировал ответ, и он работает, даже если 'ПРОСТРАНСТВО 'находится между существующим текстом. Хотя это просто догадка, нуждается ли OP. – GOXR3PLUS

+0

Я нашел этот ответ полезным. Мои первые попытки заменить содержимое TextField не помогли, так что хорошо видеть, как вы это сделали. Ответ James_D был выбран потому, что он устраняет необходимость редактировать поле. –

+0

@Phil Freihofner И вот как это должно быть. Я также не знал решения, которое James_D добавил в его ответе;) – GOXR3PLUS