Revision: 3678
Author: [email protected]
Date: Tue Jul  6 10:54:22 2010
Log: NEW - bug 2458: Create Critic Manager
http://trillian.sqlpower.ca/bugzilla/show_bug.cgi?id=2458

The default settings of the critic panel can now be saved and loaded to and from Java Prefs.
http://code.google.com/p/power-architect/source/detail?r=3678

Modified:
 /trunk/src/main/java/ca/sqlpower/architect/ddl/critic/CriticManager.java
/trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticGroupingPanel.java /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticManagerPanel.java /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticSettingsPanel.java

=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/ddl/critic/CriticManager.java Mon Jul 5 15:06:27 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/ddl/critic/CriticManager.java Tue Jul 6 10:54:22 2010
@@ -23,6 +23,8 @@
 import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;

 import ca.sqlpower.architect.ArchitectProject;
 import ca.sqlpower.architect.ddl.DDLGenerator;
@@ -76,7 +78,7 @@
* These are the critics that the critic manager will start with when it is
      * first created.
      */
-    private static final List<CriticAndSettings> STARTING_CRITICS =
+    private final List<CriticAndSettings> STARTING_CRITICS =
         Collections.unmodifiableList(Arrays.asList(
                 //generics
                 new PrimaryKeyCritic(),
@@ -139,6 +141,7 @@
         for (CriticAndSettings criticType : STARTING_CRITICS) {
             registerCritic(criticType);
         }
+        loadDefaults();
     }

     /**
@@ -294,4 +297,45 @@
     public ArchitectProject getParent() {
         return (ArchitectProject) super.getParent();
     }
-}
+
+    /**
+ * Call this method to save the current settings of this manager to be the
+     * default setup of the critic manager on new projects.
+     * <p>
+     * Changes to this method must match {...@link #loadDefaults()}.
+     *
+     * @throws BackingStoreException
+     *             If there is an exception with Java Prefs.
+     */
+    public void saveAsDefaults() throws BackingStoreException {
+ Preferences prefs = Preferences.userNodeForPackage(CriticManager.class);
+        prefs.clear();
+        for (CriticGrouping group : getCriticGroupings()) {
+ prefs.putBoolean(CriticGrouping.class.getSimpleName() + "." + group.getPlatformType() + ".enabled", group.isEnabled()); + //Currently only one instance of each critic type exists. This may change + //in the future in which case we will need a different identifier other than
+            //its class or name.
+            for (CriticAndSettings settings : group.getSettings()) {
+ prefs.put(settings.getClass().getSimpleName() + ".severity", settings.getSeverity().name());
+            }
+        }
+        prefs.flush();
+    }
+
+    /**
+ * Call this method to load the current settings stored in prefs to be the
+     * default settings of this critic manager.
+     * <p>
+     * Changes to this method must match {...@link #saveAsDefaults()}.
+     */
+    public void loadDefaults() {
+ Preferences prefs = Preferences.userNodeForPackage(CriticManager.class);
+        for (CriticGrouping group : getCriticGroupings()) {
+ group.setEnabled(prefs.getBoolean(CriticGrouping.class.getSimpleName() + "." + group.getPlatformType() + ".enabled", false));
+            for (CriticAndSettings settings : group.getSettings()) {
+ String severity = prefs.get(settings.getClass().getSimpleName() + ".severity", Severity.IGNORE.name());
+                settings.setSeverity(Severity.valueOf(severity));
+            }
+        }
+    }
+}
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticGroupingPanel.java Tue Jun 8 14:56:35 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticGroupingPanel.java Tue Jul 6 10:54:22 2010
@@ -1,7 +1,10 @@
 package ca.sqlpower.architect.swingui.critic;

 import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
 import java.util.ArrayList;
+import java.util.Collection;
 import java.util.EventObject;
 import java.util.HashMap;
 import java.util.List;
@@ -13,6 +16,7 @@
 import javax.swing.JPanel;
 import javax.swing.JTree;
 import javax.swing.event.CellEditorListener;
+import javax.swing.event.TreeModelEvent;
 import javax.swing.event.TreeModelListener;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
@@ -21,8 +25,10 @@
 import javax.swing.tree.TreeModel;
 import javax.swing.tree.TreePath;

-import ca.sqlpower.architect.ddl.critic.CriticGrouping;
 import ca.sqlpower.architect.ddl.critic.CriticAndSettings;
+import ca.sqlpower.architect.ddl.critic.CriticGrouping;
+import ca.sqlpower.object.AbstractSPListener;
+import ca.sqlpower.object.SPListener;
 import ca.sqlpower.object.SPObject;
 import ca.sqlpower.swingui.DataEntryPanel;

@@ -120,12 +126,33 @@
      * {...@link CriticGrouping}.
      * TODO Pull a generic tree model off of this tree model for later use.
      */
