22

I wrote an application with JavaFX which will only be usable with keyboard's arrows. So I prevented MouseEvent on Scene's stage, and I "listen" to KeyEvents. I also switched off focusability of all nodes :

for(Node n : children) {
     n.setFocusTraversable(false);

Now I have some textfields, checkboxes, and buttons. I would like to change the state of my input controls (textfield, checkbox,..) programatically: for example I would like to enter the textfield to edit the content programatically. So my question is: how to enter in a non-focus-traversable textfield? Because textfield.requestFocus(); doesn't work anymore since I set false to focustraversable property of my textfield.

Thanks

Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
PacDroid
  • 541
  • 1
  • 7
  • 22
  • If you want to programmatically set the value of a textfield, you could simply use `setText`? If I have misunderstood your question, could you please rephrase what the problem is, what you have tried, and what doesn't work? – Knut Arne Vedaa Nov 18 '13 at 14:07
  • I edited my question and added that I did – PacDroid Nov 18 '13 at 14:51
  • @PacDroid you said requestFocus() is working in the comment of my answer below. Also I edited my answer with more details as per your comment. You need to clarify this confusion. – Uluk Biy Nov 18 '13 at 15:41
  • Yes, it's ok by requesting focus in a separate thread, thank you :) – PacDroid Nov 18 '13 at 18:50

2 Answers2

55

By the following code:

n.setFocusTraversable(false);

...the node is made non-focus-traversable instead of non-focusable. It can still be focused for example by mouse or programmatically. Since you prevented mouse events, here the other option:

Platform.runLater(() -> textfield.requestFocus());

Scene scene = new Scene(root);

EDIT: as per comment,
The Javadoc of requestFocus states:

... To be eligible to receive the focus, the node must be part of a scene, it and all of its ancestors must be visible, and it must not be disabled. ...

So this method should be called after construction of scene graph as follow:

Scene scene = new Scene(root);
textfield.requestFocus();

However, Platform.runLater in the above will run at the end, after the main method start(), which ensures the call of requestFocus will be after scene graph cosntruction.

There maybe other reasons depending on the requestFocus implementation code.

Lii
  • 11,553
  • 8
  • 64
  • 88
Uluk Biy
  • 48,655
  • 13
  • 146
  • 153
  • Ok, I tested it worked. Why doesn't it work with a simple textfield.requestFocus(); at the end of my parent-Pane construction? – PacDroid Nov 18 '13 at 14:32
  • 1
    Thank you it's clearer now for me :) I think that I will create my own controls that can only be focused by a method that change their visual states. Thank you – PacDroid Nov 18 '13 at 15:40
  • What will be the component who get's the focus per default? Is it the first created component, like a Button? – stephanmg Feb 24 '20 at 21:27
2

set the .requestFocus(); on initialize method to fire on .fxml file loading controller

@Override
public void initialize(URL url, ResourceBundle rb) {
/* the field defined on .fxml document  
@FXML
private TextField txtYear;
*/
txtYear.requestFocus();
}
Ravinath
  • 1,620
  • 1
  • 14
  • 8