简体   繁体   English

如何在不使用JavaFX中的控制器类的情况下使用FXML(从接口传递或获取值)?

[英]How to work with FXML (pass or get values from interface) without using controller class in JavaFX?

是否可以在不使用控制器类的情况下从JavaFX中的FXML接口字段传递/获取值?

No, not really. 不,不是真的。

JavaFX follows an MVC-type architecture. JavaFX遵循MVC类型的体系结构。 The model is left up to the programmer (with support from JavaFX observable properties): FXML supports the view, and the Java controller is the Controller. 该模型留给程序员(在JavaFX可观察属性的支持下):FXML支持视图,Java控制器是Controller。

This gives a nice separation between the definition of the layout (the view, in fxml), and the processing logic (the controller, in Java), which follows long-established, proven, industry standard designs. 这样就可以很好地区分布局的定义(视图,在fxml中)和处理逻辑(在Java中的控制器),它遵循长期建立的,经过验证的行业标准设计。 It also keeps the FXML nice and simple, which makes it relatively easy to create Rapid Application Development (RAD) tools, such as SceneBuilder. 它还使FXML保持简洁,这使得创建快速应用程序开发(RAD)工具(如SceneBuilder)变得相对容易。

That said, there is (at least technically) support for scripting in FXML, though I don't know of any real-world use of this (or even, come to that, any real examples). 也就是说,(至少在技术上)支持FXML中的脚本,虽然我不知道任何实际使用它(甚至,任何真实的例子)。 The FXML documentation has a brief section on scripting , and sure enough the following "works": FXML文档有一个关于脚本简短部分 ,确实如下“工作”:

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

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<?language javascript?>

<VBox xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <TextField promptText="Enter a number" fx:id="x" />
        <TextField promptText="Enter another number" fx:id="y" />
        <Button text="Calculate" onAction="sum.text=parseInt(x.text)+parseInt(y.text)"/>
        <Label fx:id="sum" />

    </children>
</VBox>

If you can figure out do something as simple as avoid the "Calculate" button and just update the label as the text in the text fields change, feel free to post it. 如果您可以想出做一些简单的事情,例如避免“计算”按钮,只需在文本字段中的文本更改时更新标签,请随时发布。 I don't really think this is a technique that is applicable to any real-world application. 我并不认为这是一种适用于任何实际应用的技术。

You can use a different pattern if you make a custom root for your fxml with fx:root, this way the "controller" will also be part of the component too like in the pattern Code Behind. 如果使用fx:root为fxml创建自定义根,则可以使用不同的模式,这样“控制器”也将成为组件的一部分,就像模式Code Behind一样。

Basically, you extend a component of JavaFX (for instance BorderPane). 基本上,您扩展了JavaFX的一个组件(例如BorderPane)。 Then you use it as root of your FXML. 然后你用它作为你的FXML的根。 To make this work you have to use FXMLLoader's setRoot(...) method and use fx:root in FXML. 要完成这项工作,你必须使用FXMLLoader的setRoot(...)方法并在FXML中使用fx:root。

Then you can use your custom JavaFX component as a controller too and invoke FXMLLoader in the constructor. 然后,您也可以将自定义JavaFX组件用作控制器,并在构造函数中调用FXMLLoader。 As a result you can inject components from your FXML in your custom Java component: 因此,您可以在自定义Java组件中注入FXML中的组件:

public class MyJavaFXBorderPane extends BorderPane {

@FXML
public TextField textFieldFromFXML;

public MyJavaFXBorderPane() {
    final FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myfxml.fxml"));
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);
}

}

You change the order of loading with this technique: Java component first (which is also a controller) and then FXML instead of FXML first with FXMLLoader and then its controller. 您可以使用以下技术更改加载顺序:首先是Java组件(也是控制器),然后使用FXMLLoader然后是控制器,先使用FXML而不是FXML。

So, of course it is a controller, but also a component which is the root of the fxml, you can override methods, add new fields etc... 所以,当然它是一个控制器,但也是一个组件,它是fxml的根,你可以覆盖方法,添加新的字段等...

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

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