简体   繁体   English

这个JavaFX / FXML自定义组件有什么问题?

[英]What is wrong with this JavaFX/FXML custom component?

I am learning to write FXML custom components for use with JavaFX 8 and Scene Builder. 我正在学习编写用于JavaFX 8和Scene Builder的FXML自定义组件。

I wrote the FXML file shown below but Scene Builder will not open it, giving me the message "Open operation has failed" due to the exception: 我编写了下面显示的FXML文件,但是Scene Builder不会打开它,因为例外情况给我提示“打开操作失败”:

java.io.IOException: javafx.fxml.LoadException: mycustomcomponent.TicoTeco is not a valid type.
/C:/Users/xxxxx/Documents/NetBeansProjects/MyCustomComponent/src/mycustomcomponent/TicoTeco.fxml:9
    at com.oracle.javafx.scenebuilder.kit.fxom.FXOMLoader.load(FXOMLoader.java:92)
    at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.(FXOMDocument.java:80)
    at com.oracle.javafx.scenebuilder.kit.fxom.FXOMDocument.(FXOMDocument.java:95)
...

Why am I getting this exception? 为什么我得到这个例外?

Here's the FXML file: 这是FXML文件:

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

<fx:root type="mycustomcomponent.TicoTeco" prefHeight="93.0" prefWidth="304.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <BorderPane layoutX="61.0" prefHeight="115.0" prefWidth="200.0">
         <left>
            <Button fx:id="tico" mnemonicParsing="false" text="Tico" BorderPane.alignment="CENTER" />
         </left>
         <right>
            <Button fx:id="teco" mnemonicParsing="false" text="Teco" BorderPane.alignment="CENTER" />
         </right>
      </BorderPane>
   </children>
</fx:root>

And here are the Java files for TicoTeco.java and Main.java: 以下是TicoTeco.java和Main.java的Java文件:

package mycustomcomponent;

import java.io.IOException;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;

public class TicoTeco extends AnchorPane {

    @FXML
    Button tico;

    @FXML
    Button teco;

    public TicoTeco() throws IOException {
        FXMLLoader fxmlLoader = new FXMLLoader(TicoTeco.class.getResource("TicoTeco.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);
        fxmlLoader.load();
    }

    @FXML
    public void initialize() {
        final EventHandler<ActionEvent> onAction = 
                event -> System.out.println("Hi, I'm " + (event.getSource() == tico? "Tico" : "Teco") + "!");
        tico.setOnAction(onAction);
        teco.setOnAction(onAction);
    }
}
package mycustomcomponent;

import java.io.IOException;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws IOException {
        Scene scene = new Scene(new TicoTeco());

        primaryStage.setTitle("Here are Tico and Teco!");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

}

It's a bit tricky. 这有点棘手。 So your fxml have a little mistake: 所以你的fxml有一点错误:

Your custom class is extending AnchorPane , so this should be the root in your fxml: 您的自定义类正在扩展AnchorPane ,因此这应该是您的fxml中的根:

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

<fx:root type="AnchorPane" prefHeight="93.0" prefWidth="304.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
   <children>
      <BorderPane layoutX="61.0" prefHeight="115.0" prefWidth="200.0">
         <left>
            <Button fx:id="tico" mnemonicParsing="false" text="Tico" BorderPane.alignment="CENTER" />
         </left>
         <right>
            <Button fx:id="teco" mnemonicParsing="false" text="Teco" BorderPane.alignment="CENTER" />
         </right>
      </BorderPane>
   </children>
</fx:root>

After that, you have to make a jar of it, because you have a fxml and a java class. 之后,你必须制作一个jar,因为你有一个fxml和一个java类。 This is the tricky part in Netbeans, so follow up: 这是Netbeans中棘手的部分,所以跟进:

First: Create an own Library Project for the component that looks like this with your copied source files: 第一步:使用复制的源文件为组件创建一个自己的项目:

在此输入图像描述

Second: Delete the copied Main (where the main method is in) file 第二步:删除复制的Main(主方法所在的位置)文件

Third: Do a "Clean and Build" at the project. 第三:在项目中进行“清理和建设”。 The generated .jar file will be in the subfolder "dist" in your Project directory. 生成的.jar文件将位于Project目录的子文件夹“dist”中。

Fourth: Open Scene Builder and import your CustomComponent .jar file like this: 第四步:打开Scene Builder并导入CustomComponent .jar文件,如下所示:

在此输入图像描述

在此输入图像描述

Now you are able to use the component as you want. 现在,您可以根据需要使用该组件。 But be aware of changes to the component are not dynamicaly refresh the imported jar, you have to do the whole thing again. 但要注意组件的更改不是动态刷新导入的jar,你必须再做一遍。

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

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