JavaFX ConcurrentModificationException / setRoot

thovu

Mitglied
Hallo Zusammen,

ich habe hier ein seltsames Phänomen. Ich möchte eine LoginApplikation mit JavaFx schreiben im MVC Prinzip. Funktioniert fast gut. Komme zur Login Scene, dann zum Hauptbildschirm und wenn ich wieder zur Login Scene möchte erhalte ich eine ConcurrentModificationException.

Was es für mich noch seltsamer macht, ich habe zwei "Hauptschirme", von einem klappt der "Callback" vom anderen nicht. Der bei dem es nicht funktioniert enthält eine TableView. Entferne ich diese TableView, funktioniert auch der Callback.

Vielleicht könnt ihr mich auf den richtigen Weg bringen, vielleicht übersehe ich ja etwas.

Hier die entsprechenden Stelle aus der Main:
Java:
@Override
public void start(Stage primaryStage) {
	Scene scene = new Scene(new StackPane());
	LoginManager lm = new LoginManager(scene, false);
	primaryStage.setScene(scene);
	lm.showLoginScene();
	primaryStage.show();
	}

Dem Konstruktor der LoginManager wird die Scene übergeben ansonsten passiert da nichts erhellendes bezüglich FX. Die showLoginScene sieht so aus:
Java:
public void showLoginScene() {
		try {
		
			String url = "../gui/LoginForm.fxml";
			FXMLLoader loader = new FXMLLoader(
			        getClass().getResource(url)
			      );								
			scene.setRoot(loader.load());
			scene.getWindow().sizeToScene();
			LoginController controller = loader
					.<LoginController> getController();
			controller.initLoginController(this);
			
		} catch (ConcurrentModificationException ex){
			log.error(ex.toString());
			ex.printStackTrace();
		} catch (IOException ex) {
			log.error(ex.getMessage());
		} 
	}
		
}

Die Hauptbildschirme rufe ich hier auf:
Java:
private void showMainView() {
		try {
		    String url;
		    url = "../gui/admin/AdminUserListForm.fxml";
		    FXMLLoader loader = new FXMLLoader(
		        getClass().getResource(url)
		     );
		      
		    scene.setRoot((Parent) loader.load());
		      
		    scene.getWindow().sizeToScene();
		    AdminUserListController controller = loader.<AdminUserListController>getController();
		    controller.initForm(this);
		      
	       } catch (IOException ex) {
		    	log.error(ex.getMessage());
	       }
	}

Im Code ist nur ein Hauptbildschirm zu sehen, da ich gerade versuche die Grundlagen in FX zu verstehen, habe ich bisher immer nur die URL getauscht um die andere Maske zu laden. Das soll später in ein Menü überführt werden. Nur einen Schritt nach den anderen.

Ablauf wie folgt: Loginmaske - Hauptmaske (Aktion: logout) - Loginmaske
Wenn Hauptmaske keine TableView enthält funktioniert es.
Enthält die Hauptmaske eine TableView, bekomme ich folgende Fehlermeldung:

