0

I got following controller for my application:

public class Controller {

    @FXML
    private CustomerPane customerPane;

}

The customerPane is a extended GridPane:

public class CustomerPane extends GridPane {

    @FXML
    private TableView<Customer> customerTable;

    public CustomerPane() {
        System.out.println(this.customerTable);
    }

}

My *.fmxl looks like (I left out some details):

<?import vm.CustomerPane?>
<CustomerPane fx:id="customerPane" layoutX="316.0" prefHeight="654.0" prefWidth="536.0" style="-fx-background-color: #7C8184;">
    <children>
        <TableView fx:id="customerTable" editable="true" prefHeight="200.0" prefWidth="461.0" GridPane.columnSpan="2" GridPane.rowIndex="1">
        </TableView>
    </children>
</CustomerPane>

I got two problems here:

  1. If I save the fmxl-file with a scene builder, it will override the import of my CustomerPane. Why is this the case and how can I fix it?

  2. The customerTable leads to null. Why and how can I fix it?

alexander
  • 1,191
  • 2
  • 20
  • 40

1 Answers1

0

Using a class as controller and creating is using a element with the same name as the class are different things.

In your case you assuming a instance of Controller is used as controller instance:

A CustomerPane instance is created, but since it's not the controller, the customerTable field of that object is not a target objects can be injected to.

You should try to use the Custom Component approach:

<?import vm.CustomerPane?>
<fx:root type="vm.CustomerPane" layoutX="316.0" prefHeight="654.0" prefWidth="536.0" style="-fx-background-color: #7C8184;" xmlns:fx="http://javafx.com/fxml/1">
    <children>
        <TableView fx:id="customerTable" editable="true" prefHeight="200.0" prefWidth="461.0" GridPane.columnSpan="2" GridPane.rowIndex="1">
        </TableView>
    </children>
</fx:root>
public class CustomerPane extends GridPane {

    @FXML
    private TableView<Customer> customerTable;

    public CustomerPane() {
        FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxmlpackage/fxmlName.fxml"));
        loader.setRoot(this);
        loader.setController(this);
        try {
            loader.load();
        } catch (IOException ex) {
            throw new IllegalStateException(ex);
        }
        System.out.println(this.customerTable);
    }

}

This allows you to use new CustomerPane() to create a instance or alternatively use a <CustomerPane> element to create one inside a fxml

<CustomerPane/>
fabian
  • 80,457
  • 12
  • 86
  • 114
  • Thanks for your answer! I now get an exception if I try to open the file in scene builder: `Caused by: java.lang.ClassNotFoundException: vm.CustomerPane` in the fmxl file where I referenced ``. Also I can not edit the fxml file from the customer pane, same error as above. – alexander Sep 05 '18 at 06:06
  • @alexander probably you haven't imported the class in a way that allows scenebuilder to find it. creating a jar containing both should make this work, see https://stackoverflow.com/questions/30063792/adding-a-custom-component-to-scenebuilder-2-0 – fabian Sep 05 '18 at 08:15
  • So, I always have to export the component as jar for every change I will make? That sounds very stressful – alexander Sep 05 '18 at 08:44