ConfigItem: improve logic, UI
authorNiki Roo <niki@nikiroo.be>
Thu, 16 May 2019 07:10:06 +0000 (09:10 +0200)
committerNiki Roo <niki@nikiroo.be>
Thu, 16 May 2019 07:10:06 +0000 (09:10 +0200)
src/be/nikiroo/utils/resources/MetaInfo.java
src/be/nikiroo/utils/ui/ConfigItem.java

index 3a6e71ae1571469a421c216761ae7208b98ff675..746fd4d939a71f346c3529b63fd65b13af5f9be9 100644 (file)
@@ -2,6 +2,9 @@ package be.nikiroo.utils.resources;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
 
 import be.nikiroo.utils.resources.Meta.Format;
 
@@ -21,7 +24,8 @@ public class MetaInfo<E extends Enum<E>> {
        private Meta meta;
 
        private String value;
-       private List<Runnable> reloadListeners = new ArrayList<Runnable>();
+       private List<Runnable> reloadedListeners = new ArrayList<Runnable>();
+       private List<Runnable> saveListeners = new ArrayList<Runnable>();
 
        private String name;
        private String description;
@@ -50,7 +54,7 @@ public class MetaInfo<E extends Enum<E>> {
                if (description == null) {
                        description = meta.description();
                        if (meta.info() != null && !meta.info().isEmpty()) {
-                               description += "\n" + meta.info();
+                               description += " (" + meta.info() + ")";
                        }
                }
 
@@ -178,7 +182,7 @@ public class MetaInfo<E extends Enum<E>> {
         */
        public void reload() {
                value = bundle.getString(id);
-               for (Runnable listener : reloadListeners) {
+               for (Runnable listener : reloadedListeners) {
                        try {
                                listener.run();
                        } catch (Exception e) {
@@ -188,17 +192,31 @@ public class MetaInfo<E extends Enum<E>> {
                }
        }
 
-       public void addReloadListener(Runnable listener) {
-               reloadListeners.add(listener);
+       // listeners will be called AFTER reload
+       public void addReloadedListener(Runnable listener) {
+               reloadedListeners.add(listener);
        }
 
        /**
         * Save the current value to the {@link Bundle}.
         */
        public void save() {
+               for (Runnable listener : saveListeners) {
+                       try {
+                               listener.run();
+                       } catch (Exception e) {
+                               // TODO: error management?
+                               e.printStackTrace();
+                       }
+               }
                bundle.setString(id, value);
        }
 
+       // listeners will be called BEFORE save
+       public void addSaveListener(Runnable listener) {
+               saveListeners.add(listener);
+       }
+
        /**
         * Create a list of {@link MetaInfo}, one for each of the item in the given
         * {@link Bundle}.
@@ -222,5 +240,52 @@ public class MetaInfo<E extends Enum<E>> {
                return list;
        }
 
-       // TODO: by groups, a-là Authors/Sources
+       // TODO: multiple levels?
+       static public <E extends Enum<E>> Map<MetaInfo<E>, List<MetaInfo<E>>> getGroupedItems(
+                       Class<E> type, Bundle<E> bundle) {
+               Map<MetaInfo<E>, List<MetaInfo<E>>> map = new TreeMap<MetaInfo<E>, List<MetaInfo<E>>>();
+               Map<MetaInfo<E>, List<MetaInfo<E>>> map1 = new TreeMap<MetaInfo<E>, List<MetaInfo<E>>>();
+
+               List<MetaInfo<E>> ungrouped = new ArrayList<MetaInfo<E>>();
+               for (MetaInfo<E> info : getItems(type, bundle)) {
+                       if (info.meta.group()) {
+                               List<MetaInfo<E>> list = new ArrayList<MetaInfo<E>>();
+                               map.put(info, list);
+                               map1.put(info, list);
+                       } else {
+                               ungrouped.add(info);
+                       }
+               }
+
+               for (int i = 0; i < ungrouped.size(); i++) {
+                       MetaInfo<E> info = ungrouped.get(i);
+                       MetaInfo<E> group = findParent(info, map.keySet());
+                       if (group != null) {
+                               map.get(group).add(info);
+                               ungrouped.remove(i--);
+                       }
+               }
+
+               if (ungrouped.size() > 0) {
+                       map.put(null, ungrouped);
+               }
+
+               return map;
+       }
+
+       static private <E extends Enum<E>> MetaInfo<E> findParent(MetaInfo<E> info,
+                       Set<MetaInfo<E>> candidates) {
+               MetaInfo<E> group = null;
+               for (MetaInfo<E> pcandidate : candidates) {
+                       if (info.id.toString().startsWith(pcandidate.id.toString())) {
+                               if (group == null
+                                               || group.id.toString().length() < pcandidate.id
+                                                               .toString().length()) {
+                                       group = pcandidate;
+                               }
+                       }
+               }
+
+               return group;
+       }
 }
index beed66f55f9de312998924c0e85c06f01344a45c..3780a7e21058a1c9a80475ce8932112aa350e039 100644 (file)
@@ -3,9 +3,9 @@ package be.nikiroo.utils.ui;
 import java.awt.BorderLayout;
 
 import javax.swing.JCheckBox;
+import javax.swing.JLabel;
 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.Format;
@@ -25,7 +25,7 @@ public class ConfigItem<E extends Enum<E>> extends JPanel {
 
        public ConfigItem(final MetaInfo<E> info) {
                this.setLayout(new BorderLayout());
-               this.setBorder(new EmptyBorder(2, 10, 2, 10));
+               // this.setBorder(new EmptyBorder(2, 10, 2, 10));
 
                if (info.getFormat() == Format.BOOLEAN) {
                        final JCheckBox field = new JCheckBox();
@@ -38,33 +38,56 @@ public class ConfigItem<E extends Enum<E>> extends JPanel {
                        // Should not happen!
                        if (state == null) {
                                System.err
-                                               .println("No default value given for BOOLEAN parameter "
-                                                               + info.getName() + ", we consider it is FALSE");
+                                               .println("No default value given for BOOLEAN parameter \""
+                                                               + info.getName()
+                                                               + "\", we consider it is FALSE");
                                state = false;
                        }
 
                        field.setSelected(state);
 
-                       info.addReloadListener(new Runnable() {
+                       info.addReloadedListener(new Runnable() {
                                @Override
                                public void run() {
-                                       field.setText(info.getString());
+                                       Boolean state = info.getBoolean();
+                                       if (state == null) {
+                                               info.getDefaultBoolean();
+                                       }
+                                       if (state == null) {
+                                               state = false;
+                                       }
+
+                                       field.setSelected(state);
+                               }
+                       });
+                       info.addSaveListener(new Runnable() {
+                               @Override
+                               public void run() {
+                                       info.setBoolean(field.isSelected());
                                }
                        });
 
+                       this.add(new JLabel(info.getName() + ": "), BorderLayout.WEST);
                        this.add(field, BorderLayout.CENTER);
                } else {
                        final JTextField field = new JTextField();
                        field.setToolTipText(info.getDescription());
                        field.setText(info.getString());
 
-                       info.addReloadListener(new Runnable() {
+                       info.addReloadedListener(new Runnable() {
                                @Override
                                public void run() {
                                        field.setText(info.getString());
                                }
                        });
+                       info.addSaveListener(new Runnable() {
+                               @Override
+                               public void run() {
+                                       info.setString(field.getText());
+                               }
+                       });
 
+                       this.add(new JLabel(info.getName() + ": "), BorderLayout.WEST);
                        this.add(field, BorderLayout.CENTER);
                }
        }