java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at com.sun.javafx.font.PrismFontFactory.removeEmbeddedFont(PrismFontFactory.java:1550)
at com.sun.javafx.font.PrismFontFactory.loadEmbeddedFont(PrismFontFactory.java:1644)
at com.sun.javafx.font.PrismFontFactory.loadEmbeddedFont(PrismFontFactory.java:1525)
at com.sun.javafx.font.PrismFontLoader.loadFont(PrismFontLoader.java:99)
at javafx.scene.text.Font.loadFont(Font.java:400)
at com.sun.javafx.css.StyleManager.loadStylesheetUnPrivileged(StyleManager.java:1080)
at com.sun.javafx.css.StyleManager.loadStylesheet(StyleManager.java:886)
at com.sun.javafx.css.StyleManager.processStylesheets(StyleManager.java:1413)
at com.sun.javafx.css.StyleManager.gatherParentStylesheets(StyleManager.java:1452)
at com.sun.javafx.css.StyleManager.findMatchingStyles(StyleManager.java:1510)
at javafx.scene.CssStyleHelper.createStyleHelper(CssStyleHelper.java:111)
at javafx.scene.Node.reapplyCss(Node.java:8785)
at javafx.scene.Node.impl_reapplyCSS(Node.java:8748)
at javafx.scene.Node.invalidatedScenes(Node.java:829)
at javafx.scene.Node.setScenes(Node.java:894)
at javafx.scene.Parent.scenesChanged(Parent.java:654)
at javafx.scene.Node.invalidatedScenes(Node.java:828)
at javafx.scene.Node.setScenes(Node.java:894)
at javafx.scene.Parent.scenesChanged(Parent.java:654)
at javafx.scene.Node.invalidatedScenes(Node.java:828)
at javafx.scene.Node.setScenes(Node.java:894)
at javafx.scene.Scene$9.invalidated(Scene.java:1085)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:111)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:145)
at javafx.scene.Scene.setRoot(Scene.java:1038)
at application.LoginManager.showLoginScene(LoginManager.java:78)
at application.LoginManager.logout(LoginManager.java:134)
at controller.admin.AdminUserListController.handleCloseButtonAction(AdminUserListController.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275)
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1757)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1645)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Node.fireEvent(Node.java:8216)
at javafx.scene.control.Button.fire(Button.java:185)
at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96)
at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89)
at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56)
at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114)
at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74)
at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54)
at javafx.event.Event.fireEvent(Event.java:198)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3724)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3452)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1728)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2461)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:348)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:273)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:382)
at com.sun.glass.ui.View.handleMouseEvent(View.java:553)
at com.sun.glass.ui.View.notifyMouse(View.java:925)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(WinApplication.java:102)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
at java.lang.Thread.run(Thread.java:745)

Wobei "LoginManager.java:78" die Zeile

Java:
scene.setRoot(loader.load());

ist.

Meine JDK Version ist 1.8.0_31 und die Masken wurden mit dem Scenebuilder (Version 2.0-b20) erstellt.

Hat einer von euch eine Idee, die mir weiterhelfen könnte?

Viele Grüße
Thomas
 

Tom299

Bekanntes Mitglied
Erklären kann ich es nicht, aber ich habs immer andersrum in meinem Code gemacht:
Scene neu erstellt und dann in der PrimaryStage gesetzt:

Code:
Parent root = (Parent) fxmlLoader.load();
Scene scene = new Scene(root,width,height); // width und height kannste weglassen
primaryStage.setScene(scene);
primaryStage.show();

Vielleicht klappts damit?


Ich hatte mal ein ähnliches Problem, als ich auf einer View den Button als "Default" eingestellt hatte bzw. als "Cancel". Nachdem ich das rausgenommen hatte und die Key-Events von Hand implementiert hatte, war der Fehler auch weg.
 

thovu

Mitglied
Klappt leider auch nicht.

"Default" und "Cancel" habe ich auch raus genommen, war es leider auch nicht.

Habe jetzt die TableView spaßeshalber gegen eine TreeTableView ausgetauscht, dann funktioniert es. Aber das ist ja nicht im Sinne des Erfinders.

Es scheint wirklich irgendwie mit dem TableView zusammenzuhängen.
 

thovu

Mitglied
Ok, habe nun in der fxml Datei des Hauptbildschirms eine TreeTableView angelegt und im XML Code "TreeTableView" gegen "TableView" ausgetauscht

Code:
<TableView fx:id="tableUser" layoutX="5.0" layoutY="64.0" prefHeight="260.0" prefWidth="717.0" />

und siehe da, es funktioniert.

Wenn ich die Tabelle nun aber mit Daten fülle, bin ich wieder beim alten Ergebnis, ich komme nicht mehr zurück in die Login Scene.

Habe zudem herausgefunden, wenn ich den "Logout Button" nach der Fehlermeldung ein zweites Mal drücke, gelange ich ohne Fehlermeldung zurück in die Login Scene.
 

thovu

Mitglied
Gelöst!

Es scheint ein Fehler im JDK zu sein, ein Update auf 1.8.0_40 beseitigte den Fehler.

Habe ich so auch noch nie erlebt.
 

Tom299

Bekanntes Mitglied
Mir war gestern noch eingefallen, mal die Tabelle zu clearen bevor du ausloggst, obs vielleicht daran liegt. Aber wenns nach dem Update geht, ist ja gut :)
 

Ähnliche Java Themen


Oben