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