# Guis erstellen mit FXML und javaFX gemischt



## venator (7. Mai 2012)

Hallo, 

beschäftige mich zurzeit viel mit JavaFx und FXML. Dabei tritt bei mir die Frage auf ob sich beiden Möglichkeiten ein GUI zu erstellen ergänzen können (1. FXML 2. Direkt in JavaFX). Entgültiges Ziel ist es z.B den rechten Teil einer horizontalen splitpane dynamisch zur Laufzeit in Java zu erstellen, während der rechte Teil statisch in einer FXML Datei definiert wird.

Habe viel ausprobiert, scheitere aber irgendwie ständig. Eigentlich versuche ich nur der im FXML definierten mainPane ein neues Label in der Javaklasse hinzuzufügen.

Am Besten zeige ich euch mal im Quellcode an einem stark vereinfachten Beispiel was ich meine.

sample.fxml

```
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.collections.*?>

<Pane fx:controller="testapplication.Sample"
    xmlns:fx="http://javafx.com/fxml" 
    fx:id="mainPane">
</Pane>
```

TestApplication.java

```
public class TestApplication extends Application {
    @FXML private Pane mainPane;
    
    public static void main(String[] args) {
        Application.launch(TestApplication.class, args);
    }
    
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));
        
        stage.setScene(new Scene(root));
        stage.show();

        Label label = new Label();
        label.setText("Hello");
        
        mainPane.getChildren().add(label);
    }
}
```

Im Controller passiert noch nichts.

Wenn ich das jetzt versuche zu starten, bekomme ich eine java.lang.NullPointerException in der Zeile [JAVA=18]mainPane.getChildren().add(label);[/code] geworfen.

Kann ich die beiden Möglichkeiten eine GUI zu erstellen nicht mischen.
Was mache ich falsch? ???:L

Danke im Voraus


----------



## Paddelpirat (7. Mai 2012)

Die NullPointerException bekommst du, weil du das Label der 
	
	
	
	





```
mainPane
```
 hinzufügen möchtest, aber du initialisierst ja nur deine Parent 
	
	
	
	





```
root
```
.

Edit: Bei mir funktioniert das übrigens dann auch mit einer AnchorPane, die ich über FXML erstelle, mit dem FXMLLoader lade und zu der ich anschließend noch einen Button im Java-Code hinzufüge.

Würde dir zum Testen, mal NetBeans empfehlen, weil es da direkt ein funktionierendes Beispiel gibt.


----------



## venator (7. Mai 2012)

Hallo Paddelpirat danke für deine schnelle Antwort,

eigentlich sollte die mainPane durch die sample.fxml bereits initialisiert werden.
Durch 
	
	
	
	





```
@FXML private Pane mainPane;
```
 sollte die mainPane in Testapplication.java bekannt sein. (dachte ich)

Benutze auch Netbeans, da mir e(fx)clipse zu umständlich war. Habe auch schon einige Tutorials und Beispiele durchgearbeitet. Jedoch hat mir noch keines bei meinem Problem geholfen.

kannst Du mir noch zeigen, wie Du die mainPane oder AnchorPane initialisiert hast?


----------



## Paddelpirat (7. Mai 2012)

Hmm vielleicht musst du noch das 
	
	
	
	





```
Initializable
```
 implementieren. Ansonsten schätze ich mal, dass das in dem Beispiel funktioniert, weil es zu dem Sample.fxml eine gleichnamige Sample.java gibt.
Aber wie du im Hauptprogramm unten siehst, habe ich die AnchorPane, wie du, mit dem FXMLLoader geladen und anschließend noch einen zusätzlichen Button darauf im Java-Code hinzugefügt.

Ich poste einfach mal wie das bei mir im Beispielprogramm aussieht:

Sample.fxml

```
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxml.Sample">
    <children>
        <Button id="button" layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
        <Label id="label" layoutX="126" layoutY="120" minHeight="16" minWidth="69" prefHeight="16" prefWidth="69" fx:id="label" />
    </children>
</AnchorPane>
```

Sample.java

```
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;

public class Sample implements Initializable {
    
    @FXML
    private Label label;
    
    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        label.setText("Hello World!");
    }
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }    
}
```

und das aufrufende Programm: JavaFXML.java

```
public class JavaFXML extends Application {
    
    public static void main(String[] args) {
        Application.launch(JavaFXML.class, args);
    }
    
    @Override
    public void start(Stage stage) throws Exception {
        AnchorPane root = (AnchorPane)FXMLLoader.load(getClass().getResource("Sample.fxml"));
        root.getChildren().add(new Button("Test Me"));
        
        stage.setScene(new Scene(root));
        stage.show();
    }
}
```

Edit: Was du evtl. noch ausprobieren könntest ist bei dir 
	
	
	
	





```
fx:controller="testapplication.Sample"
```
 auf 
	
	
	
	





```
fx:controller="testapplication.TestApplication"
```
 zu ändern. Schaue mir das aber auch gerade zum ersten Mal an ;-)


----------



## venator (8. Mai 2012)

Du hast recht. Danke nochmal für das Beispiel.

Desweiteren ist es wahrscheinlich auch kein guter Stil den Button in der 
	
	
	
	





```
start
```
 Methode hinzuzufügen.

Dafür ist wahrscheinlich die 
	
	
	
	





```
Initializable
```
 da. Hier funktioniert das hinzufügen der Elemente auch besser. 

In der 
	
	
	
	





```
start
```
 methode ist die Refenenz 
	
	
	
	





```
@FXML private Label label;
```
 noch nicht gefüllt. 
Somit die NullPointerException.


----------



## Paddelpirat (8. Mai 2012)

venator hat gesagt.:


> Desweiteren ist es wahrscheinlich auch kein guter Stil den Button in der
> 
> 
> 
> ...



Hab ich auch nur da gemacht, ums mal schnell auszuprobieren, ob sowas funktioniert. Freut mich wenn es jetzt geklappt hat.
Werde mir das auf jeden Fall später auch nochmal genauer ansehen.


----------

