ConfigItem: remove logic from UI, improve UI
authorNiki Roo <niki@nikiroo.be>
Wed, 15 May 2019 19:50:47 +0000 (21:50 +0200)
committerNiki Roo <niki@nikiroo.be>
Wed, 15 May 2019 19:50:47 +0000 (21:50 +0200)
src/be/nikiroo/utils/resources/Bundle.java
src/be/nikiroo/utils/resources/BundleHelper.java
src/be/nikiroo/utils/resources/Meta.java
src/be/nikiroo/utils/resources/MetaInfo.java [new file with mode: 0644]
src/be/nikiroo/utils/ui/ConfigEditor.java
src/be/nikiroo/utils/ui/ConfigItem.java

index 424f12096dbfaa4378eda21208118be59e0ae06a..5932cfff71db0793a074a0bddccf9b56a5b34e25 100644 (file)
@@ -298,7 +298,7 @@ public class Bundle<E extends Enum<E>> {
         *            the new colour
         */
        public void setColor(E id, Integer color) {
-               setString(id, BundleHelper.fromColour(color));
+               setString(id, BundleHelper.fromColor(color));
        }
 
        /**
index 94066d8685572a6027a88d88f19a0d31a8175b31..39c00c5c6079e5791a62ae73b2c38535d0ffb371 100644 (file)
@@ -227,7 +227,7 @@ class BundleHelper {
         *            the ARGB colour value
         * @return the raw {@link String} value that correspond to it
         */
-       static public String fromColour(int color) {
+       static public String fromColor(int color) {
                int a = (color >> 24) & 0xFF;
                int r = (color >> 16) & 0xFF;
                int g = (color >> 8) & 0xFF;
index d50664da74f0828e3465383a9bb828222cd29ea9..a83bcca418df48fca8f51efa6c1cf9b1275c8174 100644 (file)
@@ -46,11 +46,22 @@ public @interface Meta {
                 * custom String value (basically, a {@link Format#FIXED_LIST} with an
                 * option to enter a not accounted for value).
                 */
-               COMBO_LIST
+               COMBO_LIST,
+               /**
+                * A list of {@link Format#STRING}s.
+                * <p>
+                * The list items are separated by a comma, each surrounded by
+                * double-quotes, with backslashes and double-quotes escaped by a
+                * backslash.
+                * <p>
+                * Example: <tt>"un", "deux"</tt>
+                */
+               LIST_OF_STRINGS,
        }
 
        /**
-        * A description of this item.
+        * A description of this item (what it is or does, how to explain that item
+        * to the user).
         * 
         * @return what it is
         */
diff --git a/src/be/nikiroo/utils/resources/MetaInfo.java b/src/be/nikiroo/utils/resources/MetaInfo.java
new file mode 100644 (file)
index 0000000..3a6e71a
--- /dev/null
@@ -0,0 +1,226 @@
+package be.nikiroo.utils.resources;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import be.nikiroo.utils.resources.Meta.Format;
+
+/**
+ * A graphical item that reflect a configuration option from the given
+ * {@link Bundle}.
+ * 
+ * @author niki
+ * 
+ * @param <E>
+ *            the type of {@link Bundle} to edit
+ */
+public class MetaInfo<E extends Enum<E>> {
+       private final Bundle<E> bundle;
+       private final E id;
+
+       private Meta meta;
+
+       private String value;
+       private List<Runnable> reloadListeners = new ArrayList<Runnable>();
+
+       private String name;
+       private String description;
+
+       public MetaInfo(Class<E> type, Bundle<E> bundle, E id) {
+               this.bundle = bundle;
+               this.id = id;
+
+               try {
+                       this.meta = type.getDeclaredField(id.name()).getAnnotation(
+                                       Meta.class);
+               } catch (NoSuchFieldException e) {
+               } catch (SecurityException e) {
+               }
+
+               // We consider that if a description bundle is used, everything is in it
+
+               String description = null;
+               if (bundle.getDescriptionBundle() != null) {
+                       description = bundle.getDescriptionBundle().getString(id);
+                       if (description != null && description.trim().isEmpty()) {
+                               description = null;
+                       }
+               }
+
+               if (description == null) {
+                       description = meta.description();
+                       if (meta.info() != null && !meta.info().isEmpty()) {
+                               description += "\n" + meta.info();
+                       }
+               }
+
+               String name = id.toString();
+               if (name.length() > 1) {
+                       name = name.substring(0, 1) + name.substring(1).toLowerCase();
+                       name = name.replace("_", " ");
+               }
+
+               this.name = name;
+               this.description = description;
+
+               reload();
+       }
+
+       /**
+        * THe name of this item, deduced from its ID.
+        * <p>
+        * In other words, it is the ID but presented in a displayable form.
+        * 
+        * @return the name
+        */
+       public String getName() {
+               return name;
+       }
+
+       /**
+        * The description of this item (information to present to the user).
+        * 
+        * @return the description
+        */
+       public String getDescription() {
+               return description;
+       }
+
+       public Format getFormat() {
+               return meta.format();
+       }
+
+       /**
+        * The value stored by this item, as a {@link String}.
+        * 
+        * @return the value
+        */
+       public String getString() {
+               return value;
+       }
+
+       public String getDefaultString() {
+               return meta.def();
+       }
+
+       public Boolean getBoolean() {
+               return BundleHelper.parseBoolean(getString());
+       }
+
+       public Boolean getDefaultBoolean() {
+               return BundleHelper.parseBoolean(getDefaultString());
+       }
+
+       public Character getCharacter() {
+               return BundleHelper.parseCharacter(getString());
+       }
+
+       public Character getDefaultCharacter() {
+               return BundleHelper.parseCharacter(getDefaultString());
+       }
+
+       public Integer getInteger() {
+               return BundleHelper.parseInteger(getString());
+       }
+
+       public Integer getDefaultInteger() {
+               return BundleHelper.parseInteger(getDefaultString());
+       }
+
+       public Integer getColor() {
+               return BundleHelper.parseColor(getString());
+       }
+
+       public Integer getDefaultColor() {
+               return BundleHelper.parseColor(getDefaultString());
+       }
+
+       public List<String> getList() {
+               return BundleHelper.parseList(getString());
+       }
+
+       public List<String> getDefaultList() {
+               return BundleHelper.parseList(getDefaultString());
+       }
+
+       /**
+        * The value stored by this item, as a {@link String}.
+        * 
+        * @param value
+        *            the new value
+        */
+       public void setString(String value) {
+               this.value = value;
+       }
+
+       public void setBoolean(boolean value) {
+               setString(BundleHelper.fromBoolean(value));
+       }
+
+       public void setCharacter(char value) {
+               setString(BundleHelper.fromCharacter(value));
+       }
+
+       public void setInteger(int value) {
+               setString(BundleHelper.fromInteger(value));
+       }
+
+       public void setColor(int value) {
+               setString(BundleHelper.fromColor(value));
+       }
+
+       public void setList(List<String> value) {
+               setString(BundleHelper.fromList(value));
+       }
+
+       /**
+        * Reload the value from the {@link Bundle}.
+        */
+       public void reload() {
+               value = bundle.getString(id);
+               for (Runnable listener : reloadListeners) {
+                       try {
+                               listener.run();
+                       } catch (Exception e) {
+                               // TODO: error management?
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public void addReloadListener(Runnable listener) {
+               reloadListeners.add(listener);
+       }
+
+       /**
+        * Save the current value to the {@link Bundle}.
+        */
+       public void save() {
+               bundle.setString(id, value);
+       }
+
+       /**
+        * Create a list of {@link MetaInfo}, one for each of the item in the given
+        * {@link Bundle}.
+        * 
+        * @param <E>
+        *            the type of {@link Bundle} to edit
+        * @param type
+        *            a class instance of the item type to work on
+        * @param bundle
+        *            the {@link Bundle} to sort through
+        * 
+        * @return the list
+        */
+       static public <E extends Enum<E>> List<MetaInfo<E>> getItems(Class<E> type,
+                       Bundle<E> bundle) {
+               List<MetaInfo<E>> list = new ArrayList<MetaInfo<E>>();
+               for (E id : type.getEnumConstants()) {
+                       list.add(new MetaInfo<E>(type, bundle, id));
+               }
+
+               return list;
+       }
+
+       // TODO: by groups, a-là Authors/Sources
+}
index 7bdf17a24abe3adeec66af828674f2258b902119..367396da85d5acbaf8c7c1b5a4bd0f8d73615ee0 100644 (file)
@@ -15,6 +15,7 @@ import javax.swing.JScrollPane;
 import javax.swing.border.EmptyBorder;
 
 import be.nikiroo.utils.resources.Bundle;
+import be.nikiroo.utils.resources.MetaInfo;
 
 /**
  * A configuration panel for a {@link Bundle}.
@@ -30,7 +31,7 @@ import be.nikiroo.utils.resources.Bundle;
  */
 public class ConfigEditor<E extends Enum<E>> extends JPanel {
        private static final long serialVersionUID = 1L;
-       private List<ConfigItem<E>> items;
+       private List<MetaInfo<E>> items;
 
        /**
         * Create a new {@link ConfigEditor} for this {@link Bundle}.
@@ -54,15 +55,15 @@ public class ConfigEditor<E extends Enum<E>> extends JPanel {
 
                main.add(new JLabel(title));
 
-               items = ConfigItem.getItems(type, bundle);
-               for (ConfigItem<E> item : items) {
-                       main.add(item);
+               items = MetaInfo.getItems(type, bundle);
+               for (MetaInfo<E> item : items) {
+                       main.add(new ConfigItem<E>(item));
                }
 
                main.add(createButton("Reset", new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
-                               for (ConfigItem<E> item : items) {
+                               for (MetaInfo<E> item : items) {
                                        item.reload();
                                }
                        }
@@ -73,7 +74,7 @@ public class ConfigEditor<E extends Enum<E>> extends JPanel {
                        public void actionPerformed(ActionEvent e) {
                                Object snap = bundle.takeSnapshot();
                                bundle.reload(true);
-                               for (ConfigItem<E> item : items) {
+                               for (MetaInfo<E> item : items) {
                                        item.reload();
                                }
                                bundle.reload(false);
@@ -84,7 +85,7 @@ public class ConfigEditor<E extends Enum<E>> extends JPanel {
                main.add(createButton("Save", new ActionListener() {
                        @Override
                        public void actionPerformed(ActionEvent e) {
-                               for (ConfigItem<E> item : items) {
+                               for (MetaInfo<E> item : items) {
                                        item.save();
                                }
 
index 691c6198319b24d71ea2710e6f96f7aa348a3c49..beed66f55f9de312998924c0e85c06f01344a45c 100644 (file)
@@ -1,17 +1,15 @@
 package be.nikiroo.utils.ui;
 
 import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.util.ArrayList;
-import java.util.List;
 
-import javax.swing.JLabel;
+import javax.swing.JCheckBox;
 import javax.swing.JPanel;
 import javax.swing.JTextField;
 import javax.swing.border.EmptyBorder;
 
 import be.nikiroo.utils.resources.Bundle;
-import be.nikiroo.utils.resources.Meta;
+import be.nikiroo.utils.resources.Meta.Format;
+import be.nikiroo.utils.resources.MetaInfo;
 
 /**
  * A graphical item that reflect a configuration option from the given
@@ -24,92 +22,50 @@ import be.nikiroo.utils.resources.Meta;
  */
 public class ConfigItem<E extends Enum<E>> extends JPanel {
        private static final long serialVersionUID = 1L;
-       private Class<E> type;
-       private final Bundle<E> bundle;
-       private final E id;
-
-       private Meta meta;
-       private String value;
-
-       private JTextField valueField;
-
-       public ConfigItem(Class<E> type, Bundle<E> bundle, E id) {
-               this.type = type;
-               this.bundle = bundle;
-               this.id = id;
-
-               try {
-                       this.meta = type.getDeclaredField(id.name()).getAnnotation(
-                                       Meta.class);
-               } catch (NoSuchFieldException e) {
-               } catch (SecurityException e) {
-               }
 
+       public ConfigItem(final MetaInfo<E> info) {
                this.setLayout(new BorderLayout());
                this.setBorder(new EmptyBorder(2, 10, 2, 10));
 
-               String tooltip = null;
-               if (bundle.getDescriptionBundle() != null) {
-                       tooltip = bundle.getDescriptionBundle().getString(id);
-                       if (tooltip != null && tooltip.trim().isEmpty()) {
-                               tooltip = null;
+               if (info.getFormat() == Format.BOOLEAN) {
+                       final JCheckBox field = new JCheckBox();
+                       field.setToolTipText(info.getDescription());
+                       Boolean state = info.getBoolean();
+                       if (state == null) {
+                               info.getDefaultBoolean();
                        }
-               }
-
-               String name = id.toString();
-               if (name.length() > 1) {
-                       name = name.substring(0, 1) + name.substring(1).toLowerCase();
-                       name = name.replace("_", " ");
-               }
-
-               JLabel nameLabel = new JLabel(name);
-               nameLabel.setToolTipText(tooltip);
-               nameLabel.setPreferredSize(new Dimension(400, 0));
-               this.add(nameLabel, BorderLayout.WEST);
 
-               valueField = new JTextField();
-               valueField.setText(value);
-
-               reload();
-               this.add(valueField, BorderLayout.CENTER);
-       }
-
-       /**
-        * Reload the value from the {@link Bundle}.
-        */
-       public void reload() {
-               value = bundle.getString(id);
-               valueField.setText(value);
-       }
-
-       /**
-        * Save the current value to the {@link Bundle}.
-        */
-       public void save() {
-               value = valueField.getText();
-               bundle.setString(id, value);
-       }
+                       // Should not happen!
+                       if (state == null) {
+                               System.err
+                                               .println("No default value given for BOOLEAN parameter "
+                                                               + info.getName() + ", we consider it is FALSE");
+                               state = false;
+                       }
 
-       /**
-        * Create a list of {@link ConfigItem}, one for each of the item in the
-        * given {@link Bundle}.
-        * 
-        * @param <E>
-        *            the type of {@link Bundle} to edit
-        * @param type
-        *            a class instance of the item type to work on
-        * @param bundle
-        *            the {@link Bundle} to sort through
-        * 
-        * @return the list
-        */
-       static public <E extends Enum<E>> List<ConfigItem<E>> getItems(
-                       Class<E> type, Bundle<E> bundle) {
-               List<ConfigItem<E>> list = new ArrayList<ConfigItem<E>>();
-               for (E id : type.getEnumConstants()) {
-                       list.add(new ConfigItem<E>(type, bundle, id));
+                       field.setSelected(state);
+
+                       info.addReloadListener(new Runnable() {
+                               @Override
+                               public void run() {
+                                       field.setText(info.getString());
+                               }
+                       });
+
+                       this.add(field, BorderLayout.CENTER);
+               } else {
+                       final JTextField field = new JTextField();
+                       field.setToolTipText(info.getDescription());
+                       field.setText(info.getString());
+
+                       info.addReloadListener(new Runnable() {
+                               @Override
+                               public void run() {
+                                       field.setText(info.getString());
+                               }
+                       });
+
+                       this.add(field, BorderLayout.CENTER);
                }
-
-               return list;
        }
 }