JavaFX TableView Item hinzufügen

programmierer12

Bekanntes Mitglied
Hallo zusammen,
ich habe ein mehr oder weniger großes Problem:
Ich habe mit JavaFX eine Fxml-Datei geladen und möchte jetzt während der Laufzeit Daten zu einer ListView hinzufügen. Das wird mir aber immer mit einer Exception quittiert!
Meine Fxml-Datei:
Java:
<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Frame_Controller">
   <children>
      <MenuBar>
         <menus>
            <Menu mnemonicParsing="false" text="%key1">
               <items>
                  <MenuItem mnemonicParsing="false" onAction="#schliessen" text="%key2" />
                  <MenuItem fx:id="abmelden" mnemonicParsing="false" onAction="#abmelden" text="%key41" />
               </items>
            </Menu>
            <Menu mnemonicParsing="false" text="%key3" />
            <Menu mnemonicParsing="false" text="%key11">
               <items>
                  <MenuItem disable="true" mnemonicParsing="false" text="%key9" />
                  <MenuItem disable="true" mnemonicParsing="false" text="%key10" />
               </items>
            </Menu>
            <Menu mnemonicParsing="false" text="%key4">
               <items>
                  <MenuItem mnemonicParsing="false" text="%key6" />
                  <MenuItem mnemonicParsing="false" text="%key5" />
               </items>
            </Menu>
         </menus>
      </MenuBar>
      <TabPane prefHeight="200.0" prefWidth="200.0" tabClosingPolicy="UNAVAILABLE">
        <tabs>
          <Tab text="Englisch">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                     <children>
                        <HBox prefHeight="171.0" prefWidth="600.0">
                           <children>
                              <ScrollPane prefHeight="200.0" prefWidth="300.0">
                                 <content>
                                    <ListView fx:id="englisch" prefHeight="171.0" prefWidth="300.0" />
                                 </content>
                              </ScrollPane>
                              <ScrollPane prefHeight="200.0" prefWidth="300.0">
                                 <content>
                                    <ListView fx:id="englischVokabeln" prefHeight="171.0" prefWidth="300.0" />
                                 </content>
                              </ScrollPane>
                           </children>
                        </HBox>
                     </children>
                  </AnchorPane>
            </content>
          </Tab>
          <Tab text="Latein">
            <content>
              <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                     <children>
                        <HBox prefHeight="171.0" prefWidth="600.0">
                           <children>
                              <ScrollPane prefHeight="200.0" prefWidth="300.0">
                                 <content>
                                    <ListView fx:id="latein" prefHeight="171.0" prefWidth="300.0" />
                                 </content>
                              </ScrollPane>
                              <ScrollPane prefHeight="200.0" prefWidth="300.0">
                                 <content>
                                    <ListView fx:id="lateinVokabeln" prefHeight="171.0" prefWidth="300.0" />
                                 </content>
                              </ScrollPane>
                           </children>
                        </HBox>
                     </children>
                  </AnchorPane>
            </content>
          </Tab>
        </tabs>
      </TabPane>
   </children>
</VBox>

und mein Versuch die Daten zu laden:
Java:
    	List<String> l = new ArrayList<String>();
    	l.add(new Vokabel("FRAGE", "ANTWORT").toString());       //Die Vokabel habe ich nur zum testen erstellt   
    	ObservableList<String> list = FXCollections.observableList();
    	englisch.setItems(list);

