问题
I use JavaFX 2.1 and I created GUI using FXML, in the controller of this GUI I added myTextField.requestFocus();
.
But I always get the focus in the other control.
回答1:
At the time of initialize()
controls are not yet ready to handle focus.
You can try next trick:
@Override
public void initialize(URL url, ResourceBundle rb) {
Platform.runLater(new Runnable() {
@Override
public void run() {
tf.requestFocus();
}
});
}
For tricky complex applications (like Pavel_K has in the comments) you may want to repeat this routine several times and call method line next one:
private void repeatFocus(Node node) {
Platform.runLater(() -> {
if (!node.isFocused()) {
node.requestFocus();
repeatFocus(node);
}
});
}
Note this is undocumented approach and it may be wise to add a limit for repetitions to avoid endless loop if something changed or broke in future Java releases. Better to lose focus than a whole app. :)
回答2:
The exact same answer as @Sergey Grinev. Make sure your version of java is up-to-date (JDK 1.8 or later).
Platform.runLater(()->myTextField.requestFocus());
回答3:
If you requestFocus(); AFTER initializing the scene, it will work!
Like this:
Stage stage = new Stage();
GridPane grid = new GridPane();
//... add buttons&stuff to pane
Scene scene = new Scene(grid, 800, 600);
TEXTFIELD.requestFocus();
stage.setScene(scene);
stage.show();
I hope this helps. :)
回答4:
This can occur when the Scene property for the Node is not yet set. Alas, the scene property can take a "long" time to be set.
The child node's scene property lags when a scene is first created, and also, when items are added to some parents, such as a TabPane (oddly some parents seem immune, I'm not sure why).
The correct strategy, which has always worked for me :
if (myNode.scene) == null {
// listen for the changes to the node's scene property,
// and request focus when it is set
} else {
myNode.requestFocus()
}
I have a handy Kotlin extension function which does this.
fun Node.requestFocusOnSceneAvailable() {
if (scene == null) {
val listener = object : ChangeListener<Scene> {
override fun changed(observable: ObservableValue<out Scene>?, oldValue: Scene?, newValue: Scene?) {
if (newValue != null) {
sceneProperty().removeListener(this)
requestFocus()
}
}
}
sceneProperty().addListener(listener)
} else {
requestFocus()
}
}
You can then call it from within you code like so :
myNode.requestFocusOnSceneAvailable()
Perhaps somebody would like to translate it to Java.
来源:https://stackoverflow.com/questions/12744542/requestfocus-in-textfield-doesnt-work