Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 文本字段中的RequestFocus不';行不通_Java_Javafx 2_Fxml - Fatal编程技术网

Java 文本字段中的RequestFocus不';行不通

Java 文本字段中的RequestFocus不';行不通,java,javafx-2,fxml,Java,Javafx 2,Fxml,我使用JavaFX2.1,并使用FXML创建GUI,在这个GUI的控制器中添加了myTextField.requestFocus() 但是我总是在另一个控件中获得焦点。在initialize()时,控件尚未准备好处理焦点 您可以尝试下一个技巧: @Override public void initialize(URL url, ResourceBundle rb) { Platform.runLater(new Runnable() { @Override

我使用JavaFX2.1,并使用FXML创建GUI,在这个GUI的控制器中添加了
myTextField.requestFocus()


但是我总是在另一个控件中获得焦点。

initialize()时,
控件尚未准备好处理焦点

您可以尝试下一个技巧:

@Override
public void initialize(URL url, ResourceBundle rb) {
    Platform.runLater(new Runnable() {
        @Override
        public void run() {
            tf.requestFocus();
        }
    });
}
对于棘手的复杂应用程序(如Pavel_K在注释中所述),您可能希望重复此例程几次,然后调用下一个方法行:

private void repeatFocus(Node node) {
    Platform.runLater(() -> {
        if (!node.isFocused()) {
            node.requestFocus();
            repeatFocus(node);
        }
    });
}
请注意,这是一种没有文档记录的方法,如果在将来的Java版本中发生了更改或中断,那么最好为重复添加一个限制,以避免无休止的循环。失去焦点比整个应用程序更好。:)


具有所述阈值的示例:

@覆盖
public void requestFocus(){
requestFocus(getNode(),3);
}
私有void requestFocus(最终节点,最终int max){
如果(最大值>0){
朗莱特(
() -> {
如果(!node.isFocused()){
requestFocus();
请求焦点(节点,最大值-1);
}
}
);
}
}
如果您请求Focus()初始化场景后,它将工作

像这样:

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();

我希望这有帮助。:)

答案与@Sergey Grinev完全相同。确保您的java版本是最新的(JDK1.8或更高版本)


当尚未设置节点的场景属性时,可能会发生这种情况。 唉,设置场景属性可能需要“很长”的时间

第一次创建场景时,以及将项目添加到某些父节点(例如TabPane)时,子节点的“场景”属性会滞后(奇怪的是,有些父节点似乎免疫,我不知道为什么)

正确的策略一直对我有效:

if (myNode.scene) == null {
    // listen for the changes to the node's scene property,
    // and request focus when it is set
} else {
    myNode.requestFocus()
}
我有一个方便的Kotlin扩展函数来实现这一点

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()
    }
}

也许有人想把它翻译成Java。

我在使用JavaFX11时遇到了同样的问题,并用nickthecoder提出的类似方法解决了它

ChangeListener<Scene> sceneListener = new ChangeListener<Scene>() {
    @Override
    public void changed(ObservableValue<? extends Scene> observable, Scene oldValue, Scene newValue) {
        if (newValue != null) {
            editInput.requestFocus();
            editInput.sceneProperty().removeListener(this);
        }
    }
};
editInput.sceneProperty().addListener(sceneListener);
ChangeListener sceneListener=new ChangeListener(){
@凌驾

public void changed(observevalue较旧的答案解释了
Platform.runLater
不工作的情况,但此答案也涵盖了多个节点上的多个请求的情况

问题是:
scene
属性对于节点变为非null的顺序,以及由此调用添加的侦听器的顺序,不一定与添加两个侦听器的顺序相同。因此,此顺序:

requestFocusOnSceneAvailable(node1)
requestFocusOnSceneAvailable(node2)
node2.requestFocus()
node1.requestFocus()
可能意外地导致以下顺序:

requestFocusOnSceneAvailable(node1)
requestFocusOnSceneAvailable(node2)
node2.requestFocus()
node1.requestFocus()
解决方案要求侦听器仅在最近的节点上调用
requestFocus()
,可以使用静态变量跟踪该节点:

private static Node nodeToRequestFocusOnOnceSceneAvailable;

public static void requestFocusOnceSceneAvailable(Node node) {
    
    // Remember this node as the latest node requested to receive focus.
    nodeToRequestFocusOnOnceSceneAvailable = node;
    
    // Schedule the focus request to happen whenever
    // JavaFX finally adds the node to the scene.
    Listeners.addAndFire(node.sceneProperty(), new ChangeListener<Scene>() {
        @Override
        public void changed(ObservableValue<? extends Scene> observable, Scene oldScene, Scene newScene) {
            if (newScene != null) {
                if (node == nodeToRequestFocusOnOnceSceneAvailable) {
                    node.requestFocus();
                    
                    // We no longer need to remember this node,
                    // since its focus has been requested.
                    nodeToRequestFocusOnOnceSceneAvailable = null;
                }
                
                // We no longer need the listener
                // after it has run once.
                observable.removeListener(this);
            }
        }
    });
}
私有静态节点NodeToRequestFocusOnceSceneAvailable;
公共静态void requestFocusOnceSceneAvailable(节点){
//记住此节点是请求接收焦点的最新节点。
NodeToRequestFocusOnceSceneAvailable=节点;
//安排焦点请求在任何时候发生
//JavaFX最终将节点添加到场景中。
addAndFire(node.sceneProperty(),new ChangeListener()){
@凌驾

更改公众假期(Observalevalue)我有一个相关的问题,我的
TextArea
拒绝以编程方式获取焦点,即使该阶段可见且处于活动状态,并且当前正在运行的线程是JavaFX应用程序线程。但是如果我按照示例将一个新的
Runnable
排队,它就工作了。真奇怪,我对此没有任何解释。Th似乎不再适用于JavaFX 8。
tf==null
initialize
运行时仍然为真。@skiwi,这意味着FXML中存在错误:检查@FXML注释,“fx:id”标记以及两者中变量的拼写。所有@FXML ed控件在
initialize()处都不应为null
time。否则,
initialize()有什么意义
方法?此解决方案在10%的情况下有效,90%的情况下无效。我是说相同的代码,相同的程序。是否有其他方法可以检测文本字段何时准备好请求焦点?@Pavel_K 100%适用于我。如果您有特定的情况,最好在单独的问题中显示。另一个选项可以是codepleb的答案——它应该在没有任何计时技巧的情况下工作。