-    private final TreeModel treeModel = new TreeModel() {
-
+    private final TreeModel treeModel;
+
+    private static class CriticSettingsTreeModel implements TreeModel {
+
         /**
          * Tree listeners.
          */
private final List<TreeModelListener> treeListeners = new ArrayList<TreeModelListener>();
+
+ private final PropertyChangeListener criticSettingsListener = new PropertyChangeListener() {
+
+            public void propertyChange(PropertyChangeEvent evt) {
+ final CriticSettingsPanel source = (CriticSettingsPanel) evt.getSource();
+                for (int i = treeListeners.size() - 1; i >= 0; i--) {
+ treeListeners.get(i).treeNodesChanged(new TreeModelEvent(evt.getSource(), new TreePath(new Object[]{grouping, source.getSettings()})));
+                }
+            }
+        };
+
+        private final CriticGrouping grouping;
+
+ public CriticSettingsTreeModel(CriticGrouping grouping, Collection<CriticSettingsPanel> panels) {
+            this.grouping = grouping;
+            for (CriticSettingsPanel childPanel : panels) {
+ childPanel.addPropertyChangeListener(criticSettingsListener);
+            }
+        }

         public void valueForPathChanged(TreePath path, Object newValue) {
throw new UnsupportedOperationException("This should not be allowed at this point. " +
@@ -160,7 +187,7 @@
         public void addTreeModelListener(TreeModelListener l) {
             treeListeners.add(l);
         }
-    };
+    }

     /**
      * Displays the settings editor panels in a tree for easier navigation.
@@ -183,9 +210,21 @@
* Each of the settings grouped by this class's grouping will have a data entry panel
      * associated with it.
      */
-    private final Map<CriticAndSettings, DataEntryPanel> settingsPanels =
-        new HashMap<CriticAndSettings, DataEntryPanel>();
-
+ private final Map<CriticAndSettings, CriticSettingsPanel> settingsPanels =
+        new HashMap<CriticAndSettings, CriticSettingsPanel>();
+
+    /**
+ * Added to the group this panel displays to update the checkbox of the group.
+     */
+    private final SPListener groupListener = new AbstractSPListener() {
+
+        public void propertyChanged(PropertyChangeEvent evt) {
+            if (evt.getPropertyName().equals("enabled")) {
+                enabledCheckbox.setSelected((Boolean) evt.getNewValue());
+            }
+        }
+    };
+
     public CriticGroupingPanel(CriticGrouping grouping) {
         this.grouping = grouping;

@@ -196,11 +235,15 @@
final CriticSettingsPanel settingsPanel = new CriticSettingsPanel(settings);
             settingsPanels.put(settings, settingsPanel);
         }
+
+ treeModel = new CriticSettingsTreeModel(grouping, settingsPanels.values());

         enabledCheckbox = new JCheckBox();
         enabledCheckbox.setSelected(grouping.isEnabled());
         builder.append(enabledCheckbox);

+        grouping.addSPListener(groupListener);
+
         JTree settingsTree = new JTree(treeModel);
         settingsTree.setCellRenderer(treeCellRenderer);
         settingsTree.setRowHeight(0);
@@ -244,5 +287,15 @@
         }
         return false;
     }
+
+    /**
+     * Call when disposing of this panel.
+     */
+    public void cleanup() {
+        grouping.removeSPListener(groupListener);
+        for (CriticSettingsPanel panel : settingsPanels.values()) {
+            panel.cleanup();
+        }
+    }

 }
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticManagerPanel.java Wed Jun 30 15:00:13 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticManagerPanel.java Tue Jul 6 10:54:22 2010
@@ -19,9 +19,12 @@

 package ca.sqlpower.architect.swingui.critic;

+import java.awt.event.ActionEvent;
 import java.util.ArrayList;
 import java.util.List;
-
+import java.util.prefs.BackingStoreException;
+
+import javax.swing.AbstractAction;
 import javax.swing.JComponent;
 import javax.swing.JPanel;
 import javax.swing.JScrollPane;
@@ -31,6 +34,7 @@
 import ca.sqlpower.architect.swingui.ArchitectSwingSession;
 import ca.sqlpower.swingui.DataEntryPanel;

+import com.jgoodies.forms.builder.ButtonBarBuilder2;
 import com.jgoodies.forms.builder.DefaultFormBuilder;
 import com.jgoodies.forms.layout.FormLayout;

@@ -50,13 +54,13 @@
      * of critic settings.
      */
