简体   繁体   English

javafx 8,不使用 fxml,scene.lookup 找不到节点

[英]javafx 8, not using fxml, scene.lookup not finding node

In the following code, the primaryScene.lookup (line 30) returns null.在以下代码中,primaryScene.lookup(第 30 行)返回 null。 But in debug mode (IntelliJ) I can drill in and see the node in the scene graph.但是在调试模式(IntelliJ)中,我可以深入查看场景图中的节点。

This is a self-contained example.这是一个独立的例子。 No FXML.没有 FXML。

The app just draws the Stage and Scene and then tries to select the Pane that is tagged with id="drawPane" using Scene.lookup.该应用程序仅绘制舞台和场景,然后尝试使用 Scene.lookup 选择标记为 id="drawPane" 的窗格。

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ScrollPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

import static javafx.application.Application.launch;

public class Main extends Application {
    Scene primaryScene;
    Pane drawPane;

    public static void main(String[] args) {
        launch(args);

    }

    public void start(Stage primaryStage) {
        primaryScene = buildUI(primaryStage);
        if (primaryScene == null) throw new NullPointerException();

        drawPane = (Pane)primaryScene.lookup("#drawPane");
        if (drawPane == null) {
            throw new NullPointerException();
    }

    primaryStage.show();
}

private Scene buildUI(Stage primaryStage) {
    ScrollPane scrollPane;
    ImageView iv;

    BorderPane root = new BorderPane();
    Scene primaryScene = new Scene(root, 900, 800);
    initializePrimaryStage(primaryStage, primaryScene);
    initializeFrameContent(root);
    initializeContent(root);
    return primaryScene;

}

private void initializePrimaryStage(Stage primaryStage, Scene primaryScene) {
    primaryStage.setTitle("Image Clip Test");
    primaryStage.setScene(primaryScene);
    primaryStage.setWidth(400);
    primaryStage.setHeight(300);
    primaryStage.minWidthProperty().setValue(400);
    primaryStage.minHeightProperty().setValue(300);
}

private void initializeFrameContent(BorderPane root) {
    Button leftButton = new Button("LEFT");
    leftButton.setId("leftButton");
    Button rightButton = new Button("RIGHT");
    rightButton.setId("rightButton");
    Button topButton = new Button("TOP");
    rightButton.setId("topButton");

    StackPane leftPane = new StackPane(leftButton);
    leftPane.setAlignment(Pos.TOP_LEFT);

    StackPane rightPane = new StackPane(rightButton);
    rightPane.setAlignment(Pos.TOP_RIGHT);

    root.setLeft(leftPane);
    root.setTop(topButton);
    root.setRight(rightButton);
}

private void initializeContent(BorderPane root) {
    Pane drawPane = new Pane();
    drawPane.setId("drawPane");
    drawPane.setPrefSize(1000, 800);
    drawPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);

    ScrollPane scrollPane = new ScrollPane(drawPane);
    scrollPane.setPrefSize(300, 300);
    scrollPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    scrollPane.setFitToHeight(true);
    scrollPane.setFitToWidth(true);
    scrollPane.setStyle("-fx-focus-color: transparent");

    root.setCenter(scrollPane);
    }
}

Lookups do not work until CSS has been applied, which will usually not happen until the scene is laid out and rendered to the screen.在应用 CSS 之前,查找不起作用,这通常在场景布局并渲染到屏幕之前不会发生。

The following will force this to happen earlier, so you can access the lookup:以下将强制此操作更早发生,以便您可以访问查找:

public void start(Stage primaryStage) {
    primaryScene = buildUI(primaryStage);
    if (primaryScene == null) throw new NullPointerException();

    primaryScene.getRoot().applyCss();

    drawPane = (Pane)primaryScene.lookup("#drawPane");
    if (drawPane == null) {
        throw new NullPointerException();
}

Also stumbled on this situation.也偶然发现了这种情况。 The solution above did not work, by inspecting the .fxml file that was generated by the Gluon WYSIWYG noticed that there were two id fields.上述解决方案不起作用,通过检查由 Gluon WYSIWYG 生成的 .fxml 文件,注意到有两个 id 字段。

id="Content" fx:id="workpanel" id="内容" fx:id="工作面板"

All that was needed was to remove the id="Content" and then the other id worked as expected.所需要做的就是删除id="Content" ,然后另一个 id 就按预期工作了。

Strange but the call to new ScrollPane(drawPane) does not add the drawPane to the ScrollPane children list.奇怪的是,调用new ScrollPane(drawPane)并没有将 drawPane 添加到 ScrollPane 子列表中。 I tried with scrollPane.setContent(drawPane) , but it also does not work.我尝试使用scrollPane.setContent(drawPane) ,但它也不起作用。 This is why you can not look it up by the id.这就是为什么您不能通过 id 查找它的原因。 But you can lookup the drawPane by it's id after the window is displayed using following code.但是您可以在使用以下代码显示窗口后通过其 id 查找drawPane

Platform.runLater(() -> {
  drawPane = (Pane)primaryScene.lookup("#drawPane");
  if (drawPane == null) {
    throw new NullPointerException(); // this will not throw
  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM