在JavaFX中添加自定义组件

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在JavaFX中添加自定义组件相关的知识,希望对你有一定的参考价值。

我想在VBox中添加一个自定义元素。

例如:能够编写VBox.getChildren().add(element)element是我在FXML中创建的自定义节点。

我已经按照本教程:https://docs.oracle.com/javafx/2/fxml_get_started/custom_control.htm但这个例子只显示了如何在同一个控制器内执行此操作(单个控制器,我已经拥有了我的“大”控制器,这是WinnerController,我想拆分两个类,一个管理单个元素,以及管理整个场景的一个Winner.fxml)。

我已经有一个类WinnerController,它是我的FXML Winner.fxml的控制器。

这里是我的Winner.fxml的代码:

<AnchorPane id="paneWinner" fx:id="paneWinner" prefHeight="800.0" prefWidth="1280.0" stylesheets="@winner.css" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.gui.WinnerController">

<children>
  <VBox layoutX="434.0" layoutY="125.0" prefHeight="250.0" prefWidth="413.0" spacing="10.0">
     <children>
        <AnchorPane id="leaderBoardElement" prefHeight="80.0" prefWidth="413.0" stylesheets="@leaderBoard.css">
           <children>
              <Text layoutX="49.0" layoutY="45.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Text" wrappingWidth="107.13671875" />
           </children></AnchorPane>
     </children>
  </VBox>

我想动态地将带有id“leaderBoardElement”的元素(所以一个AnchorPane + Text)添加到我的VBox中。

我怎样才能做到这一点?

编辑:我也尝试过这个解决方案:How to understand and use `<fx:root>` , in JavaFX?但我一无所获。当我在我的vbox.getChildren().add(new MyComponent()); i中调用WinnerController时什么都没得到。

WinnerController类:

public class WinnerController implements Initializable {

@FXML
private VBox leaderBoard;

@FXML
public void initialize(URL location, ResourceBundle resources)  {
    System.out.println("Winner Init");

    MyComponent test = new MyComponent();
    System.out.println(test);


    // leaderBoard.getChildren().add(new MyComponent());
}



}

我的Component类:

public class MyComponent extends AnchorPane {
@FXML
private TextField textField ;
@FXML
private Button button ;
public MyComponent() {
    try {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("MyComponent.fxml"));
        loader.setController(this);
        loader.setRoot(this);
        loader.load();
        textField.setText("HELLO!");
    } catch (IOException exc) {
        // handle exception
        System.out.println("ELEMENT NOT CREATE!!!");

    }
  }
}

Winner.fxml:

<AnchorPane id="paneWinner" fx:id="paneWinner" prefHeight="800.0" 
    prefWidth="1280.0" stylesheets="@winner.css" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="client.gui.WinnerController">
     <children>
  <VBox fx:id="leaderBoard" layoutX="434.0" layoutY="125.0" prefHeight="250.0" prefWidth="413.0" spacing="10.0" />

MyComponent.fxml:

<fx:root type="javafx.scene.layout.AnchorPane" fx:id="leaderBoardElement" id="leaderBoardElement">
<TextField fx:id="textField" />
<Button fx:id="button" />

我打电话给另一个类的Winner.fxml创建和加载如下:

 FXMLLoader loader = new FXMLLoader(getClass().getResource("/Winner.fxml"));
                if (loader!=null)
                    System.out.println("LOADER NOT NULL!!");

                try{
                    System.out.println("TRY!");

                    Parent root = (Parent) loader.load();
                    if(root!=null)
                        System.out.println("ROOT NOT NULL!!");

                    Scene startedGame = new Scene(root, 1280, 800, Color.WHITE);
                    if(startedGame!=null)
                        System.out.println("SCENE NOT  NULL!");

                    Stage window = (Stage) paneCarta0.getScene().getWindow();
                    if (window!=null)
                        System.out.println("WINDOW NOT NULL!!");

                    window.setScene(startedGame);
                    window.show();
                    catch (IOException Exception) {
                        System.out.println("View not found. Error while loading");

                }

问题出在new MyComponent()里面,我可能会得到一个异常并传播给我的主调用者。我已经尝试了一切,但我无法弄清楚为什么它不能创建MyComponent对象。

答案

如果您的自定义组件位于单独的FXML文件中,则可以执行此操作。

在你的WinnerController班:

@FXML
private void initialize() throws IOException {
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getRessource("customElement.fxml"));
    fxmlLoader.setController(new CustomElementController()); //Or just specify the Controller in the FXML file
    myVBox.getChildren().add(fxmlLoader.load());
}

编辑:在这个解决方案中,你的主fxml中应该没有<fx:include>标签

以上是关于在JavaFX中添加自定义组件的主要内容,如果未能解决你的问题,请参考以下文章

JavaFX窗口拖动

JavaFX 自定义节点不呈现子节点

如何在片段 xml 中使用自定义组件?

VS中添加自定义代码片段——偷懒小技巧

将自定义组件小部件动态添加到 Android 中的布局中

JavaFX一点学习