1 package com.melloware.jukes.gui.view.editor;
2
3 import java.awt.Color;
4 import java.awt.Component;
5 import java.awt.Container;
6 import java.awt.Cursor;
7 import java.awt.Font;
8 import java.awt.KeyboardFocusManager;
9 import java.beans.PropertyChangeEvent;
10 import java.beans.PropertyChangeListener;
11 import java.text.SimpleDateFormat;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Iterator;
15 import java.util.Locale;
16
17 import javax.swing.BorderFactory;
18 import javax.swing.Icon;
19 import javax.swing.JComboBox;
20 import javax.swing.JComponent;
21 import javax.swing.JLabel;
22 import javax.swing.JPanel;
23 import javax.swing.JTextArea;
24 import javax.swing.JTextField;
25 import javax.swing.JToolBar;
26 import javax.swing.ProgressMonitor;
27 import javax.swing.Timer;
28 import javax.swing.border.Border;
29 import javax.swing.text.JTextComponent;
30
31 import com.jgoodies.forms.builder.PanelBuilder;
32 import com.jgoodies.forms.layout.CellConstraints;
33 import com.jgoodies.forms.layout.FormLayout;
34 import com.jgoodies.uif.action.ActionManager;
35 import com.jgoodies.uif.application.Application;
36 import com.jgoodies.uif.component.ToolBarButton;
37 import com.jgoodies.uifextras.util.UIFactory;
38 import com.jgoodies.validation.view.ValidationComponentUtils;
39 import com.jgoodies.validation.view.ValidationResultViewFactory;
40 import com.melloware.jukes.db.orm.AbstractJukesObject;
41 import com.melloware.jukes.gui.tool.Actions;
42 import com.melloware.jukes.gui.tool.MainModule;
43 import com.melloware.jukes.gui.tool.Resources;
44 import com.melloware.jukes.gui.tool.Settings;
45 import com.melloware.jukes.gui.view.MainFrame;
46 import com.melloware.jukes.gui.view.tasks.UpdateTagsTask;
47 import com.melloware.jukes.gui.view.validation.AbstractValidationModel;
48 import com.melloware.jukes.util.MessageUtil;
49
50
51
52
53
54
55
56
57
58 @SuppressWarnings("PMD")
59 abstract public class AbstractEditor
60 extends JPanel
61 implements Editor {
62
63 protected static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("MMM dd yyyy h:mm a", Locale.US);
64 protected static final Font FONT_ENABLED = new JLabel().getFont();
65 protected static final Font FONT_DISABLED = FONT_ENABLED.deriveFont(FONT_ENABLED.getStyle() ^ Font.BOLD);
66 protected static final Border BORDER_ENABLED = new JTextField().getBorder();
67 protected static final Border BORDER_DISABLED = BorderFactory.createEmptyBorder();
68 protected static final String HINT = "HINT";
69 protected AbstractValidationModel validationModel;
70 protected final Icon icon;
71 protected JComponent hintAreaPane;
72 protected JLabel createdByLabel;
73 protected JLabel createdDateLabel;
74 protected JLabel hintLabel;
75 protected JLabel modifiedByLabel;
76 protected JLabel modifiedDateLabel;
77 protected JTextArea hintArea;
78 protected ProgressMonitor progressMonitor;
79 protected final String titlePrefix;
80 protected Timer timer;
81 protected UpdateTagsTask task;
82 private Object model;
83
84
85
86
87 public AbstractEditor(Icon icon) {
88 this(icon, "");
89 }
90
91
92
93
94
95 public AbstractEditor(String titlePrefix) {
96 this(null, titlePrefix);
97 }
98
99
100
101
102
103 public AbstractEditor(Icon icon, String titlePrefix) {
104 this.icon = icon;
105 this.titlePrefix = titlePrefix;
106 build();
107 }
108
109
110
111
112 abstract public Class getDomainClass();
113
114
115
116
117
118 public JToolBar getHeaderToolBar() {
119 return null;
120 }
121
122
123
124
125 public Icon getIcon() {
126 return icon;
127 }
128
129
130
131
132 public Object getModel() {
133 return model;
134 }
135
136
137
138
139 public AbstractJukesObject getOrmObject() {
140 return (AbstractJukesObject)model;
141 }
142
143
144
145
146 public String getTitle() {
147 return titlePrefix + ' ' + getTitleSuffix();
148 }
149
150
151
152
153
154 public JToolBar getToolBar() {
155 return null;
156 }
157
158
159
160
161
162
163
164 public void setModel(Object newModel) {
165 Object oldModel = getModel();
166 AbstractJukesObject newObject, oldObject;
167 oldObject = (AbstractJukesObject) oldModel;
168 newObject = (AbstractJukesObject) newModel;
169
170 if ((oldModel != null) && (oldModel.equals(newModel)) && (oldObject.getId() == newObject.getId()) ) {
171 this.lock();
172 return;
173 }
174 model = newModel;
175 updateView();
176 this.lock();
177 }
178
179
180
181
182 public void activate() {
183
184 }
185
186
187
188
189 public void commit() {
190 this.lock();
191 }
192
193
194
195
196 public void unlock() {
197 ActionManager.get(Actions.UNLOCK_ID).setEnabled(false);
198 validationModel.updateButtonState(true);
199 final Collection components = getAllComponents(this);
200
201 for (Iterator iter = components.iterator(); iter.hasNext();) {
202 final Component component = (Component) iter.next();
203 if (component instanceof JTextComponent) {
204 final JTextComponent field = (JTextComponent)component;
205
206 if (field.getClientProperty(HINT) != null) {
207 continue;
208 }
209 field.setEnabled(true);
210 field.setBorder(BORDER_ENABLED);
211 field.setOpaque(true);
212 field.setFont(FONT_ENABLED);
213 } else if (component instanceof JComboBox) {
214 final JComboBox field = (JComboBox)component;
215 field.setEnabled(true);
216 field.setVisible(true);
217 } else if (component instanceof JLabel) {
218 final JLabel field = (JLabel)component;
219 if ("GENRE".equalsIgnoreCase(field.getName())) {
220 field.setVisible(false);
221 }
222 } else if (component instanceof ToolBarButton) {
223 final ToolBarButton button = (ToolBarButton)component;
224 button.setVisible(true);
225 }
226 }
227
228 this.updateUI();
229 }
230
231
232
233
234 public void lock() {
235 ActionManager.get(Actions.UNLOCK_ID).setEnabled(true);
236 validationModel.updateButtonState(false);
237 final Collection components = getAllComponents(this);
238
239 for (Iterator iter = components.iterator(); iter.hasNext();) {
240 final Component component = (Component) iter.next();
241 if (component instanceof JTextComponent) {
242 final JTextComponent field = (JTextComponent)component;
243
244 if (field.getClientProperty(HINT) != null) {
245 continue;
246 }
247
248 field.setEnabled(false);
249 field.setDisabledTextColor(Color.BLACK);
250 field.setBorder(BORDER_DISABLED);
251 field.setOpaque(false);
252 field.setFont(FONT_DISABLED);
253 } else if (component instanceof JComboBox) {
254 final JComboBox field = (JComboBox)component;
255 field.setEnabled(false);
256 field.setVisible(false);
257 } else if (component instanceof JLabel) {
258 final JLabel field = (JLabel)component;
259 if ("GENRE".equalsIgnoreCase(field.getName())) {
260 final String text = field.getText().trim();
261 field.setText(" " + text);
262 field.setVisible(true);
263 field.setFont(FONT_DISABLED);
264 }
265 } else if (component instanceof ToolBarButton) {
266 final ToolBarButton button = (ToolBarButton)component;
267 button.setVisible(false);
268 }
269
270 }
271
272 this.updateUI();
273 }
274
275
276
277
278
279
280
281
282 private Collection getAllComponents(Container aTop) {
283 final Component[] comp = aTop.getComponents();
284 final ArrayList list = new ArrayList();
285
286 if (comp.length == 0) {
287 return list;
288 }
289
290 for (int i = 0; i < comp.length; i++) {
291 list.add(comp[i]);
292 if (comp[i] instanceof Container) {
293 list.addAll(getAllComponents((Container)comp[i]));
294 }
295 }
296 return list;
297 }
298
299
300
301
302 public void deactivate() {
303
304
305
306
307
308
309
310
311 if (validationModel.isDirty()) {
312 if (MessageUtil.promptYesNo(getMainFrame(), Resources.getString("messages.promptSaveChanges"))) {
313 this.commit();
314 } else {
315
316 this.rollback();
317 }
318 }
319
320 }
321
322
323
324
325 public void delete() {
326
327 }
328
329
330
331
332 public void findCover() {
333
334 }
335
336
337
338
339 public void renameFiles() {
340
341 }
342
343
344
345
346 public void rollback() {
347
348 this.lock();
349 }
350
351
352
353
354 public void webSearch() {
355
356 }
357
358
359
360
361 public void freeDBSearch() {
362
363 }
364
365
366
367
368
369
370 abstract protected String getTitleSuffix();
371
372
373
374
375 abstract protected void build();
376
377
378
379
380 abstract protected void updateModel();
381
382
383
384
385 abstract protected void updateView();
386
387
388
389
390
391
392 protected MainFrame getMainFrame() {
393 return (MainFrame)Application.getDefaultParentFrame();
394 }
395
396
397
398
399
400
401 protected MainModule getMainModule() {
402 return getMainFrame().getMainModule();
403 }
404
405
406
407
408
409
410 protected Settings getSettings() {
411 return MainModule.SETTINGS;
412 }
413
414
415
416
417
418
419 protected AbstractValidationModel getValidationModel() {
420 return this.validationModel;
421 }
422
423
424
425
426
427
428
429 protected void setBusyCursor(boolean aBusy) {
430 if (aBusy) {
431 getMainFrame().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
432 } else {
433 getMainFrame().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
434 }
435 }
436
437
438
439
440
441
442
443 protected JComponent buildAuditInfoPanel() {
444
445 createdDateLabel = UIFactory.createBoldLabel("");
446 createdByLabel = UIFactory.createBoldLabel("");
447 modifiedDateLabel = UIFactory.createBoldLabel("");
448 modifiedByLabel = UIFactory.createBoldLabel("");
449
450 FormLayout layout = new FormLayout("right:max(40dlu;pref), 3dlu, 100dlu, 7dlu, "
451 + "right:max(40dlu;pref), 3dlu, 100dlu", "p, 3dlu, p, 3dlu, p, 3dlu, p");
452 PanelBuilder builder = new PanelBuilder(layout);
453 CellConstraints cc = new CellConstraints();
454
455 int row = 1;
456 builder.addLabel(Resources.getString("label.createdby") + ": ", cc.xy(1, row));
457 builder.add(createdByLabel, cc.xy(3, row));
458 builder.addLabel(Resources.getString("label.createddate") + ": ", cc.xy(5, row));
459 builder.add(createdDateLabel, cc.xy(7, row++));
460 row++;
461
462 builder.addLabel(Resources.getString("label.modifiedby") + ": ", cc.xy(1, row));
463 builder.add(modifiedByLabel, cc.xy(3, row));
464 builder.addLabel(Resources.getString("label.modifieddate") + ": ", cc.xy(5, row));
465 builder.add(modifiedDateLabel, cc.xy(7, row++));
466 row++;
467
468 JComponent component = builder.getPanel();
469 component.setVisible(this.getSettings().isAuditInfo());
470
471 return component;
472 }
473
474
475
476
477
478
479 protected JComponent buildHintAreaPane() {
480 hintLabel = new JLabel(ValidationResultViewFactory.getInfoIcon());
481 hintArea = new JTextArea(1, 38);
482 hintArea.putClientProperty(HINT, HINT);
483 hintArea.setEditable(false);
484 hintArea.setOpaque(false);
485
486 FormLayout layout = new FormLayout("pref, 2dlu, default", "pref");
487 PanelBuilder builder = new PanelBuilder(layout);
488 CellConstraints cc = new CellConstraints();
489 builder.add(hintLabel, cc.xy(1, 1));
490 builder.add(hintArea, cc.xy(3, 1));
491
492 hintAreaPane = builder.getPanel();
493 hintAreaPane.setVisible(false);
494 return hintAreaPane;
495 }
496
497
498
499
500
501
502 protected boolean hasErrors() {
503 return getValidationModel().getValidationResultModel().getResult().hasErrors();
504 }
505
506
507
508
509 protected void initEventHandling() {
510 KeyboardFocusManager.getCurrentKeyboardFocusManager().addPropertyChangeListener(new FocusChangeHandler());
511 }
512
513
514
515
516
517 private final class FocusChangeHandler
518 implements PropertyChangeListener {
519
520 public void propertyChange(PropertyChangeEvent evt) {
521 String propertyName = evt.getPropertyName();
522 if (!"permanentFocusOwner".equals(propertyName)) {
523 return;
524 }
525 Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
526 String focusHint = (focusOwner instanceof JComponent)
527 ? (String)ValidationComponentUtils.getInputHint((JComponent)focusOwner) : null;
528
529 hintArea.setText(focusHint);
530 hintAreaPane.setVisible(focusHint != null);
531 }
532 }
533
534 }