JavaFX,通过 Id 查找节点

标签 java javafx

我最近遇到了问题,我需要从我的窗口中使用的节点获取特定节点(最好是通过 id)。我正在使用 FXMLLoader,所以第一个想法是搜索 FXMLLoader 返回的树结构。

root|  
    |                
    |--some_container |- child1   
    |                 |- child2
    |      
    |--other_container |-child3
    ...

进一步的研究使我在 Scene 类中找到了方法 lookup ,但官方文档 ( https://docs.oracle.com/javase/8/javafx/api/javafx/scene/Scene.html#lookup-java.lang.String- ) 缺乏对这种方法工作原理的描述,在我看来是不准确的(我费了很大力气才让事情顺利进行)。

如此处所述 ( How to find an element with an ID in JavaFX? ) 方法 lookup 的调用必须在 方法 show 之后,为什么?

第二个问题是为什么节点 id 必须以“#”(井号)开头?而官方文件说明它应该是“...CSS选择器...”? (我在这里有点困惑,因为 Node 类只包含一个类似 id 的属性)

Edi1 - @kleopatra 的简单示例 尽管严格来说问题不在于代码,而在于理解。

具有场景内容的示例 fxml 文件:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.canvas.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/11.0.2" xmlns:fx="http://javafx.com/fxml/1" fx:controller="display.windows.ConsoleForBoard">
   <children>
      <SplitPane fx:id="mainSplitPane" dividerPositions="0.7" layoutX="277.0" layoutY="100.0" prefHeight="160.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
        <items>
          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="398.0" prefWidth="404.0">
               <children>
                  <SplitPane dividerPositions="0.8" layoutX="150.0" layoutY="53.0" orientation="VERTICAL" prefHeight="200.0" prefWidth="160.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
                    <items>
                      <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
                           <children>
                              <Canvas fx:id="drawBoard" height="313.0" layoutX="125.0" layoutY="43.0" width="413.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                           </children>
                        </AnchorPane>
                      <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
                           <children>
                              <TextArea layoutX="107.0" layoutY="-86.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
                           </children>
                        </AnchorPane>
                    </items>
                  </SplitPane>
               </children>
            </AnchorPane>
          <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
               <children>
                  <ToggleButton layoutX="35.0" layoutY="62.0" mnemonicParsing="false" text="ToggleButton" />
                  <TextField alignment="CENTER" layoutX="2.0" layoutY="14.0" promptText="Main Menu" text="Main Menu" />
               </children>
            </AnchorPane>
        </items>
      </SplitPane>
   </children>
</AnchorPane>

注意: Canvas 有 fx:id="drawBoard"

创建此场景的示例类:

public class BoardWithMenu extends Application {
    Scene mainScene;
    AnchorPane root;
    FXMLLoader loader;

    public static void start() {launch("start");}
    @Override
    public void start(Stage stage) throws Exception {
        loader = new FXMLLoader(this.getClass().getResource("scene_definition.fxml"));
        root = loader.load();
        mainScene = new Scene(root, 500, 500);

        stage.setScene(mainScene);
        stage.setTitle("Space map");
        stage.show();

        Canvas board = (Canvas) mainScene.lookup("drawBoard");
        System.out.println(board.getId());
    }
}  

问题:

线 Canvas 板 = (Canvas) mainScene.lookup("#drawBoard"); 之前不能调用 stage.show(); 它会产生空指针错误。为什么?

最佳答案

您引用的评论:

As mentioned here (How to find an element with an ID in JavaFX?) invocation of method lookup must be after method show?

作为一般性陈述是错误的。加载后是否可以立即查找节点取决于它是如何添加的:

  • 作为子节点注入(inject)的所有节点在加载器之后直接可用(例如“#mainSplitPane”作为根节点的子节点)
  • 所有由皮肤插入的节点仅在附加皮肤后可用,即在显示后(例如注入(inject)到 splitPane 的项目的“#drawBoard”)

关于JavaFX,通过 Id 查找节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68475291/

相关文章:

JavaFX HTML 节点元素

Java 在 jar 中使用代理设置

java - 在 Java 中查找给定有序子序列的超序列

java - Android Matrix 如何使用指定的点进行 postRotate?

java - 获取整个文档innerhtml

java - 尝试将本地页面加载到 JavaFX webEngine

java - 简单的 TestFX 示例失败

java - GSON 不返回 JSON key

java - 谷歌探戈/opencv Android 相机应用程序崩溃/挂起

apache-flex - Flash、Flex、Adobe Air、Java FX 和 Silverlight 的这些业务是什么?