private final List<CriticGroupingPanel> groupingPanels = new ArrayList<CriticGroupingPanel>();
-
+
     public CriticManagerPanel(ArchitectSwingSession session) {

         mainPanel = new JPanel();
DefaultFormBuilder builder = new DefaultFormBuilder(new FormLayout("pref"));

- CriticManager criticManager = session.getWorkspace().getCriticManager(); + final CriticManager criticManager = session.getWorkspace().getCriticManager(); for (CriticGrouping grouping : criticManager.getCriticGroupings()) { CriticGroupingPanel criticGroupingPanel = new CriticGroupingPanel(grouping);
             builder.append(criticGroupingPanel.getPanel());
@@ -66,9 +70,39 @@
         DefaultFormBuilder outerBuilder = new DefaultFormBuilder(
new FormLayout("pref:grow", "min(pref;400dlu):grow"), mainPanel);
         outerBuilder.append(new JScrollPane(builder.getPanel()));
+        outerBuilder.nextLine();
+        ButtonBarBuilder2 buttonBar = new ButtonBarBuilder2();
+        buttonBar.addButton(new AbstractAction("Restore Defaults") {
+            public void actionPerformed(ActionEvent e) {
+                if (doApplyChanges()) {
+                    criticManager.loadDefaults();
+                }
+            }
+        });
+        buttonBar.addButton(new AbstractAction("Set As Defaults") {
+            public void actionPerformed(ActionEvent e) {
+                try {
+                    if (doApplyChanges()) {
+                        criticManager.saveAsDefaults();
+                    }
+                } catch (BackingStoreException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        });
+        buttonBar.addGlue();
+        outerBuilder.append(buttonBar.getPanel());
     }

     public boolean applyChanges() {
+        boolean changesApplied = doApplyChanges();
+        if (changesApplied) {
+            cleanup();
+        }
+        return changesApplied;
+    }
+
+    private boolean doApplyChanges() {
         for (CriticGroupingPanel panel : groupingPanels) {
             if (!panel.applyChanges()) {
                 return false;
@@ -81,6 +115,7 @@
         for (CriticGroupingPanel panel : groupingPanels) {
             panel.discardChanges();
         }
+        cleanup();
     }

     public JComponent getPanel() {
@@ -94,5 +129,9 @@
         return false;
     }

-
-}
+    private void cleanup() {
+        for (CriticGroupingPanel panel : groupingPanels) {
+            panel.cleanup();
+        }
+    }
+}
=======================================
--- /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticSettingsPanel.java Fri Jun 25 11:32:00 2010 +++ /trunk/src/main/java/ca/sqlpower/architect/swingui/critic/CriticSettingsPanel.java Tue Jul 6 10:54:22 2010
@@ -19,12 +19,19 @@

 package ca.sqlpower.architect.swingui.critic;

+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+
 import javax.swing.JComboBox;
 import javax.swing.JComponent;
 import javax.swing.JPanel;

 import ca.sqlpower.architect.ddl.critic.CriticAndSettings;
 import ca.sqlpower.architect.ddl.critic.CriticAndSettings.Severity;
+import ca.sqlpower.object.AbstractSPListener;
+import ca.sqlpower.object.SPListener;
 import ca.sqlpower.swingui.DataEntryPanel;

 import com.jgoodies.forms.builder.DefaultFormBuilder;
@@ -51,6 +58,29 @@
      */
     private final JComboBox severityCombo;

+    /**
+ * The listeners in this list will be notified when there is a change to the + * model that causes the UI to update. Components that may need to repaint
+     * on these changes can listen and be notified here.
+     */
+ private final List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
+
+    /**
+     * Updates the severity combo box due to changes to the model.
+     */
+ private final SPListener severitySettingListener = new AbstractSPListener() {
+        public void propertyChanged(java.beans.PropertyChangeEvent evt) {
+            if (evt.getPropertyName().equals("severity")) {
+                Object oldSeverity = severityCombo.getSelectedItem();
+                severityCombo.setSelectedItem(evt.getNewValue());
+                for (PropertyChangeListener l : listeners) {
+ l.propertyChange(new PropertyChangeEvent(CriticSettingsPanel.this,
+                            "severity", oldSeverity, evt.getNewValue()));
+                }
+            }
+        }
+    };
+
     public CriticSettingsPanel(CriticAndSettings settings) {
         this.settings = settings;

@@ -62,6 +92,8 @@
DefaultFormBuilder builder = new DefaultFormBuilder(new FormLayout("225dlu, 5dlu, pref"), panel);
         builder.append(settings.getName());
         builder.append(severityCombo);
+
+        settings.addSPListener(severitySettingListener);
     }

     public boolean applyChanges() {
@@ -82,4 +114,19 @@
         return false;
     }

-}
+    public void cleanup() {
+        settings.removeSPListener(severitySettingListener);
+    }
+
+    public void addPropertyChangeListener(PropertyChangeListener l) {
+        listeners.add(l);
+    }
+
+    public void removePropertyChangeListener(PropertyChangeListener l) {
+        listeners.remove(l);
+    }
+
+    public CriticAndSettings getSettings() {
+        return settings;
+    }
+}

Reply via email to