1 package com.melloware.jukes.gui.tool;
2
3 import java.util.Enumeration;
4 import java.util.prefs.Preferences;
5
6 import javax.swing.event.TreeSelectionEvent;
7 import javax.swing.event.TreeSelectionListener;
8 import javax.swing.tree.DefaultMutableTreeNode;
9 import javax.swing.tree.DefaultTreeModel;
10 import javax.swing.tree.DefaultTreeSelectionModel;
11 import javax.swing.tree.TreeModel;
12 import javax.swing.tree.TreeNode;
13 import javax.swing.tree.TreePath;
14 import javax.swing.tree.TreeSelectionModel;
15
16 import org.apache.commons.lang.StringUtils;
17 import org.apache.commons.logging.Log;
18 import org.apache.commons.logging.LogFactory;
19
20 import com.jgoodies.binding.beans.Model;
21 import com.jgoodies.uif.application.Application;
22 import com.jgoodies.uifextras.convenience.SetupManager;
23 import com.melloware.jukes.db.orm.AbstractJukesObject;
24 import com.melloware.jukes.db.orm.Artist;
25 import com.melloware.jukes.db.orm.Catalog;
26 import com.melloware.jukes.db.orm.Disc;
27 import com.melloware.jukes.db.orm.Track;
28 import com.melloware.jukes.gui.view.node.AbstractTreeNode;
29 import com.melloware.jukes.gui.view.node.ArtistNode;
30 import com.melloware.jukes.gui.view.node.DiscNode;
31 import com.melloware.jukes.gui.view.node.NavigationNode;
32 import com.melloware.jukes.gui.view.node.RootNode;
33 import com.melloware.jukes.gui.view.node.TrackNode;
34
35
36
37
38
39
40
41
42
43
44
45
46
47 public final class MainModule
48 extends Model {
49
50 private static final Log LOG = LogFactory.getLog(MainModule.class);
51
52 public static final String PROPERTYNAME_CATALOG = "catalog";
53 public static final String PROPERTYNAME_HIGHLIGHT = "highlight";
54 public static final String PROPERTYNAME_SELECTION = "selection";
55 public static final String PROPERTYNAME_SELECTION_TYPE = "selectionType";
56 public static final String PROPERTYNAME_NAVIGATION_TREE_MODEL = "navigationTreeModel";
57
58
59
60
61
62
63 public static final Settings SETTINGS = new Settings();
64
65
66
67
68
69
70
71 private Catalog catalog;
72
73
74
75
76
77
78
79 private Class selectionType;
80
81
82
83
84
85
86
87
88
89
90
91 private NavigationNode selectedNode;
92
93
94
95
96
97
98
99 private Object selection;
100
101
102
103
104
105
106
107
108 private TreeModel navigationTreeModel;
109
110
111
112
113
114
115
116
117 private final TreeSelectionModel navigationTreeSelectionModel = new DefaultTreeSelectionModel();
118
119
120
121
122
123 public MainModule() {
124 LOG.debug("MainModule created.");
125 restoreState();
126 }
127
128
129
130
131
132
133 public Catalog getCatalog() {
134 return catalog;
135 }
136
137
138
139
140
141
142 public TreeModel getNavigationTreeModel() {
143 return navigationTreeModel;
144 }
145
146
147
148
149
150
151 public TreeSelectionModel getNavigationTreeSelectionModel() {
152 return navigationTreeSelectionModel;
153 }
154
155
156
157
158
159
160 public NavigationNode getSelectedNode() {
161 return this.selectedNode;
162 }
163
164
165
166
167
168
169
170
171
172
173
174 public Object getSelection() {
175 return selection;
176 }
177
178
179
180
181
182
183
184
185 public Class getSelectionType() {
186 return selectionType;
187 }
188
189
190
191
192
193
194
195
196 public void setCatalog(final Catalog newCatalog) {
197 if (newCatalog == null) {
198 throw new IllegalArgumentException("The catalog must not be null.");
199 }
200
201 final Catalog oldCatalog = getCatalog();
202 catalog = newCatalog;
203 firePropertyChange(PROPERTYNAME_CATALOG, oldCatalog, newCatalog);
204 setNavigationTreeModel(createNavigationTreeModel(newCatalog));
205
206 }
207
208
209
210
211
212
213 public boolean isCatalogFilePathValid() {
214 return false;
215 }
216
217
218
219
220
221
222 public boolean hasCatalog() {
223 return getCatalog() != null;
224 }
225
226
227
228
229
230
231
232 public void refreshSelection(final Object domainObject, final String operation) {
233 if (selectedNode == null) {
234 return;
235 }
236 final DefaultTreeModel treeModel = ((DefaultTreeModel)getNavigationTreeModel());
237 if (Resources.NODE_CHANGED.equals(operation)) {
238 treeModel.nodeChanged(selectedNode);
239 LOG.debug("Tree Node changed.");
240 } else if (Resources.NODE_DELETED.equals(operation)) {
241 final TreeNode parent = selectedNode.getParent();
242 if (parent != null) {
243 LOG.debug("Tree Node Deleted");
244 treeModel.removeNodeFromParent((DefaultMutableTreeNode)selectedNode);
245 setSelectedNode((AbstractTreeNode)parent);
246 }
247 }
248 }
249
250
251
252
253
254
255 public void refreshTree() {
256 setCatalog(new Catalog(SETTINGS.getFilter()));
257 firePropertyChange(PROPERTYNAME_SELECTION, selection, null);
258 }
259
260
261
262
263 public void restoreState() {
264 SETTINGS.restoreFrom(Application.getUserPreferences());
265 }
266
267
268
269
270
271
272
273
274 public void selectNodeInTree(final Object newSelection) {
275 final AbstractJukesObject selection = (AbstractJukesObject)newSelection;
276 AbstractTreeNode node = null;
277 String artistName = null;
278 String discName = null;
279 String trackName = null;
280
281 if (selection instanceof Artist) {
282 artistName = selection.getName();
283 } else if (selection instanceof Disc) {
284 final Disc disc = (Disc)selection;
285 artistName = disc.getArtist().getName();
286 discName = selection.getName();
287 } else if (selection instanceof Track) {
288 final Track track = (Track)selection;
289 artistName = track.getDisc().getArtist().getName();
290 discName = track.getDisc().getName();
291 trackName = selection.getName();
292 }
293
294 final DefaultTreeModel treeModel = ((DefaultTreeModel)navigationTreeModel);
295 final AbstractTreeNode root = (AbstractTreeNode)treeModel.getRoot();
296
297
298 ArtistNode artistNode = null;
299 if (StringUtils.isNotBlank(artistName)) {
300 final Enumeration artistEnum = root.children();
301 while (artistEnum.hasMoreElements()) {
302 artistNode = (ArtistNode)artistEnum.nextElement();
303 if (StringUtils.equalsIgnoreCase(artistNode.toString(), artistName)) {
304 node = artistNode;
305 break;
306 }
307 }
308 }
309
310
311 DiscNode discNode = null;
312 if ((StringUtils.isNotBlank(discName)) && (artistNode != null)) {
313 final Enumeration discEnum = artistNode.children();
314 while (discEnum.hasMoreElements()) {
315 discNode = (DiscNode)discEnum.nextElement();
316 if (StringUtils.equalsIgnoreCase(discNode.toString(), discName)) {
317 node = discNode;
318 break;
319 }
320 }
321 }
322
323
324 TrackNode trackNode = null;
325 if ((StringUtils.isNotBlank(trackName)) && (discNode != null)) {
326 final Enumeration trackEnum = discNode.children();
327 while (trackEnum.hasMoreElements()) {
328 trackNode = (TrackNode)trackEnum.nextElement();
329 if (StringUtils.equalsIgnoreCase(trackNode.toString(), trackName)) {
330 node = trackNode;
331 break;
332 }
333 }
334 }
335
336 if (node != null) {
337
338 setSelectedNode(node);
339
340
341 firePropertyChange(PROPERTYNAME_HIGHLIGHT, null, "Highlight");
342 }
343 }
344
345
346
347
348 public void storeState() {
349 final Preferences prefs = Application.getUserPreferences();
350 SETTINGS.storeIn(prefs);
351 SetupManager.incrementUsageCounter();
352 }
353
354
355
356
357
358
359 private void setNavigationTreeModel(final TreeModel newModel) {
360 final TreeModel oldModel = getNavigationTreeModel();
361 navigationTreeModel = newModel;
362 firePropertyChange(PROPERTYNAME_NAVIGATION_TREE_MODEL, oldModel, newModel);
363 }
364
365
366
367
368
369
370
371
372
373 private void setSelectedNode(final NavigationNode newSelectedNode) {
374 final NavigationNode oldSelectedNode = selectedNode;
375 selectedNode = newSelectedNode;
376 setSelection(newSelectedNode.getModel());
377 ((DefaultTreeModel)getNavigationTreeModel()).nodeChanged(oldSelectedNode);
378 }
379
380
381
382
383
384
385
386
387
388
389 private void setSelection(final Object newSelection) {
390 final Object oldSelection = getSelection();
391 selection = newSelection;
392 setSelectionType(newSelection.getClass());
393 firePropertyChange(PROPERTYNAME_SELECTION, oldSelection, newSelection);
394 }
395
396
397
398
399
400
401
402
403
404 private void setSelectionType(final Class newSelectionType) {
405 final Class oldSelectionType = getSelectionType();
406 selectionType = newSelectionType;
407 if (equals(oldSelectionType, newSelectionType)) {
408 return;
409 }
410
411 firePropertyChange(PROPERTYNAME_SELECTION_TYPE, oldSelectionType, newSelectionType);
412 }
413
414
415
416
417
418
419
420
421 private TreeModel createNavigationTreeModel(final Catalog catalog) {
422 final RootNode rootNode = new RootNode(catalog);
423 rootNode.setSettings(SETTINGS);
424 final DefaultTreeModel model = new DefaultTreeModel(rootNode);
425 navigationTreeSelectionModel.setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
426 navigationTreeSelectionModel.addTreeSelectionListener(new NavigationTreeSelectionChangeHandler());
427 return model;
428 }
429
430
431
432 private class NavigationTreeSelectionChangeHandler
433 implements TreeSelectionListener {
434
435
436
437
438
439
440
441
442
443
444 public void valueChanged(final TreeSelectionEvent evt) {
445 final TreePath path = evt.getPath();
446 final NavigationNode aSelectedNode = (NavigationNode)path.getLastPathComponent();
447 if (aSelectedNode != null) {
448 setSelectedNode(aSelectedNode);
449 }
450 }
451
452 }
453
454 }