Nun bekomme ich wenn ich die Liste füllen will immer diese Exception:
Java:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	at javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
	at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
	at javafx.event.Event.fireEvent(Unknown Source)
	at javafx.scene.Node.fireEvent(Unknown Source)
	at javafx.scene.control.Button.fire(Unknown Source)
	at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
	at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
	at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
	at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
	at javafx.event.Event.fireEvent(Unknown Source)
	at javafx.scene.Scene$MouseHandler.process(Unknown Source)
	at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source)
	at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
	at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
	at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
	at com.sun.glass.ui.View.notifyMouse(Unknown Source)
	at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source)
	at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at sun.reflect.misc.Trampoline.invoke(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
	... 48 more
Caused by: java.lang.NullPointerException
	at application.Frame_Controller.karteikasten(Frame_Controller.java:124)
	... 57 more

Kann mir jemand einen Tipp geben wie ich das Problem lösen kann?

MFG
programmierer12
 
Wie muss ich das jetzt verstehen?
Frame_Controller.java:124 ist das hier
Java:
englisch.setItems(list);
aber was kann ich daran jetzt ändern?
 
englisch.setItems(list); --> englisch==null
Also: Ist dein Controller richtig angebunden?
Da sollte so etwas wie
Code:
@FXML
private ListView englisch;
drin stehen. Wenn du deine FXML also über einen FXMLLoader initialisierst, wird dort der ListView mit der fx:id="englisch" injiziert.

Aber ich weiss auch noch nicht, was dein Code bewirken soll, denn deine Liste "list" ist leer, wenn du englisch.setItems(list); aufrufst. Ich denke du wolltest hier etwas wie list.addAll(l); machen, das ist aber Blödsinn, denn es genügt, wenn du nach erstellen der ObservableList list.add(new Vokabel("FRAGE", "ANTWORT").toString()); ausführst (also Vokabel auf "list" und nicht auf "l").
 
Ich habe jetzt meinen Code dahingehend verändert, dass ich mit
Java:
    @FXML
    private ListView<Vokabel> englisch;
meine ListView initialisiere (in der Controller Klasse) und die Einträge jetzt so hinzufüge:
Java:
    	List<Vokabel> l = new ArrayList<Vokabel>();
    	l.add(new Vokabel("FRAGE", "ANTWORT"));
    	ObservableList<Vokabel> list = FXCollections.observableList(l);
    	list.addAll(l);
    	englisch.setItems(list);
.
Jetzt ändert sich aber auch meine Exception!
Java:
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
	at javafx.fxml.FXMLLoader$MethodHandler.invoke(Unknown Source)
	at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(Unknown Source)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
	at javafx.event.Event.fireEvent(Unknown Source)
	at javafx.scene.Node.fireEvent(Unknown Source)
	at javafx.scene.control.Button.fire(Unknown Source)
	at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(Unknown Source)
	at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
	at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(Unknown Source)
	at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(Unknown Source)
	at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEventImpl(Unknown Source)
	at com.sun.javafx.event.EventUtil.fireEvent(Unknown Source)
	at javafx.event.Event.fireEvent(Unknown Source)
	at javafx.scene.Scene$MouseHandler.process(Unknown Source)
	at javafx.scene.Scene$MouseHandler.access$1500(Unknown Source)
	at javafx.scene.Scene.impl_processMouseEvent(Unknown Source)
	at javafx.scene.Scene$ScenePeerListener.mouseEvent(Unknown Source)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(Unknown Source)
	at com.sun.glass.ui.View.handleMouseEvent(Unknown Source)
	at com.sun.glass.ui.View.notifyMouse(Unknown Source)
	at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source)
	at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at sun.reflect.misc.Trampoline.invoke(Unknown Source)
	at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at sun.reflect.misc.MethodUtil.invoke(Unknown Source)
	... 48 more
Caused by: java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
	at java.util.ArrayList$Itr.next(Unknown Source)
	at java.util.AbstractCollection.addAll(Unknown Source)
	at javafx.collections.ModifiableObservableListBase.addAll(Unknown Source)
	at application.Frame_Controller.karteikasten(Frame_Controller.java:124)
	... 57 more
Was hat das zu bedeuten, und wie kann ich das beheben?

MFG
programmierer12
 
Das du in Zeile 124 der Klasse Frame_Controller (btw: Underscores in Klassennamen? Ernsthat???) gleichzeitig versucht hast, die Liste zu editieren.
at application.Frame_Controller.karteikasten(Frame_Controller.java:124)

Java:
    	List<Vokabel> l = new ArrayList<Vokabel>();
    	l.add(new Vokabel("FRAGE", "ANTWORT"));
    	ObservableList<Vokabel> list = FXCollections.observableList(l); // <---
    	list.addAll(l); // <---
    	englisch.setItems(list);
Der Grund liegt hier in den beiden markierten Zeilen. Und mal abgesehen davon... Was soll der Blödsinn???
Warum fügst du die "Vokabel" erst einer List a zu, diese Liste dann der nächsten Liste b und dann gleich noch einmal zu b?

Mach das so hier:
Java:
    	ObservableList<Vokabel> list = FXCollections.observableArrayList(); // Achtung: hier ist ein "Array" dazugekommen
    	list.add(new Vokabel("FRAGE", "ANTWORT"));
    	englisch.setItems(list);
Und fertig!

Du musst deine Daten nicht erst noch in eine andere Liste verpacken (unnötiger Speicherverbrauch und allgemein blödsinnig). ObservableList erweitert die normalen Listen und fügt "nur" ein paar nette Features wie Databinding und "Überwachung" á la PropertyChangeEvent hinzu.
 
Tut mir leid aber wenn ich das so mache wie du es gepostet hast bekomme ich bei
Java:
englisch.setItems(list);
eine Nullpointer Exception. Hätte ich etwas an der Fxml-Datei ändern müssen?
 
