PreferencesFX
PreferencesFX copied to clipboard
Adding new categories to an existing object
Currently it appears that you can define the PreferencesFx object once and that's it. I would like to be able to later access that object to add additional categories (for example from a module loaded later in my program).
As a workaround I am using an interface to create my modules, and searching for them using Spring, and I have a method that returns Category[] which I then add to the PreferencesFx object at the time of creation, but if I load a new module later in the app, I have no way of updating.
This is possible by creating a new PreferencesFx
object every time you show the Preferences, making sure you use the same class as the storage key, you can always pass in less or more settings / categories.
Although I admit this is not as elegant as having the possibility to add them at runtime by calling for example preferences.getCategories()
along the lines of how it works with getChildren()
in JavaFX.
I would welcome someone adding a PR for this functionality, however I think it involves quite a lot of work, since we currently assume everything is set before initializing. So a lot of change listeners need to be added to support every behavior of PreferencesFX.
As a workaround for this, instead of having my modules add to the preferences object, I'm using Spring to search for all of my modules and then using a common interface, each module is required to return Category[] which is then added to the preferences object the first time it's built.
This is possible by creating a new
PreferencesFx
object every time you show the Preferences, making sure you use the same class as the storage key, you can always pass in less or more settings / categories.
Hi @martinfrancois I was happy to see this workaround but I can't get it to work. On the second call I get 'IllegalStateException: Cannot change a control's field once set.' I can reproduce this in the WorkbenchFX demo too by duplicating the line
public Preferences() {
preferencesFx = createPreferences();
preferencesFx = createPreferences();
}
https://github.com/dlsc-software-consulting-gmbh/WorkbenchFX/blob/60a7e5fef4c2c3c8fcfda9561bfac2abcc49a9b4/workbenchfx-demo/src/main/java/com/dlsc/workbenchfx/modules/preferences/Preferences.java#L75
Am I doing something wrong?
The output I get is:
Exception in thread "JavaFX Application Thread" java.lang.IllegalStateException: Cannot change a control's field once set.
at com.dlsc.preferencesfx.formsfx.view.controls.SimpleControl.setField(SimpleControl.java:70)
at com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxGroupRenderer.layoutParts(PreferencesFxGroupRenderer.java:88)
at com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxGroupRenderer.init(PreferencesFxGroupRenderer.java:51)
at com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxGroupRenderer.<init>(PreferencesFxGroupRenderer.java:43)
at com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxFormRenderer.lambda$initializeParts$0(PreferencesFxFormRenderer.java:50)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566)
at com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxFormRenderer.initializeParts(PreferencesFxFormRenderer.java:51)
at com.dlsc.formsfx.view.util.ViewMixin.init(ViewMixin.java:45)
at com.dlsc.preferencesfx.formsfx.view.renderer.PreferencesFxFormRenderer.<init>(PreferencesFxFormRenderer.java:36)
at com.dlsc.preferencesfx.view.CategoryView.initializeFormRenderer(CategoryView.java:48)
at com.dlsc.preferencesfx.view.CategoryPresenter.initializeViewParts(CategoryPresenter.java:60)
at com.dlsc.preferencesfx.view.Presenter.init(Presenter.java:15)
at com.dlsc.preferencesfx.view.CategoryPresenter.<init>(CategoryPresenter.java:51)
at com.dlsc.preferencesfx.PreferencesFx.lambda$initializeCategoryViews$0(PreferencesFx.java:123)
at java.util.ArrayList.forEach(ArrayList.java:1257)
at com.dlsc.preferencesfx.PreferencesFx.initializeCategoryViews(PreferencesFx.java:121)
at com.dlsc.preferencesfx.PreferencesFx.init(PreferencesFx.java:77)
at com.dlsc.preferencesfx.PreferencesFx.<init>(PreferencesFx.java:64)
at com.dlsc.preferencesfx.PreferencesFx.<init>(PreferencesFx.java:55)
at com.dlsc.preferencesfx.PreferencesFx.of(PreferencesFx.java:102)
at com.dlsc.workbenchfx.modules.preferences.Preferences.createPreferences(Preferences.java:89)
at com.dlsc.workbenchfx.modules.preferences.Preferences.initPrefs(Preferences.java:79)
at com.dlsc.workbenchfx.modules.preferences.PreferencesModule.activate(PreferencesModule.java:36)
at com.dlsc.workbenchfx.Workbench.lambda$initListeners$0(Workbench.java:419)
at com.sun.javafx.binding.ExpressionHelper$Generic.fireValueChangedEvent(ExpressionHelper.java:361)
at com.sun.javafx.binding.ExpressionHelper.fireValueChangedEvent(ExpressionHelper.java:81)
at javafx.beans.property.ObjectPropertyBase.fireValueChangedEvent(ObjectPropertyBase.java:105)
at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:146)
at javafx.beans.property.ObjectProperty.setValue(ObjectProperty.java:69)
at com.dlsc.workbenchfx.Workbench.openModule(Workbench.java:499)
at com.dlsc.workbenchfx.view.controls.module.Tile.open(Tile.java:73)
at com.dlsc.workbenchfx.view.controls.module.Tile.lambda$setupEventHandlers$1(Tile.java:66)
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.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.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$ClickGenerator.postProcess(Scene.java:3470)
at javafx.scene.Scene$ClickGenerator.access$8100(Scene.java:3398)
at javafx.scene.Scene$MouseHandler.process(Scene.java:3766)
at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389)
at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
at com.sun.glass.ui.View.notifyMouse(View.java:937)
at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
at com.sun.glass.ui.gtk.GtkApplication.lambda$null$10(GtkApplication.java:245)
at java.lang.Thread.run(Thread.java:748)
30.08.2019 17:06:00.319 [JavaFX Application Thread] TRACE com.dlsc.workbenchfx.Workbench - openModule - set active module to Preferences