0

I am creating an application where I'm combining FXML and regular javaFX to create an application. I'm, however, experiencing problems writing EventHandlers for a Stage-subclass called AddItemWindow that generates custom windows.

The application shows a list of items (keys and weapons) in an inventory. The user can add items, and needs to press a button to add the item of his choice (Add Key or Add Weapon).

A new window then pops up, where the user has to input the relevant data. It will generate a GridPane with the TextFields where the user can input the data. This will be a custom GridPane, depending on the ItemType. It will then load the FXML and add the GridPane.

With the below code, I am getting LoadExceptions for my SetOnAction-code for the buttons cancelling the window or confirming the new item.

Would any-one know where I'm making an error?

/* StartUp Class*/ package main;

//imports from javafx and java
import domain.DomainController;
import gui.OverviewWindow;

public class StartUpGUI extends Application {

    @Override
    public void start(Stage primaryStage) {
        Parent root = new OverviewWindow(new DomainController());

        Scene scene = new Scene(root);

        primaryStage.setTitle("Weapons and Keys");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String... args) {
        Application.launch(StartUpGUI.class, args);
    }

}

/* OverviewWindow, subclass of BorderPane */ package gui;

//imports from javafx and java
import domain.DomainController;
import domain.ItemType;

public class OverviewWindow extends BorderPane{

    @FXML
    private Button btnAddWeapon;
    @FXML
    private Button btnAddKey;
    @FXML
    private TextArea txaOverview;

    private DomainController dc;

        this.dc = dc;

        FXMLLoader loader = new FXMLLoader(getClass().getResource("OverviewWindow.fxml"));
        loader.setRoot(this);
        loader.setController(this);
        try{
            loader.load();
            txaOverview.setText(dc.showOverview()); // showOverview returns a String containing a toString of all items in the inventory
        }
        catch (IOException ex){
            throw new RuntimeException(ex);
        }
    }

    @FXML
    public void btnAddWeaponOnAction(ActionEvent event){
        try{
            add(ItemType.WEAPON); // ItemType is an Enum where all the properties of the items are defined; for Weapon: name, weight, level, power, used(boolean)
        }
        catch (Exception e){
            throw e;
        }
    }

    @FXML
    public void btnAddKeyOnAction(ActionEvent event){
        try{
            add(ItemType.SLEUTEL); // ItemType is an Enum where all the properties of the items are defined; for Key: name, weight, level, door
        }
        catch (Exception e){
            throw e;
        }
    }

    private void add(ItemType itemType){
        Stage stage = new Stage();
        stage.setTitle(itemType== VoorwerpSoort.WEAPON ? "Add Weapon" : "Add Key");
        AddItem addItem = new AddItem(dc,itemType,this);

        addItem.setOnHiding(new EventHandler<WindowEvent>(){
            @Override
            public void handle(WindowEvent e){
                txaOverview.setText(dc.showOverview()); // when we close the AddItemWindow, we will update the item overview by having the domain controller get this data from the repository
            }
        });

        addItem.show();
    }
}

/* AddItemWindow, a subclass of Stage*/ package gui;

// import relevant javafx and java classes
import domain.DomainController;
import domain.ItemType;

public class AddItemWindow extends Stage {

    @FXML
    private BorderPane addRoot;
    @FXML
    private Button btnOK;
    @FXML
    private Button btnCancel;

    private DomainController dc;
    private ItemType itemType;
    private Parent parent;

    private TextField[] txfAttributes;

    public AddItemWindow(DomainController dc, ItemType itemType, OverviewWindow overviewWindow){
        this.dc = dc;
        this.itemType = itemType;
        this.parent = overviewWindow;
        this.setScene(buildGUI(dc,itemType,overviewWindow));
    }

    private Scene buildGUI(DomeinController dc, VoorwerpSoort vwps, OverzichtSchermController ovsController){
        Parent root = new BorderPane();

        GridPane properties = new GridPane();

        properties.setPadding(new Insets(10));
        properties.setHgap(10);
        properties.setVgap(10);

        ColumnConstraints col1 = new ColumnConstraints();
        col1.setHalignment(HPos.RIGHT);
        ColumnConstraints col2 = new ColumnConstraints();
        properties.getColumnConstraints().addAll(col1, col2);

        String[] attributes = itemType.attributeNames();
        txfAttributes = new TextField[attributes.length];

        for(int i = 0; i<attributes.length; i++){
            properties.add(new Label(attributes[i]),0,i);
            properties.add(txfAttributes[i] = new TextField(),1,i);
        }

        ((BorderPane) root).setCenter(properties);

        FXMLLoader loader = new FXMLLoader(getClass().getResource("AddItemWindow.fxml"));
        loader.setRoot(root);
        loader.setController(root);
        try{
            loader.load();
            return new Scene(root);
        }
        catch(IOException e){
            throw new RuntimeException(e);
        }
    }


    // NOT WORKING
    @FXML
    public void btnOKOnAction(){
        addItem();
    }

    // NOT WORKING
    @FXML
    public void btnCancelOnAction(ActionEvent event){
        hide();
    }

    private void voorwerpToevoegen(){ // we're calling the domaincontroller to add the new item to the repository
        switch (itemType)
        {
    // for the item, add an item by getting the value of each TextField, which are the
    // parameters for a constructor of the new item           
            case WEAPON:
                dc.addWeapon(txfAttributes[0].getText(),
                    Double.parseDouble(txfAttributes[1].getText()),
                    Integer.parseInt(txfAttributes[2].getText()),
                    Integer.parseInt(txfAttributes[3].getText()),
                    Boolean.parseBoolean(txfAttributes[4].getText()));
                break;
            case KEY:
                dc.addKey(txfAttributes[0].getText(),
                    Double.parseDouble(txfAttributes[1].getText()),
                    Integer.parseInt(txfAttributes[2].getText()),
                    Integer.parseInt(txfAttributes[3].getText()));
                break;
        }
        hide();
    }
}
1
  • Edit: that private method voorwerpToevoegen() in the class AddItemWindow should be called addItem(). Translation oversight... Also: the buttons on the OverviewWindow work fine if I leave out the code for the button of the AddItemWindow. Commented May 29, 2016 at 16:39

1 Answer 1

0

At the top you have @FXML private Button btnOK; which is good.

To specify the button's action in Java code, you can use this Java 8 syntax in your buildGUI() method (see JavaFX 8 Event Handling Examples):

 btnOK.setOnAction((event) -> addItem());

If you're not using Java 8, see UI Control Sample.

You don't need the methods annotated with @FXML.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.