PreferencesFX icon indicating copy to clipboard operation
PreferencesFX copied to clipboard

Conditional settings enhancement

Open p1r9t3 opened this issue 5 years ago • 7 comments

Settings should be allowed to have sub-settings that are shown/hidden conditionally on the value of the parent. Example: I have a checkbox that enables/disables an additional part of my application. I don't want the settings for that part to be available unless the parent function is enabled, so having the option to display a Group/Groups only if the value of the parent is 'True' would be a nice enhancement.

p1r9t3 avatar Jun 24 '19 14:06 p1r9t3

While this is not possible currently with a convenience method, it is possible to add and remove settings at runtime. So in your case you could add or remove the settings you mentioned by listening to a BooleanProperty for changes that you attach to the checkbox you mentioned.

Of course, I still agree introducing some kind of convenience method to handle that more neatly would make sense. What API would you propose for this?

martinfrancois avatar Jul 19 '19 08:07 martinfrancois

I'm not sure just yet, but I've been doing some playing with the code to see if I can implement this... something along the lines of Category->Subcategory->Setting->Subsetting where the subsetting visibility is bound to a property of the setting like you said. Once I have a better plan in place I'll post it here.

p1r9t3 avatar Jul 20 '19 06:07 p1r9t3

What about the following:

Category cat = Category.of(...);
PreferencesFx.of(cat);
// later, to set to invisible
cat.visibleProperty().set(false);
// and
cat.setVisible(false);

Along the lines of the standard visibility implementation in JavaFX nodes?

martinfrancois avatar Jul 20 '19 17:07 martinfrancois

That could work. I'm trying to work out a way to implement this at the group / property level. I'll keep you posted on my progress.

p1r9t3 avatar Jul 21 '19 02:07 p1r9t3

a feature I am looking into it too.

I would like to display different settings on some switch setting.

fujohnwang avatar Jan 19 '21 14:01 fujohnwang

I try this way:

  val switchListener: InvalidationListener = { _ =>
    category.getGroups.clear()
    if (localStoreOnlyProperty.get()) {
      category.getGroups.addAll(util.Arrays.asList(basicGroup, uiGroup))
    } else {
      category.getGroups.addAll(util.Arrays.asList(basicGroup, uiGroup, remoteGroup))
    }
  }
  localStoreOnlyProperty.addListener(switchListener)
  switchListener.invalidated(localStoreOnlyProperty)

but failed with exception:

 java.lang.RuntimeException: Unable to construct Application instance: class com.keevol.keenotes.desk.KeeNotesFXApplication
	at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:890)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
	at java.base/java.lang.Thread.run(Thread.java:832)
Caused by: java.lang.reflect.InvocationTargetException
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:64)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:481)
	at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$8(LauncherImpl.java:802)
	at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
	at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
	at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
Caused by: java.lang.UnsupportedOperationException
	at java.base/java.util.AbstractList.remove(AbstractList.java:167)
	at java.base/java.util.AbstractList$Itr.remove(AbstractList.java:387)
	at java.base/java.util.AbstractList.removeRange(AbstractList.java:598)
	at java.base/java.util.AbstractList.clear(AbstractList.java:243)
	at com.keevol.keenotes.desk.settings.Settings.$anonfun$switchListener$1(Settings.scala:60)
	at com.keevol.keenotes.desk.settings.Settings.<init>(Settings.scala:68)
	at com.keevol.keenotes.desk.KeeNotesFXApplication.<init>(KeeNotesFXApplication.scala:44)
	... 11 more

or:

  val switchListener: InvalidationListener = { _ =>
    if (localStoreOnlyProperty.get()) {
      if (category.getGroups.contains(remoteGroup)) category.getGroups.remove(remoteGroup)
    } else {
      if (!category.getGroups.contains(remoteGroup)) category.getGroups.add(remoteGroup)
    }
  }
  localStoreOnlyProperty.addListener(switchListener)
  switchListener.invalidated(localStoreOnlyProperty)

both dead end.

fujohnwang avatar Jan 19 '21 15:01 fujohnwang

I get things done by introducing 2 preferencesFX instance and switch their View on custom dialog.

cheers ;0)

code is here if you want to know the details: https://github.com/keevol/keenotes-desktop/blob/master/src/main/scala/com/keevol/keenotes/desk/settings/SettingsDialog.scala

fujohnwang avatar Jan 20 '21 03:01 fujohnwang