0
votes

I want to create a custom control in which I can set a list of another custom controls, and I want to be able to use FXML just like it is possible to do in the JavaFX TableView (see the list of columns):

JavaFX TableView

TableView.fxml

<TableView fx:id="tableView">

    <columns>

        <TableColumn>...</TableColumn>

        <TableColumn>...</TableColumn>

      ...
    </columns>
</TableView>

TableView.java

public class FXMLTableViewController {

    @FXML TableView<MyBean> tableView;

    private void myMethod1() {
        ObservableList<TableColumn<MyBean, ?>> columns = tableView.getColumns();
        ...

    }
}

I just want to write something like:

CustomControl1

CustomControl1.fxml

<?import javafx.scene.control.*?>

<fx:root type="javafx.scene.control.Control" xmlns:fx="http://javafx.com/fxml"> 
   <customList>

       <CustomControl2>
           ...
       </CustomControl2>

       <CustomControl2>
           ...
       </CustomControl2>

       ...

   </customList>
</fx:root>

CustomControl1.java

public class CustomControl1 extends Control {

    private ObservableList<CustomControl2> controls2;

    public CustomControl1() {
        FXMLLoader fxmlLoader = new 
        FXMLLoader(getClass().getResource("CustomControl1.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();            
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }
    }

    private void myMethod1() {
        controls2 = getControls2();
        ...
    }
}

I already know how to implement simple custom controls, but I have not found anything about composing custom controls this way. Can you point me some direction?

1

1 Answers

0
votes

You should use the real type of the class in the <fx:root> element, since Control does not provide customList. I.e. use something like type="my.package.CustomControl1".

Furthermore to add elements the way TableView allows you to do the class created for the surrounding tag needs to provide a readonly list property with the name of the tag, i.e.

public class CustomControl1 extends Control {

    ...

    public ObservableList<CustomControl2> getCustomList() {
        return controls2;
    }

}