如何从 JavaFX 中的 SceneBuilder 访问 UI 组件

How to access UI components from SceneBuilder in JavaFX

(重复并已解决 - 请参阅下面的答案)

我正在尝试使用 JavaFX,但似乎很难使用 "SceneBuilder"。我习惯了 Android 和 QtCreator。在我看来,访问 UI 组件要容易得多。

类似于 findViewById(R.id.btnPushMe); <- Android 代码

其实我有一个解决方案,但是用起来很不舒服。这看起来像这样:

FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("../fmxl/main.fxml"));

AnchorPane pane = loader.load();
System.out.println("panechilds:" + pane.getChildren().size());

BorderPane border = (BorderPane) pane.getChildren().get(0);
System.out.println("borderchilds:" + border.getChildren().size());

xml..

<AnchorPane fx:id="mAnchor" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0"
            xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.progui.MainController">
    <children>
        <BorderPane layoutX="-1.0" prefHeight="600.0" prefWidth="800.0">
            <top>

               ...

提前致谢 马丁

编辑:

这是一个重复的问题(但我不会删除它,因为我花了一些时间来找到答案 - 可能是因为 JavaFX 没有被问到 Android 个问题那么多..)

AnchorPane anchor = (AnchorPane) scene.lookup("#mAnchor");

在此处找到:How to find an element with an ID in JavaFX?

当您针对 FXML 进行设计时,通常会设计三样东西:应用程序逻辑、GUI 控制器逻辑和 FXML。

对您希望访问的 UI 控件的引用在其加载和初始化期间由 FXML 加载程序注入到您的控制器 class 中,因此您不需要使用 FindById() 方法.

控制器 class 看起来类似于:

class DCServRecEditor extends DialogController {


@FXML // ResourceBundle that was given to the FXMLLoader
private ResourceBundle resources;

@FXML // URL location of the FXML file that was given to the FXMLLoader
private URL location;

@FXML // fx:id="ancMatchSelector"
private AnchorPane ancMatchSelector; // Value injected by FXMLLoader

@FXML // fx:id="ancServEditor"
private AnchorPane ancServEditor; // Value injected by FXMLLoader

@FXML // fx:id="ancServRecEditor"
private AnchorPane ancServRecEditor; // Value injected by FXMLLoader
:
:

FXML 加载工具自动将引用注入到用 @FXML 标记注释的实例字段中。要操作 UI 控件,只需使用适当的引用访问其方法。

将 UI 控制逻辑与您的应用程序逻辑分开是非常可取的,并且效果 "separation of concerns"。当您习惯以这种方式设计 FXML UI 时,您会喜欢上它的。

您应该使用 controller class 并访问那里的 UI 元素。

基本上你会:

<AnchorPane fx:id="mAnchor" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="800.0"
            xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="app.progui.MainController">
    <children>
        <BorderPane fx:id="border" layoutX="-1.0" prefHeight="600.0" prefWidth="800.0">
            <top>

               ...

然后您可以使用

访问控制器中的 fx:id 属性元素
package app.progui ;

// ...

public class MainController {

    @FXML
    private BorderPane border ;


    public void initialize() {
        border.setStyle("-fx-background-color: antiquewhite;");
        // ...
    }

    // ...
}

控制器 class 中的字段名称必须与 FXML 文件中的 fx:id 值匹配。

可以访问调用 FXMLLoader 的 class 中的 fx:id 属性元素,但如果您需要这样做,通常表明您的整体设计是错误的。你可以这样做:

FXMLLoader loader = new FXMLLoader(MainApp.class.getResource("../fmxl/main.fxml"));

AnchorPane pane = loader.load();
Map<String, Object> fxmlNamespace = loader.getNamespace();
BorderPane border = (BorderPane) fxmlNamespace.get("border");

假设 fx:id 在上面截取的 FXML 中定义。