简体   繁体   English

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

[英]How to access UI components from SceneBuilder in JavaFX

(DUPLICATE & SOLVED - see answer below) (重复和解决 - 见下面的答案)

I'm doing my first steps in JavaFX and it seems quite hard to use the "SceneBuilder". 我正在JavaFX中完成我的第一步,似乎很难使用“SceneBuilder”。 I'm used to Android and the QtCreator. 我已经习惯了Android和QtCreator。 It looks to me that there is accessing the UI components much easier. 在我看来,访问UI组件更容易。

Something like findViewById(R.id.btnPushMe); findViewById(R.id.btnPushMe); <- Android Code < - Android代码

Actually I got an solution but it is quite uncomfortable to use. 实际上我得到了一个解决方案,但使用起来非常不舒服。 This looks as this: 这看起来像这样:

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

the xml.. 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>

               ...

Thanks in advance Martin 在此先感谢马丁

Edit: 编辑:

This is a duplicate question (but I will not delete it, because I took some time to find the answer - maybe because JavaFX wasn't asked as much as Android questions were..) 这是一个重复的问题(但我不会删除它,因为我花了一些时间来找到答案 - 也许是因为JavaFX没有像Android问题那样被问到......)

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

found here: How to find an element with an ID in JavaFX? 在这里找到: 如何在JavaFX中找到带有ID的元素?

You should use a controller class and access the UI elements there. 您应该使用控制器类并访问那里的UI元素。

Basically you do: 基本上你做:

<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>

               ...

And then you can access the fx:id -attributed elements in the controller with 然后你可以访问控制器中的fx:id -attributed元素

package app.progui ;

// ...

public class MainController {

    @FXML
    private BorderPane border ;


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

    // ...
}

The field names in the controller class must match the fx:id values in the FXML file. 控制器类中的字段名称必须与FXML文件中的fx:id值匹配。

It is possible to access the fx:id -attributed elements in the class that invoked the FXMLLoader , but if you need to do this it is usually a sign that your overall design is wrong. 可以访问调用FXMLLoader的类中的fx:id -attributed元素,但是如果你需要这样做,通常表明你的整体设计是错误的。 You can do: 你可以做:

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

assuming the fx:id defined in the FXML snipped above. 假设FXML中定义的fx:id在上面剪断了。

When you design for FXML, you typically design three things: the application logic, the GUI controller logic, and the FXML. 在设计FXML时,通常需要设计三个方面:应用程序逻辑,GUI控制器逻辑和FXML。

References to the UI controls you wish to access are injected by the FXML loader into your controller class during its loading and initialization so that you do not need to use a FindById() method. 在加载和初始化期间,FXML加载器会将对您希望访问的UI控件的引用注入到控制器类中,这样您就不需要使用FindById()方法。

A controller class looks similar to this: 控制器类看起来类似于:

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
:
:

The FXML loading facility automatically injects references into instance fields that are annotated with the @FXML tag. FXML加载工具自动将引用注入到使用@FXML标记注释的实例字段中。 To manipulate a UI control, just access its methods using the appropriate reference. 要操作UI控件,只需使用适当的引用访问其方法。

Separating the UI control logic from your application logic is highly desirable, and effects a "separation of concerns". 将UI控制逻辑与应用程序逻辑分离是非常需要的,并且会产生“关注点分离”。 When you get used to designing FXML UI's this way, you'll enjoy it. 当你习惯用这种方式设计FXML UI时,你会很享受它。

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

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