Ohne den Cord vor mir zu haben, ist es nur rätselraten. Setze eine Breakpoiunt und Debugge. Dann siehst du, was jetzt genau null ist. Was anderes kann ich dir an dieser Stelle nicht mehr raten.
 
Ich konnte auch durch das debuggen nichts rausfinden;( aber wenn es dir eventuell etwas bringt ist hier die gesamte Controller Klasse:
Java:
package application;

import java.net.URL;
import java.util.ResourceBundle;

import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListView;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;

public class Frame_Controller implements Initializable {

	private Database db = new Database();
	
    @FXML
    private PasswordField passwort;

    @FXML
    private TextField name;
    
    @FXML
    private ListView<Vokabel> englisch;
    
    @FXML
    private ListView<Vokabel> atein;
    
    @FXML
    void loginAction(ActionEvent event){

    	System.err.println("LOGIN");
    	
    	String inputname = name.getText();
    	String inputpasswort = passwort.getText();
    	
    	System.out.println(inputname+"\t"+inputpasswort);
    	
    	System.out.println(db.checkPW(inputname, inputpasswort));
    	
    	if (db.checkPW(inputname, inputpasswort)) {
			
    		Main.login();
    		
		}
    	
    	else {

    		name.clear();
    		passwort.clear();
    		Main.falscheEingabe();
    		
		}
    	
    }
    
    @FXML
    void nochmalVersuchen(ActionEvent event){
    	
    	System.err.println("Nochmal versuchen");
    	Main.backFrame();
    	
    }
    
    @FXML
    void registerAction(ActionEvent event){
    	
    	System.err.println("Registrieren");
    	Main.registrieren();
    	
    }
    
    @FXML
    void abmelden(ActionEvent event){
    	
    	System.err.println("Abmelden");
    	Main.abmelden();
    	
    }
    
    @FXML
    void schliessen(ActionEvent event){
    	
    	System.err.println("Schließen");
    	Main.schließen();
    	
    }
    
    @FXML
    void bestaetigen(ActionEvent event){
    	
    	System.err.println("Ja");
    	System.exit(0);
    	
    }
    
    @FXML
    void abbrechen(ActionEvent event){
    	
    	System.err.println("Abbrechen");
    	Main.backFrame();
    	
    }
    
    @FXML
    void karteikasten(ActionEvent event){
    	
    	System.err.println("Karteikasten starten");
    	Main.karteikasten();
    	
    	ObservableList<Vokabel> list = FXCollections.observableArrayList(); // Achtung: hier ist ein "Array" dazugekommen
    	list.add(new Vokabel("FRAGE", "ANTWORT"));
    	englisch.setItems(list);
    	
    }

	@Override
	public void initialize(URL location, ResourceBundle resources) {

		
		
	}

}

MFG
programmierer12
 
Ah! Ich vermute mal einfach du brauchst noch die ganzen Cell-irgendwass-Provider - wenigstens den CellValueProvider (bindet die Daten deines Typs an die ListView, glaub ich). Am besten aber auch den CellProvider mit dem du den Inhalt deiner ListView-Zellen bestimmst. Sind beides so schräge Callbacks.
 
BTW: Ich bekomme Kopfschmerzen, wenn ich das hier sehen muss:
Java:
    @FXML
    void bestaetigen(ActionEvent event){
 
    	System.err.println("Ja");
    	System.exit(0);
 
    }

Weil:
a) Was sollen die vielen System.err.println-Aufrufe? Denke hier mal über ein vernünftiges Logging nach (z.B. log4j). Das kannst du mit dem ConsoleAppender auch erst einmal nur auf die Konsole umleiten, später dann aber auch einfach in eine Datei.
b) System.exit(0);....... Bitte nicht. Das ist eher etwas für reine Konsolenprogramme (wobei ich es auch da meist vermeide). Wenn du die Anwendung beenden willst, dann verwende die dafür vorgesehene Methode Platform.exit() aus dem Package javafx.application. Alles andere lässt einem ja die Haare zu Berge stehen!

#edit
c) Und verwende CamelCase für Klassennamen und camelCase für reguläre Variablen (das das C mal gross und mal klein war, ist Absicht)
d) Und wenn wir schon bei Programmierstil angekommen sind: Verwende möglichst englische Begriffe ("confirm" anstelle von "bestaetigen" (Java ist übrigens UTF-8 - du kannst also theoretisch auch Umlaute verwenden - würde es aber nie machen)), ok?
 
