#javafx-8
#javafx-8
Вопрос:
У меня есть графический интерфейс JavaFX, в котором я хочу перехватить нажатие пробела и использовать его для вызова метода. Я написал eventFilter, который, кажется, делает свое дело. Он включает в себя команду event.consume(), которая, как я полагаю, должна препятствовать распространению KeyEvent на различные элементы управления.
Моя проблема в том, что когда я добавил текстовое поле, и это поле имеет фокус, нажатия пробела не используются, как я думал. » » захватываются текстовым полем. Я хотел бы перехватить и предотвратить добавление » » в текстовое поле.
Что я оставляю в приведенном ниже коде, чтобы не допустить попадания » » в текстовое поле? API, если я правильно его читаю, говорит, что фильтры, зарегистрированные в родительском элементе управления, могут перехватывать событие до того, как оно достигнет дочерних узлов. Но даже при установке фильтра непосредственно в текстовое поле у меня все еще появляются символы » » в текстовом поле.
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();
}
}
}
Ответ №1:
Вероятно, текстовое поле прослушивает KEY_TYPED
события. Как хорошо документировано, 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();
}
}
}
Ответ №2:
Я могу придумать простое решение, которое, хотя и не блокирует добавление пробела в TextField
, но заменяет его после того, как оно было добавлено почти мгновенно, — это добавление a changeListener
TextProperty
в TextField
:
textField.textProperty().addListener((observable,oldValue,newValue)->{
textField.setText(textField.getText().replace(" ", ""));
});
Это также может быть полезно http://fxexperience.com/2012/02/restricting-input-on-a-textfield /
Комментарии:
1. @James_D почти не видел этого. Спасибо, в любом случае я отредактировал ответ, и он работает, даже если
SPACE
он находится между существующим текстом. Хотя это всего лишь предположение, нужно ли это OP.2. Я нашел этот ответ полезным. Мои первые попытки заменить содержимое текстового поля не сработали, поэтому приятно видеть, как вы это сделали. Ответ James_D был выбран, поскольку он устраняет необходимость редактирования поля.
3. @Phil Freihofner И так и должно быть. Я также не знал решения, которое James_D добавил в свой ответ 😉