View Javadoc

1   package com.melloware.jukes.gui.tool;
2   
3   import java.net.URL;
4   import java.util.HashMap;
5   import java.util.Map;
6   
7   import javax.swing.event.TreeSelectionEvent;
8   import javax.swing.event.TreeSelectionListener;
9   import javax.swing.tree.DefaultMutableTreeNode;
10  import javax.swing.tree.DefaultTreeModel;
11  import javax.swing.tree.DefaultTreeSelectionModel;
12  import javax.swing.tree.TreeModel;
13  import javax.swing.tree.TreeNode;
14  import javax.swing.tree.TreePath;
15  import javax.swing.tree.TreeSelectionModel;
16  
17  import org.apache.commons.logging.Log;
18  import org.apache.commons.logging.LogFactory;
19  
20  import com.melloware.jukes.gui.tool.help.HelpNode;
21  import com.melloware.jukes.gui.tool.help.HelpSets;
22  
23  /**
24   * Provides bound bean properties for the help tree model,
25   * the help page and the help visibility.
26   * <p>
27   * Copyright (c) 1999-2007 Melloware, Inc. <http://www.melloware.com>
28   * @author Emil A. Lefkof III <info@melloware.com>
29   * @version 4.0
30   */
31  public final class DynamicHelpModule
32      extends com.jgoodies.binding.beans.Model {
33  
34      private static final Log LOG = LogFactory.getLog(DynamicHelpModule.class);
35  
36      public static final String PROPERTYNAME_HELP_TREE_MODEL = "helpTreeModel";
37      public static final String PROPERTYNAME_HELP_PAGE = "helpPage";
38      public static final String PROPERTYNAME_HELP_VISIBLE = "helpVisible";
39  
40      /**
41       * Determines whether the dynamic help shall be displayed or hidden.
42       *
43       * @see #isHelpVisible()
44       * @see #setHelpVisible(boolean)
45       */
46      private boolean helpVisible;
47  
48      /**
49       * Maps domain classes to help roots.
50       */
51      private final Map helpRegistry;
52  
53      /**
54       * Holds the model for the help tree.
55       * It changes everytime the selection changes.
56       *
57       * @see #getHelpTreeModel()
58       * @see #getHelpTreeSelectionModel()
59       */
60      private TreeModel helpTreeModel;
61  
62      /**
63       * Refers to the single selection model for the help tree.
64       * The selection is reset if the help tree model changes.
65       *
66       * @see #getHelpTreeSelectionModel()
67       * @see #getHelpTreeModel()
68       */
69      private final TreeSelectionModel helpTreeSelectionModel;
70  
71      /**
72       * Holds the URL for the currently selected help page.
73       *
74       * @see #getHelpPage()
75       */
76      private URL helpPage;
77  
78      /**
79       * Constructs a <code>DynamicHelpModule</code>
80       * with the welcome help set preselected.
81       */
82      DynamicHelpModule() {
83          helpRegistry = new HashMap();
84  
85          setHelpSet(HelpSets.WELCOME_HELP_SET);
86          helpTreeSelectionModel = new DefaultTreeSelectionModel();
87          helpTreeSelectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
88          helpTreeSelectionModel.addTreeSelectionListener(new HelpTreeSelectionChangeHandler());
89      }
90  
91      /**
92       * Returns the current help page, a URL. This page
93       * will be updated if the selection in the help tree changes.
94       *
95       * @return the URL for the currently selected help page.
96       */
97      public URL getHelpPage() {
98          return helpPage;
99      }
100 
101     /**
102      * Returns the tree model for the help tree.
103      *
104      * @return the tree model for the help tree.
105      */
106     public TreeModel getHelpTreeModel() {
107         return helpTreeModel;
108     }
109 
110     /**
111      * Returns the fixed selection model for the navigation tree.
112      *
113      * @return the fixed selection model for the navigation tree.
114      */
115     public TreeSelectionModel getHelpTreeSelectionModel() {
116         return helpTreeSelectionModel;
117     }
118 
119     /**
120      * Sets a new visibility for the help viewer.
121      *
122      * @param newVisibility   the help page to set
123      *
124      * @see #isHelpVisible()
125      */
126     public void setHelpVisible(boolean newVisibility) {
127         boolean oldVisibility = isHelpVisible();
128         helpVisible = newVisibility;
129         firePropertyChange(PROPERTYNAME_HELP_VISIBLE, oldVisibility, newVisibility);
130     }
131 
132     /**
133      * Answers whether the dynamic help is visible or not.
134      *
135      * @return true if the help viewer is visible, false if hidden.
136      */
137     public boolean isHelpVisible() {
138         return helpVisible;
139     }
140 
141     /**
142      * Registers a help tree for a domain class.
143      */
144     @SuppressWarnings("unchecked")
145     public void registerHelp(Class domainClass, TreeNode node) {
146         Object oldValue = helpRegistry.put(domainClass, node);
147         if (oldValue != null) {
148             LOG.warn("Duplicate help registered for class " + domainClass);
149         }
150     }
151 
152     void updateHelpSet(Object selection) {
153         TreeNode helpSet = lookupHelpSet(selection.getClass());
154         if (helpSet != null) {
155             setHelpSet(helpSet);
156         }
157     }
158 
159     /**
160      * Sets a URL as new help page. This method is invoked
161      * by the HelpTreeSelectionChangeHandler that observes changes in
162      * the selection of the help tree.<p>
163      *
164      * Sets the help to visible.
165      *
166      * @param newHelpPage   the help page to set
167      *
168      * @see #getHelpPage()
169      */
170     private void setHelpPage(URL newHelpPage) {
171         URL oldHelpPage = getHelpPage();
172         helpPage = newHelpPage;
173         if (equals(oldHelpPage, newHelpPage)) {
174             return;
175         }
176 
177         firePropertyChange(PROPERTYNAME_HELP_PAGE, oldHelpPage, newHelpPage);
178         setHelpVisible(true);
179     }
180 
181     private void setHelpSet(TreeNode helpSet) {
182         setHelpTreeModel(new DefaultTreeModel(helpSet));
183     }
184 
185     /**
186      * Sets a new tree model for the help tree.
187      *
188      * @param newModel  the new tree model to set
189      */
190     private void setHelpTreeModel(TreeModel newModel) {
191         TreeModel oldModel = getHelpTreeModel();
192         helpTreeModel = newModel;
193         firePropertyChange(PROPERTYNAME_HELP_TREE_MODEL, oldModel, newModel);
194     }
195 
196     /**
197      * Returns the <code>HelpNode</code> that has been registered
198      * for the given domain object class, <code>null</code> if none.
199      *
200      * @param domainClass   the class associated with the editor to lookup
201      * @return the editor associated with the given domain class
202      */
203     private TreeNode lookupHelpSet(Class domainClass) {
204         return (TreeNode)helpRegistry.get(domainClass);
205     }
206 
207     // Listens to changes in the help tree node selection
208     // and updates the selection.
209     private class HelpTreeSelectionChangeHandler
210         implements TreeSelectionListener {
211 
212         /**
213          * The selected node in the help tree has changed.
214          * Updates this module's help page.<p>
215          *
216          * Does nothing if the new tree selection is <code>null</code>.
217          *
218          * @param evt    the event that describes the change
219          */
220         public void valueChanged(TreeSelectionEvent evt) {
221             TreePath path = evt.getPath();
222             DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode)path.getLastPathComponent();
223             HelpNode helpNode = (HelpNode)selectedNode.getUserObject();
224             if ((null == helpNode) || helpNode.isChapter()) {
225                 return;
226             }
227 
228             setHelpPage(helpNode.getURL());
229         }
230 
231     }
232 
233 }