Zuletzt bearbeitet:
Danke für deine überaus hilfreichen Antworten! Ich habe jetzt noch einmal den Debugger bemüht und habe herausgefunden, dass meine Variablen für die ListViews null sind habe ich dann beim Laden der Fxml-Datei einen Fehler gemacht?

edit: Nur noch als anmerkung eines meiner MenuItems ist nicht null nur die ListViews.
 
Zuletzt bearbeitet:
Etwas anderes, als noch einmal die "fx:id"s in deinem FXML zu überprüfen, ob die Namen wirklich mit denen im Code des Controllers übereinstimmen und ob die Klassen stimmen (also wenn VBox im FXML, dann nicht etwas Group im Controller), u.s.w., kann ich dir auch nicht raten.
 
Ich habe jetzt irgendwie das Gefühl, dass meine Fxml-Dateien doch nicht richtig geladen werden, weil die IDs auch alle stimmen!
Könntest du evtl. einmal darüber schauen wie ich meine Datein lade?
Java:
 private static Initializable replaceSceneContent(String fxml)throws Exception{  //Wird aufgerufen wenn die FXML-Dateien wechseln sollen
        	
        	FXMLLoader l = new FXMLLoader() ;
				
            	String baseName = "application.strings";
            	
        		ResourceBundle bundle = ResourceBundle.getBundle(baseName, Locale.getDefault());
        		
        		URL fxmlURL = Main.class.getResource(fxml);

                FXMLLoader loader = new FXMLLoader(fxmlURL, bundle);
                Parent p = loader.load();

                Scene scene = new Scene(p, 600, 400);
        		stage.setResizable(false);
        		stage.setScene(scene);        
        		stage.sizeToScene();
        		stage.setTitle("Schülersoftware");
        		
        		l = loader;
    		
    		return (Initializable) l.getController();
    		
	}
        

	private Initializable generateSceneContent(String fxml) throws Exception {    //Wird nur aufgerufen wenn das Programm gestartet wird
		
		String baseName = "application.strings";
		 
		ResourceBundle bundle = ResourceBundle.getBundle(baseName, Locale.getDefault());
		
		URL fxmlURL = getClass().getResource(fxml);

        FXMLLoader loader = new FXMLLoader(fxmlURL, bundle);
        Parent p = loader.load();

        Scene scene = new Scene(p, 600, 400);
		stage.setResizable(false);
		stage.setScene(scene);        
		stage.sizeToScene();
		stage.setTitle("Schülersoftware");

		return (Initializable) loader.getController();

	}
 
