Управление фокусом с помощью метки и кнопок - Отображение нажатия клавиш в метке - PullRequest
0 голосов
/ 06 сентября 2018

Когда я использую термин неактивный узел ниже, я имею в виду то, что не должно иметь возможности взаимодействовать с пользователем.

Я построил общий экран входа в систему, подобный этому: enter image description here

Одна метка, метка ввода над цифровыми клавишами принимает как ввод с клавиатуры, так и ввод с клавиатуры. В соответствии с тем, как я это разработал, этикетка фиксирует нажатия клавиш на клавиатуре и, следовательно, должна сохранять фокусировку. От пользователя не требуется сохранять фокусировку на этом ярлыке, щелкнув по нему, чтобы он принял нажатия клавиш.

Остальные метки должны быть неактивными: заголовок «ВХОД», сообщение «Ввести номер сотрудника», а также метки даты и времени.

Все кнопки являются интерактивными: цифровые кнопки, кнопка возврата, кнопка очистки, кнопка отправки и кнопка сброса. При нажатии на эти кнопки они редактируют текст метки и возвращают к нему фокус.

Наконец, должны быть неактивные контейнеры, содержащие эти узлы.

Когда отображается этот экран, я хочу, чтобы пользователь мог вводить цифры в метку набора текста, даже если он намеренно пытается убрать фокус с метки. Я мог бы сделать каждый отдельный узел на экране node.mouseTransparent(boolean type); или node.focusTraversable(boolean type), но, похоже, должен быть лучший способ сделать это.

Каков наилучший способ записи нажатий клавиш и управления фокусом на экране, который имеет как неактивные, так и интерактивные узлы, если от пользователя не ожидается управление фокусом?

Я думал сделать что-то вроде этого:

parent.mouseTransparent(true);
interactiveChild.mouseTransparent(false);

поскольку я надеялся, что родительский код будет охватывать ассортимент неактивных дочерних элементов, но интерактивный дочерний элемент остается не кликаемым.

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Что сказал Фабиан. Вы говорите, что, пока приложение JavaFX вообще сфокусировано, вы хотите, чтобы нажатия клавиш направлялись в поле рядом с кнопкой отправки.

Вам нужен ключевой слушатель панели, которая содержит другие элементы. Вам нужны другие элементы, чтобы не отменять какие-либо события нажатия клавиш, чтобы они доходили до вас либо во время фазы всплытия, либо в фазе замедления. Вы хотите, чтобы слушатель имел прямой или косвенный (через еще один объект) доступ к полю, на котором должны появляться нажатия клавиш. Вам нужно, чтобы слушатель взял полученные им нажатия клавиш и поместил их в это поле. Вы можете сделать это вручную или направив захваченное событие нажатия клавиши на поле.

Конечно, вам также нужно проверить, чтобы убедиться, что они допустимы (цифры в вашем случае?) И какое другое поведение вы ожидаете от этого виджета.

Надеюсь, что это даст вам хороший обзор того, что написать и как достичь своей цели.

0 голосов
/ 06 сентября 2018

Вы можете просто добавить фильтр событий для KeyEvent s на уровне макета или сцены и обрабатывать события для цифровых клавиш самостоятельно:

@Override
public void start(Stage primaryStage) throws Exception {
    GridPane grid = new GridPane();

    TextField textField = new TextField();
    grid.add(textField, 0, 0, 3, 1);

    for (int i = 0; i < 9; i++) {
        Button button = new Button(Integer.toString(9 - i));
        button.setOnAction(evt -> textField.appendText(button.getText()));
        grid.add(button, i % 3, i / 3 + 1);
    }
    Button button = new Button("0");
    button.setOnAction(evt -> textField.appendText("0"));
    grid.add(button, 1, 4);

    grid.addEventFilter(KeyEvent.ANY, evt -> {
        // consume every press of a digit key and handle the release for
        // adding the text
        if (evt.getEventType() == KeyEvent.KEY_TYPED) {
            String text = evt.getCharacter();
            if (text.length() == 1 && Character.isDigit(text.charAt(0))) {
                evt.consume();
                textField.appendText(text);
            }
        } else if (evt.getCode().isDigitKey()) {
            evt.consume();
        }
    });

    Scene scene = new Scene(grid);

    primaryStage.setScene(scene);
    primaryStage.show();
}
...