1 package com.melloware.jukes.gui.view.dialogs;
2
3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.Dimension;
6 import java.awt.Frame;
7 import java.awt.event.ActionEvent;
8 import java.util.Collection;
9 import java.util.Iterator;
10
11 import javax.swing.AbstractAction;
12 import javax.swing.Action;
13 import javax.swing.DefaultListModel;
14 import javax.swing.JButton;
15 import javax.swing.JComponent;
16 import javax.swing.JList;
17 import javax.swing.JPanel;
18 import javax.swing.JScrollPane;
19 import javax.swing.JSplitPane;
20 import javax.swing.JTable;
21 import javax.swing.ListSelectionModel;
22 import javax.swing.RowSorter;
23 import javax.swing.event.ListSelectionEvent;
24 import javax.swing.event.ListSelectionListener;
25 import javax.swing.table.TableModel;
26 import javax.swing.table.TableRowSorter;
27
28 import org.apache.commons.lang.StringUtils;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31
32 import com.jgoodies.forms.builder.PanelBuilder;
33 import com.jgoodies.forms.factories.Borders;
34 import com.jgoodies.forms.factories.ButtonBarFactory;
35 import com.jgoodies.forms.layout.CellConstraints;
36 import com.jgoodies.forms.layout.FormLayout;
37 import com.jgoodies.uif.AbstractDialog;
38 import com.jgoodies.uif.application.Application;
39 import com.jgoodies.uif.panel.SimpleInternalFrame;
40 import com.jgoodies.uif.util.Resizer;
41 import com.jgoodies.uif.util.Worker;
42 import com.jgoodies.uifextras.panel.HeaderPanel;
43 import com.jgoodies.uifextras.util.UIFactory;
44 import com.melloware.jukes.exception.WebServiceException;
45 import com.melloware.jukes.file.FileUtil;
46 import com.melloware.jukes.gui.tool.Resources;
47 import com.melloware.jukes.gui.tool.Settings;
48 import com.melloware.jukes.gui.view.MainFrame;
49 import com.melloware.jukes.gui.view.component.EnhancedTableHeader;
50 import com.melloware.jukes.gui.view.component.ExportableTable;
51 import com.melloware.jukes.util.GuiUtil;
52 import com.melloware.jukes.util.MessageUtil;
53 import com.melloware.jukes.ws.FreeDBItem;
54 import com.melloware.jukes.ws.FreeDBSearch;
55
56
57
58
59
60
61
62 public final class FreeDBDialog extends AbstractDialog {
63
64 private static final Log LOG = LogFactory.getLog(WebSearchDialog.class);
65 private FreeDBItem selection;
66 private Collection selectedTracks;
67 private DefaultListModel listModel;
68 private final EnhancedTableHeader header;
69 private final ExportableTable resultsTable;
70 private JButton buttonApply;
71 private JButton buttonCancel;
72 private JButton buttonSearch;
73 private JButton buttonStop;
74 private JComponent buttonBar;
75 private JComponent splitPane;
76 private JList list;
77 private Object[] results;
78 private String selectedArtist;
79 private String selectedDisc;
80 private String selectedYear;
81 private String selectedGenre;
82 private RowSorter<TableModel> sorter;
83 private FreeDBTableModel tableModel;
84 private Worker worker;
85 private float[] trackLength;
86
87
88
89
90
91 public FreeDBDialog(Frame owner, Settings settings) {
92 super(owner);
93 LOG.debug("FreeBD Search Dialog created.");
94 resultsTable = new ExportableTable();
95 resultsTable.setEvenColor(settings.getRowColorEven());
96 resultsTable.setOddColor(settings.getRowColorOdd());
97 header = new EnhancedTableHeader(resultsTable.getColumnModel(), resultsTable);
98 resultsTable.setTableHeader(header);
99 this.setPreferredSize(new Dimension(720, 570));
100 }
101
102
103
104
105
106
107 public String getSelectedArtist() {
108 return FileUtil.capitalize(this.selectedArtist);
109 }
110
111
112
113
114
115
116 public String getSelectedDisc() {
117 return FileUtil.capitalize(this.selectedDisc);
118 }
119
120
121
122
123
124
125 public String getSelectedGenre() {
126 return this.selectedGenre;
127 }
128
129
130
131
132
133
134 public Collection getSelectedTracks() {
135 return this.selectedTracks;
136 }
137
138
139
140
141
142
143 public String getSelectedYear() {
144 return this.selectedYear;
145 }
146
147
148
149
150
151
152 public void setTrackLength(float[] aTrackLength) {
153 this.trackLength = aTrackLength;
154 }
155
156
157
158
159
160
161 public void setSelectedArtist(String aSelectedArtist) {
162 this.selectedArtist = aSelectedArtist;
163 }
164
165
166
167
168
169
170 public void setSelectedDisc(String aSelectedDisc) {
171 this.selectedDisc = StringUtils.substringBeforeLast(aSelectedDisc, " - ");
172 }
173
174
175
176
177
178
179 public void setSelectedGenre(String aSelectedGenre) {
180 this.selectedGenre = aSelectedGenre;
181 }
182
183
184
185
186
187
188 public void setSelectedTracks(Collection aSelectedTracks) {
189 this.selectedTracks = aSelectedTracks;
190 }
191
192
193
194
195
196
197 public void setSelectedYear(String aSelectedYear) {
198 this.selectedYear = aSelectedYear;
199 }
200
201
202
203
204
205 @Override
206 public void doApply() {
207 LOG.debug("Select pressed.");
208 FreeDBItem item = selection;
209 setSelectedArtist(item.getArtist());
210 setSelectedDisc(item.getDisc());
211 setSelectedYear(item.getReleaseYear());
212 setSelectedGenre(item.getGenre());
213 setSelectedTracks(item.getTracks());
214 super.doClose();
215 }
216
217
218
219
220
221 @Override
222 public void doCancel() {
223 LOG.debug("Cancel Pressed.");
224 super.doCancel();
225 }
226
227
228
229
230 public void doSearch() {
231 LOG.debug("Searching...");
232
233 GuiUtil.setBusyCursor(this, true);
234 buttonSearch.setEnabled(false);
235 buttonCancel.setEnabled(false);
236 buttonApply.setEnabled(false);
237 buttonStop.setEnabled(true);
238
239
240
241
242
243
244
245 worker = new Worker() {
246 @Override
247 public Object construct() {
248 return doWork();
249 }
250
251 @Override
252 public void finished() {
253 threadFinished(get());
254 }
255 };
256 worker.start();
257
258 }
259
260
261
262
263 public void doStop() {
264 LOG.debug("Stopping...");
265 GuiUtil.setBusyCursor(this, false);
266 worker.interrupt();
267 buttonSearch.setEnabled(true);
268 buttonCancel.setEnabled(true);
269 buttonStop.setEnabled(false);
270 }
271
272
273
274
275
276 @Override
277 protected JComponent buildContent() {
278 JPanel content = new JPanel(new BorderLayout());
279 JButton[] buttons = new JButton[2];
280 JButton button = createApplyButton();
281 button.setText(Resources.getString("label.Select"));
282 button.setEnabled(false);
283 buttonApply = button;
284 buttonCancel = createCancelButton();
285 buttonCancel.setText(Resources.getString("label.Cancel"));
286 buttons[0] = buttonApply;
287 buttons[1] = buttonCancel;
288 buttonBar = ButtonBarFactory.buildRightAlignedBar(buttons);
289 splitPane = buildSplitPane();
290 content.add(splitPane, BorderLayout.CENTER);
291 content.add(buttonBar, BorderLayout.SOUTH);
292 return content;
293 }
294
295
296
297
298
299 @Override
300 protected JComponent buildHeader() {
301 return new HeaderPanel(Resources.getString("label.FreeDBSearch"), Resources
302 .getString("label.FreeDBSearchMessage"), Resources.FREE_DB_ICON);
303 }
304
305
306
307
308
309 @Override
310 protected void resizeHook(JComponent component) {
311 Resizer.ONE2ONE.resizeDialogContent(component);
312 }
313
314
315
316
317
318
319 private JComponent buildCriteria() {
320 FormLayout layout = new FormLayout("right:max(14dlu;pref), fill:pref:grow", "p");
321
322 PanelBuilder builder = new PanelBuilder(layout);
323 CellConstraints cc = new CellConstraints();
324
325 JButton[] buttons = new JButton[2];
326
327
328 Action search = new AbstractAction(Resources.getString("label.Search"), Resources.THREAD_START_ICON) {
329
330 public void actionPerformed(ActionEvent evt) {
331 doSearch();
332 }
333 };
334 buttonSearch = new JButton(search);
335
336 Action stop = new AbstractAction(Resources.getString("label.Stop"), Resources.THREAD_STOP_ICON) {
337
338 public void actionPerformed(ActionEvent evt) {
339 doStop();
340 }
341 };
342 buttonStop = new JButton(stop);
343 buttonStop.setEnabled(false);
344
345 buttons[0] = buttonSearch;
346 buttons[1] = buttonStop;
347 JPanel searchButtonBar = ButtonBarFactory.buildCenteredBar(buttons);
348
349 builder.add(searchButtonBar, cc.xyw(1, 1, 2));
350 return builder.getPanel();
351 }
352
353
354
355
356
357
358 private JComponent buildResultsPanel() {
359 final Component dialog = this;
360
361 resultsTable.setShowGrid(false);
362 resultsTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
363 resultsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
364
365 ListSelectionModel rowSM = resultsTable.getSelectionModel();
366 rowSM.addListSelectionListener(new ListSelectionListener() {
367 public void valueChanged(ListSelectionEvent e) {
368
369 if (e.getValueIsAdjusting()) {
370 return;
371 }
372
373 ListSelectionModel lsm = (ListSelectionModel) e.getSource();
374 if (lsm.isSelectionEmpty()) {
375 selection = null;
376 buttonApply.setEnabled(false);
377 listModel.removeAllElements();
378 } else {
379 GuiUtil.setBusyCursor(dialog, true);
380 try {
381 int selectedRow = resultsTable.getSelectedRow();
382 selectedRow = sorter.convertRowIndexToModel(selectedRow);
383 selection = (FreeDBItem) results[selectedRow];
384 buttonApply.setEnabled(true);
385 listModel.removeAllElements();
386 int count = 0;
387 for (Iterator iter = selection.getTracks().iterator(); iter.hasNext();) {
388 String element = (String) iter.next();
389 count++;
390 listModel.addElement(count + ". " + element);
391 }
392 } catch (Exception ex) {
393 final MainFrame mainFrame = (MainFrame) Application.getDefaultParentFrame();
394 LOG.error("RuntimeException", ex);
395 MessageUtil.showError(mainFrame, "RuntimeException");
396 } finally {
397 GuiUtil.setBusyCursor(dialog, false);
398 }
399 }
400 }
401 });
402
403
404 listModel = new DefaultListModel();
405 list = new JList(listModel);
406 list.setFocusable(false);
407 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
408 list.setSelectedIndex(0);
409 list.setVisibleRowCount(7);
410 JScrollPane listScrollPane = UIFactory.createStrippedScrollPane(list);
411 listScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
412 listScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
413 JPanel previewPanel = new JPanel(new BorderLayout());
414 previewPanel.add(listScrollPane, BorderLayout.CENTER);
415 final SimpleInternalFrame previewer = new SimpleInternalFrame(Resources.getString("label.tracks"));
416 previewer.add(previewPanel);
417 previewer.setPreferredSize(new Dimension(150, 350));
418
419 JComponent resultsPane = UIFactory.createTablePanel(resultsTable);
420 resultsPane.setPreferredSize(new Dimension(300, 350));
421
422
423 FormLayout layout = new FormLayout("fill:pref:grow, right:max(14dlu;pref)", "p");
424 layout.setRowGroups(new int[][] { { 1 } });
425 PanelBuilder builder = new PanelBuilder(layout);
426 CellConstraints cc = new CellConstraints();
427 builder.add(resultsPane, cc.xy(1, 1));
428 builder.add(previewer, cc.xy(2, 1));
429 builder.getPanel().setPreferredSize(new Dimension(450, 350));
430 return builder.getPanel();
431 }
432
433
434
435
436
437 private JComponent buildSplitPane() {
438 splitPane = UIFactory.createStrippedSplitPane(JSplitPane.VERTICAL_SPLIT, buildCriteria(), buildResultsPanel(),
439 0.25);
440 splitPane.setPreferredSize(new Dimension(630, 470));
441 splitPane.setBorder(Borders.DIALOG_BORDER);
442 return splitPane;
443 }
444
445
446
447
448
449 private Object doWork() {
450 Object result = null;
451 try {
452
453 try {
454 result = FreeDBSearch.findItemsAtFreeDB(trackLength);
455 } catch (WebServiceException ex) {
456 String message = Resources.getString("messages.ErrorQueryingWeb") + "\n\n" + ex.getMessage();
457 LOG.error(message);
458 throw new InterruptedException(message);
459 }
460
461 if (Thread.interrupted()) {
462 LOG.debug("Thread interrupted.");
463 throw new InterruptedException();
464 }
465
466 } catch (InterruptedException e) {
467
468 return result;
469 }
470 return result;
471 }
472
473
474
475
476
477
478 private void threadFinished(Object result) {
479 if (LOG.isDebugEnabled()) {
480 LOG.debug("Thread Finished");
481 }
482 buttonSearch.setEnabled(true);
483 buttonCancel.setEnabled(true);
484 buttonStop.setEnabled(false);
485 GuiUtil.setBusyCursor(this, false);
486
487 if (result == null) {
488 results = null;
489 tableModel = new FreeDBTableModel(results);
490 tableModel.setData(null);
491 tableModel.fireTableDataChanged();
492 } else {
493 final Collection items = (Collection) result;
494 results = items.toArray();
495 tableModel = new FreeDBTableModel(results);
496 sorter = new TableRowSorter<TableModel>(tableModel);
497 resultsTable.setModel(tableModel);
498 resultsTable.setRowSorter(sorter);
499 header.autoSizeColumns();
500 }
501
502 resultsTable.updateUI();
503 splitPane.updateUI();
504 }
505
506 }