1 package com.melloware.jukes.gui.view.dialogs;
2
3 import java.awt.BorderLayout;
4 import java.awt.EventQueue;
5 import java.awt.Frame;
6 import java.util.Collection;
7 import java.util.Iterator;
8
9 import javax.swing.DefaultListModel;
10 import javax.swing.JButton;
11 import javax.swing.JComponent;
12 import javax.swing.JList;
13 import javax.swing.JPanel;
14 import javax.swing.JProgressBar;
15 import javax.swing.JScrollPane;
16 import javax.swing.ListSelectionModel;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20
21 import com.jgoodies.forms.builder.PanelBuilder;
22 import com.jgoodies.forms.factories.Borders;
23 import com.jgoodies.forms.factories.ButtonBarFactory;
24 import com.jgoodies.forms.layout.CellConstraints;
25 import com.jgoodies.forms.layout.FormLayout;
26 import com.jgoodies.uif.AbstractDialog;
27 import com.jgoodies.uif.action.ActionManager;
28 import com.jgoodies.uif.util.Worker;
29 import com.jgoodies.uifextras.panel.HeaderPanel;
30 import com.jgoodies.validation.Severity;
31 import com.jgoodies.validation.ValidationMessage;
32 import com.melloware.jukes.db.HibernateDao;
33 import com.melloware.jukes.db.orm.Disc;
34 import com.melloware.jukes.file.MusicDirectory;
35 import com.melloware.jukes.gui.tool.Actions;
36 import com.melloware.jukes.gui.tool.Resources;
37 import com.melloware.jukes.gui.view.component.MessageCellRenderer;
38 import com.melloware.jukes.util.JukesValidationMessage;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53 public final class DiscRemoveDialog
54 extends AbstractDialog {
55
56 private static final Log LOG = LogFactory.getLog(DiscRemoveDialog.class);
57 private DefaultListModel listModel;
58 private JButton buttonApply;
59 private JButton buttonCancel;
60 private JButton buttonClose;
61 private JComponent buttonBar;
62 private JList list;
63 private JPanel panel;
64 private JProgressBar progressBar;
65 private Worker worker;
66
67
68
69
70
71
72 public DiscRemoveDialog(Frame owner) {
73 super(owner);
74 LOG.debug("Disc Cleaner created.");
75 }
76
77
78
79
80 public void doApply() {
81 LOG.debug("Apply pressed.");
82 buttonCancel.setEnabled(true);
83 buttonApply.setEnabled(false);
84 buttonClose.setEnabled(false);
85 LOG.info("[START] Disc Remover");
86
87
88
89
90
91 worker = new Worker() {
92 public Object construct() {
93 return doWork();
94 }
95
96 public void finished() {
97 buttonCancel.setEnabled(false);
98 buttonApply.setEnabled(true);
99 buttonClose.setEnabled(true);
100 threadFinished(get());
101 }
102 };
103 worker.start();
104
105 }
106
107
108
109
110 public void doCancel() {
111 LOG.debug("Cancel Pressed.");
112 if (worker != null) {
113 worker.interrupt();
114 }
115 buttonCancel.setEnabled(false);
116 buttonApply.setEnabled(true);
117 buttonClose.setEnabled(true);
118 }
119
120
121
122
123
124
125 protected JComponent buildContent() {
126 final JPanel content = new JPanel(new BorderLayout());
127 content.add(buildMainPanel(), BorderLayout.CENTER);
128 content.add(buttonBar, BorderLayout.SOUTH);
129 return content;
130 }
131
132
133
134
135
136
137 protected JComponent buildHeader() {
138 return new HeaderPanel("Disc Cleaner ",
139 "This will attempt to delete discs from the database that no longer exist.\n"
140 + "on the hard drive or were moved to another location.", Resources.DISC_REMOVER_ICON);
141 }
142
143
144
145
146
147
148 protected JComponent buildMainPanel() {
149 final JButton[] buttons = new JButton[3];
150 final JButton button = createApplyButton();
151 button.setText("Remove");
152 buttonCancel = createCancelButton();
153 buttonApply = button;
154 buttonClose = createCloseButton(true);
155 buttonCancel.setEnabled(false);
156 buttons[0] = buttonApply;
157 buttons[1] = buttonCancel;
158 buttons[2] = buttonClose;
159 buttonBar = ButtonBarFactory.buildRightAlignedBar(buttons);
160 final FormLayout layout = new FormLayout("fill:pref:grow", "p, p, p, 4px");
161 final PanelBuilder builder = new PanelBuilder(layout);
162 builder.setDefaultDialogBorder();
163 final CellConstraints cc = new CellConstraints();
164 int row = 1;
165 row++;
166 builder.add(buildProgressPanel(), cc.xy(1, row++));
167 builder.add(buildListPanel(), cc.xy(1, 3));
168 panel = builder.getPanel();
169 panel.setBorder(Borders.DIALOG_BORDER);
170 return panel;
171 }
172
173
174
175
176 protected void doCloseWindow() {
177 super.doClose();
178 }
179
180
181
182
183
184
185
186 private JComponent buildListPanel() {
187 listModel = new DefaultListModel();
188
189 list = new JList(listModel);
190 list.setFocusable(false);
191 list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
192 list.setSelectedIndex(0);
193 list.setCellRenderer(new MessageCellRenderer());
194 list.setVisibleRowCount(19);
195 return new JScrollPane(list);
196 }
197
198
199
200
201
202
203 private JComponent buildProgressPanel() {
204 progressBar = new JProgressBar();
205 progressBar.setIndeterminate(false);
206 progressBar.setStringPainted(true);
207 final FormLayout layout = new FormLayout("right:max(14dlu;pref), 4dlu, 550px, 4px",
208 "p, 4px, p");
209 final PanelBuilder builder = new PanelBuilder(layout);
210 final CellConstraints cc = new CellConstraints();
211
212 builder.addLabel("Progress:", cc.xy(1, 1));
213 builder.add(progressBar, cc.xyw(3, 1, 2));
214
215 return builder.getPanel();
216 }
217
218
219
220
221
222 private Object doWork() {
223 Object result = null;
224 try {
225
226 listModel.removeAllElements();
227
228
229
230 final Collection discs = HibernateDao.findAll(Disc.class, Disc.PROPERTYNAME_NAME);
231 if (LOG.isDebugEnabled()) {
232 LOG.debug("Disc Count = " + discs.size());
233 }
234
235
236 progressBar.setMaximum(discs.size());
237 progressBar.setValue(0);
238 progressBar.setIndeterminate(false);
239
240
241
242 int count = 0;
243 for (final Iterator iter = discs.iterator(); iter.hasNext();) {
244 final Disc disc = (Disc)iter.next();
245 count++;
246 final boolean success = MusicDirectory.removeDiscIfNoLongerExists(disc);
247 String message = "";
248 Severity severity = null;
249 if (success) {
250 message = disc.getLocation();
251 severity = Severity.OK;
252 } else {
253 message = "REMOVED " + disc.getLocation();
254 severity = Severity.ERROR;
255 }
256 updateList(message, severity, count);
257 }
258
259 if (Thread.interrupted()) {
260 LOG.debug("Thread interrupted.");
261 throw new InterruptedException();
262 }
263
264 } catch (InterruptedException e) {
265 return result;
266 }
267 return result;
268 }
269
270
271
272
273
274
275 private void threadFinished(Object result) {
276 if (LOG.isDebugEnabled()) {
277 LOG.debug("Thread Finished");
278 LOG.debug(result);
279 }
280
281
282 ActionManager.get(Actions.REFRESH_ID).actionPerformed(null);
283 LOG.info("[STOP] Disc Remover");
284 }
285
286
287
288
289
290
291
292 private void updateList(final String aMessage, final Severity aSeverity, final int aProgress) {
293 final Runnable updateList = new Runnable() {
294 public void run() {
295 progressBar.setValue(aProgress);
296 if (aSeverity == Severity.OK) {
297 return;
298 }
299 final ValidationMessage message = new JukesValidationMessage(aMessage, aSeverity);
300 listModel.addElement(message);
301 final int index = listModel.indexOf(message);
302 list.setSelectedIndex(index);
303 list.ensureIndexIsVisible(index);
304 }
305 };
306 EventQueue.invokeLater(updateList);
307 }
308
309 }