-1

When I use the term inactive node below, what I mean is something that should not be able to interact with the user.

I built a general login screen similar to this: enter image description here

One label, the typing label above the number keys takes both button input as well as keyboard input. With the way I have designed it up to this point, the label captures key presses from the keyboard and thus must maintain focus. The user is not expected to maintain focus in this label by clicking on it to get it to accept key presses.

The rest of the labels should be inactive: The "LOGIN" title, the "Enter Employee Number" message, and the date and time labels.

The buttons are all interactive: the number buttons, the back button, the clear button, the submit button, and the reset button. When these buttons are clicked, they edit the typing label text and pass focus back to it.

Lastly, there should be inactive containers holding these nodes.

When this screen is displayed, I want the user to be able to type numbers into the typing label even if they are intentionally trying to remove focus from the label. I could make every individual node on the screen node.mouseTransparent(boolean type); or node.focusTraversable(boolean type), but it seems like there should be a better way to do it.

What is the best way to record key presses and manage focus in a screen that has both inactive and interactive nodes if the user is not expected to manage focus?

I thought to do something like this:

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

as I was hoping that the parent code would cover for the assortment of inactive children but the interactive child remains unclickable.

Jack J
  • 1,514
  • 3
  • 20
  • 28
  • 1
    you would better add some code snippets to help us understand your problem that first for second why you need to set the mouse transparent ? the user can change focus using the Tab button on the keyboard anyway you can force the focus to the typing label text whenever you click a button on your screen or the keyboard if this helps you I can provide some code to help – Ahmed Emad Sep 06 '18 at 07:51
  • Please provide a [mcve] that demonstrates the problem. – kleopatra Sep 11 '18 at 11:27

2 Answers2

2

You could simply add an event filter for KeyEvents at the layout level or scene level and handle events for digit keys yourself:

@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();
}
fabian
  • 80,457
  • 12
  • 86
  • 114
1

What fabian said. What you're saying is, as long as the JavaFX app has focus at all, you want the keystrokes to be directed into the field next to the submit button.

You need a key listener to the Pane which contains the other elements. You need the other elements to not cancel any keystroke events so they reach you either during the bubble up phase or the trickle down phase. You need the listener to have direct or indirect (through yet another object) access to the field upon which the keystrokes are to appear. You need the listener to take the keystrokes it receives and place them into that field. You cna do that manually or by directing the captured keystroke event to the field.

Of course you also need to check to make sure they're legal (numbers in your case?) and whatever other behavior you expect this widget to have.

Hope that gives you an good overview of what to write and how to achieve your goal.

  • thanks for trying to be helpful :) just a couple of comments how you could improve your answering skills, in no particular order: a) don't repeat other answers (in particular not by paraphrasing the solution in words when it was given in code) b) use proper terminology (f.i. it's "consume" an event not "cancel", or "capturing phase" not "trickle down") – kleopatra Sep 11 '18 at 11:33