我正在学习编写用于JavaFX 8和Scene Builder的FXML自定义组件。
我编写了如下所示的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) ...
为什么我会收到此异常?
这里是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>
以下是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);
}
}
答案 0 :(得分:5)
这有点棘手。所以你的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>
之后,你必须制作一个jar,因为你有一个fxml和一个java类。这是Netbeans中棘手的部分,所以请跟进:
首先:使用复制的源文件为组件创建一个自己的库项目:
第二:删除复制的Main(主方法所在的位置)文件
第三:做一个&#34;清理和构建&#34;在项目中。生成的.jar文件将位于子文件夹&#34; dist&#34;在你的项目目录中。
第四:打开Scene Builder并导入CustomComponent .jar文件,如下所示:
现在您可以根据需要使用该组件。但要注意组件的更改不是动态刷新导入的jar,你必须再做一遍。