Grundsätzlich sieht es auf den ersten Blick gut aus, ABER:
Was mir ins Auge springt ist der Teil mit der Scene. Die Scene ist der Rahmen für das Programm auf der Stage. Ich öffne NIE eine (neue) Scene, es sei denn, ich mach ein neues Fenster auf (also Stage, Scene, View). Du möchtes im regulären Fall nur den View austauschen, also ist der Teil mit der Scene überflüssig.
Du musst eine Art Root-UI haben, die du in den Scene lädst. Dann lädst du das anzuzeigen UI-Fragment mit FXMLLoader und das Ergebnis (der View, den du direkt aus #load() erhälst, oder aber später - nach #load() - mit #getRoot() bekommst) setzt du dann an geeignete Stelle in deinen Root-View (oder irgendeinem Container darunter).

Bsp:
Root-View ist ein BorderPane, Top ist das Menü, Bottom eine Statuszeile. Center ist leer.
Dann lädst du mit FXMLLoader ein anderes FXML-File, das z.B. eine VBox enhält. Diese bekommst du mittelst der o.g. Methoden (#load() oder #load()->#getRoot()) und setzt die VBox nun als Center des Root-Views ein. Das läst sich beliebig tief schachteln. Ich verwende diese Art von dynamischen Austauschen der GUI-Elemente häufig (hab in einer Anwendung eine art Pseudo-Dialog, da lade ich den Inhalt der Dialoge und zeige diesen dann per Animation an - StackPanes sind da sehr praktisch!) oder aber seit ich entdeckt habe, wie einfach das geht, verwende ich häufig auch fx:include. Einzige Hürde ist immer die Kommunikation über Controller-Grenzen hinweg, über die man sich Gedanken machen muss. Wenn es schnell gehen soll, verwende ich immer einen einfachen selbstgeschrieben und generischen Event-Mechanismus.

Verstehst du, was ich meine?
 
Ja ich verstehe was du meinst! Das heißt aber auch dass es nicht an der Methode liegt wie ich die FXML-Datei lade, weshalb die ListView immer null ist? Hast du noch eine Idee was das Problem sein könnte?
 
Ich weiss es nicht, nein, aber ich vermute, dass dein Austausch der Scene hier ein Problem ist. Wie ich es zuvor beschrieben habe. Tausche nicht die Scene aus, sondern nur deren Content. Probier erst einmal das, dann sehen wir weiter.
 
Ich habe es jetzt so gemacht, dass ich mir von der Stage die Scene hohle und mit
Java:
.setRoot();
einen neuen Parent setzte der von der load-Methode des FXMLLoaders zurück gegeben wird.
Java:
        private static Initializable replaceSceneContent(String fxml)throws Exception{
				
            	String baseName = "application.strings";
            	
        		ResourceBundle bundle = ResourceBundle.getBundle(baseName, Locale.getDefault());
        		
        		URL fxmlURL = Main.class.getResource(fxml);

                FXMLLoader loader = new FXMLLoader(fxmlURL, bundle);
                Parent p = loader.load();
                
                stage.getScene().setRoot(p);
    		
    		return (Initializable) loader.getController();
    		
	}
Ist das so richtig? Wenn ja dann hat es nichts gebracht, da die ListView immer noch null ist.;(
 
Nein. Nicht ganz
vonmirselbst hat gesagt.:
Root-View ist ein BorderPane, Top ist das Menü, Bottom eine Statuszeile. Center ist leer.
Dann lädst du mit FXMLLoader ein anderes FXML-File, das z.B. eine VBox enhält. Diese bekommst du mittelst der o.g. Methoden (#load() oder #load()->#getRoot()) und setzt die VBox nun als Center des Root-Views ein.
Wenn du deine Applikation startest, lädst du (z.B. via FXML) einen Root-View und setzt ihn auf die Scene.
Danach lädst du die FXML deines Content-Views (z.B. die mit dem ListView) und fügst sie als Center auf die im Quote erwähnte BorderPane hinzu...
 
Wenn du deine Applikation startest, lädst du (z.B. via FXML) einen Root-View und setzt ihn auf die Scene.
Danach lädst du die FXML deines Content-Views (z.B. die mit dem ListView) und fügst sie als Center auf die im Quote erwähnte BorderPane hinzu...
Also muss ich im Controller den Parrent der neuen FXML als Center der alten Setzen?
 
Nein.
(Ich frage mich gerade, ob ich mich echt so kompliziert ausdrücke!?)

1) in der #start-Methode hast du deine Stage (dein Fenster)
2) Darauf legst du eine Scene mit deinem Root-View (BorderPane)
3) im Root-View änderst du nun den Center-Node
4) Du setzt keine Parents neu!

Bsp:

Main
Java:
public class Main extends Application {
	@Override
	public void start(Stage primaryStage) {
		try {
			BorderPane root = (BorderPane) FXMLLoader.load(getClass().getResource("RootExample.fxml"));
			Scene scene = new Scene(root);
			primaryStage.setScene(scene);
			primaryStage.show();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		launch(args);
	}
}

RootExample.fxml
Code:
<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Menu?>
<?import javafx.scene.control.MenuBar?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>

<BorderPane xmlns:fx="http://javafx.com/fxml" fx:id="borderPane" fx:controller="jfxtest.RootExampleController">

	<top>
		<MenuBar fx:id="menuBar"> 
			<Menu fx:id="menuFile" text="_File"/> 
			<Menu fx:id="menuHelp" text="_Help"/> 
		</MenuBar>
	</top>
	<bottom>
		<HBox fx:id="hboxStatus" style="-fx-border-color: black; -fx-background-color: white;" spacing="5" minHeight="25"> 
			<BorderPane.margin>
				<Insets/> 
			</BorderPane.margin>
		</HBox>
	</bottom>
</BorderPane>

RootExampleController
Java:
public class RootExampleController {
	
	@FXML
	private BorderPane borderPane;
	@FXML
	private MenuBar menuBar;
	@FXML
	private Menu menuFile;
	@FXML
	private Menu menuHelp;
	@FXML
	private HBox hboxStatus;
	
	@FXML
	public void initialize() {
		try {
			FXMLLoader loader = new FXMLLoader();
			loader.setLocation(RootExampleController.class.getResource("Main.fxml"));
			Pane p = (Pane) loader.load();
			borderPane.setCenter(p);
		} catch (IOException e) {}
	}
}

Main.fxml
Code:
<?xml version="1.0" encoding="UTF-8"?>

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

<BorderPane xmlns:fx="http://javafx.com/fxml">

	<top>
		<TextArea BorderPane.alignment="TOP_CENTER"/> 
	</top>
	<center>
		<Button text="Click me!"/> 
	</center>
</BorderPane>
 

Neue Themen


Zurück
Oben