root/trunk/src/main/org/lastpod/UI.java

Revision 59, 9.7 kB (checked in by chris, 3 years ago)

r7737@flan: chris
lots of GUI work:
1) Moved all actions into their own classes (they extend AbstractAction? now)
2) Added a status animation while submission is occurring.
3) Added nice images to buttons and menus (thanks to GPL'd artwork)
4) Added a menu bar.
5) Cleaned up the UI in an attempt to make it really pretty

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 /*
2  * LastPod is an application used to publish one's iPod play counts to Last.fm.
3  * Copyright (C) 2007  Chris Tilden
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  */
19 package org.lastpod;
20
21 import org.lastpod.action.ExitApplication;
22 import org.lastpod.action.OpenPreferencesEditor;
23 import org.lastpod.action.SubmitTracks;
24 import org.lastpod.action.UnselectAll;
25
26 import org.lastpod.util.SwingUtils;
27
28 import java.awt.Dimension;
29 import java.awt.GridBagConstraints;
30 import java.awt.GridBagLayout;
31 import java.awt.Insets;
32 import java.awt.Toolkit;
33 import java.awt.event.KeyEvent;
34 import java.awt.event.WindowAdapter;
35 import java.awt.event.WindowEvent;
36
37 import java.io.IOException;
38
39 import java.util.prefs.Preferences;
40
41 import javax.swing.Action;
42 import javax.swing.ImageIcon;
43 import javax.swing.JButton;
44 import javax.swing.JFrame;
45 import javax.swing.JLabel;
46 import javax.swing.JMenu;
47 import javax.swing.JMenuBar;
48 import javax.swing.JMenuItem;
49 import javax.swing.JPanel;
50 import javax.swing.JProgressBar;
51 import javax.swing.JScrollPane;
52 import javax.swing.JTextArea;
53 import javax.swing.JToolBar;
54 import javax.swing.SwingUtilities;
55
56 /**
57  * Contains the LastPod user interface. (UI)  The UI interacts with the LastPod
58  * controller.
59  * @author muti
60  * @author Chris Tilden
61  * @version $Id$
62  */
63 public class UI implements ChunkProgress {
64     private RecentPanel recentpanel;
65     private JTextArea logtextarea;
66
67     /**
68      * Displays the progress of the submit.
69      */
70     private JProgressBar progressBar = null;
71
72     /**
73      * The label used to display the idle and busy icons.
74      */
75     private JLabel statusAnimationLabel;
76     private JFrame frame;
77
78     /**
79      * The action that opens the PreferencesEditor.
80      */
81     private final Action actionOpenPreferences;
82
83     /**
84      * The action that unselects all tracks.
85      */
86     private final Action actionUnselectAll;
87
88     /**
89      * The action that submits tracks to Last.fm.
90      */
91     private final Action actionSubmitTracks;
92
93     /**
94      * The action that exits the application.
95      */
96     private final Action actionExit;
97
98     /**
99      * Constructs the user interface and some icon elements.
100      */
101     public UI() {
102         frame = new JFrame("LastPod");
103
104         ImageIcon idleIcon = SwingUtils.createImageIcon(UI.class, "images/busyicons/idle-icon.png");
105         statusAnimationLabel = new JLabel();
106         statusAnimationLabel.setIcon(idleIcon);
107
108         ImageIcon iconOpenPreferences =
109             SwingUtils.createImageIcon(UI.class, "images/preferences-desktop.png");
110         ImageIcon iconUnselectAll = SwingUtils.createImageIcon(UI.class, "images/stock_to-top.png");
111         ImageIcon iconSubmitTracks =
112             SwingUtils.createImageIcon(UI.class, "images/applications-system.png");
113         ImageIcon iconExit = SwingUtils.createImageIcon(UI.class, "images/application-exit.png");
114
115         actionOpenPreferences = new OpenPreferencesEditor(frame, "Preferences",
116                 iconOpenPreferences, "Opens Preferences Editor", KeyEvent.VK_P);
117         actionUnselectAll = new UnselectAll(frame, "Unselect All", iconUnselectAll,
118                 "Unselects All Tracks", KeyEvent.VK_A);
119         actionSubmitTracks = new SubmitTracks(statusAnimationLabel, "Submit Tracks",
120                 iconSubmitTracks, "Submits the selected tracks to Last.fm", KeyEvent.VK_S);
121         actionExit = new ExitApplication("Exit", iconExit,
122                 "Exits the application.  May launch iTunes", KeyEvent.VK_X);
123     }
124
125     /**
126      * Gets the user interface's JFrame.
127      * @return  The user interface's JFrame.
128      */
129     public JFrame getFrame() {
130         return frame;
131     }
132
133     public void buildUI() {
134         JFrame.setDefaultLookAndFeelDecorated(true);
135
136         /* If enabled launch iTunes after exiting the application. */
137         frame.addWindowListener(new WindowAdapter() {
138                 public void windowClosing(WindowEvent windowEvent) {
139                     launchItunes();
140                     System.exit(0);
141                 }
142             });
143
144         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
145         Dimension frameSize = new Dimension(screenSize);
146
147         frameSize.width *= 0.90;
148         frameSize.height *= 0.85;
149         frame.setSize(frameSize);
150
151         /* Centers the interface on the screen. */
152         int x = (screenSize.width / 2) - (frame.getWidth() / 2);
153         int y = (screenSize.height / 2) - (frame.getHeight() / 2);
154         frame.setLocation(x, y);
155
156         GridBagLayout layout = new GridBagLayout();
157         frame.getContentPane().setLayout(layout);
158
159         GridBagConstraints c = new GridBagConstraints();
160
161         JMenuBar menuBar = new JMenuBar();
162         JMenu optionsMenu = new JMenu("Options");
163         optionsMenu.setMnemonic(KeyEvent.VK_O);
164
165         JMenu editMenu = new JMenu("Edit");
166         editMenu.setMnemonic(KeyEvent.VK_E);
167
168         optionsMenu.add(new JMenuItem(actionOpenPreferences));
169         optionsMenu.addSeparator();
170         optionsMenu.add(new JMenuItem(actionExit));
171
172         editMenu.add(new JMenuItem(actionUnselectAll));
173
174         menuBar.add(optionsMenu);
175         menuBar.add(editMenu);
176         frame.setJMenuBar(menuBar);
177
178         JToolBar toolBar = new JToolBar();
179         layout.setConstraints(toolBar, c);
180
181         JButton button;
182         button = new JButton(actionOpenPreferences);
183         layout.setConstraints(button, c);
184         toolBar.add(button);
185
186         toolBar.addSeparator();
187
188         button = new JButton(actionUnselectAll);
189         layout.setConstraints(button, c);
190         toolBar.add(button);
191
192         toolBar.addSeparator();
193
194         button = new JButton(actionSubmitTracks);
195         layout.setConstraints(button, c);
196         toolBar.add(button);
197
198         toolBar.addSeparator();
199
200         button = new JButton(actionExit);
201         layout.setConstraints(button, c);
202         toolBar.add(button);
203
204         frame.getContentPane().add(toolBar);
205
206         c.gridy = 1;
207         c.fill = GridBagConstraints.BOTH;
208         c.weightx = 1.0;
209         c.weighty = 1.0;
210         c.gridwidth = GridBagConstraints.REMAINDER;
211
212         this.recentpanel = new RecentPanel();
213         layout.setConstraints(this.recentpanel, c);
214         frame.getContentPane().add(this.recentpanel);
215
216         c.gridy = 2;
217         c.weighty = 0.5;
218         this.logtextarea = new JTextArea("=====LOG=====\n");
219         this.logtextarea.setLineWrap(true);
220         this.logtextarea.setWrapStyleWord(true);
221         this.logtextarea.setEditable(false);
222
223         JScrollPane scrollpane = new JScrollPane(this.logtextarea);
224         layout.setConstraints(scrollpane, c);
225         frame.getContentPane().add(scrollpane);
226
227         c.gridwidth = 1;
228         c.weightx = 0.0;
229         c.weighty = 0.0;
230
231         c.fill = GridBagConstraints.NONE;
232         c.gridx = 2;
233         c.gridy = 3;
234         c.anchor = GridBagConstraints.LAST_LINE_END;
235
236         JPanel statusBar = new JPanel();
237         statusBar.setLayout(layout);
238         layout.setConstraints(statusBar, c);
239
240         progressBar = new JProgressBar();
241
242         c.gridx = 0;
243         c.gridy = 0;
244         c.insets = new Insets(3, 10, 3, 5);
245         layout.setConstraints(progressBar, c);
246         statusBar.add(progressBar);
247
248         c.gridx = 1;
249         c.insets = new Insets(3, 0, 3, 4);
250         layout.setConstraints(statusAnimationLabel, c);
251         statusBar.add(statusAnimationLabel);
252
253         frame.getContentPane().add(statusBar);
254     }
255
256     public void makeVisable() {
257         frame.setVisible(true);
258     }
259
260     public void newTrackListAvailable() {
261         this.recentpanel.newTrackListAvailable();
262     }
263
264     public JTextArea getLogtextarea() {
265         return this.logtextarea;
266     }
267
268     /**
269      * When the worker needs to update the GUI we do so by queuing
270      * a Runnable for the event dispatching thread with
271      * SwingUtilities.invokeLater().  In this case we're just
272      * changing the progress bars value.
273      * @param currentChunk  The progress bar value.
274      */
275     public void updateCurrentChunk(final int currentChunk) {
276         Runnable doSetProgressBarValue =
277             new Runnable() {
278                 public void run() {
279                     progressBar.setValue(currentChunk);
280                 }
281             };
282
283         SwingUtilities.invokeLater(doSetProgressBarValue);
284     }
285
286     /**
287      * Sets the number of chunks to be submitted.
288      * @param numberOfChunks  The number of chunks to be submitted.
289      */
290     public void setNumberOfChunks(final int numberOfChunks) {
291         progressBar.setMaximum(numberOfChunks);
292     }
293
294     /**
295      * Launches iTunes if the user has specified this in their preferences.
296      */
297     private void launchItunes() {
298         Preferences fPrefs = Preferences.userRoot().node("ws/afterglo/audioPod");
299         String iTunesStatus = fPrefs.get("iTunes Status", "Disabled");
300
301         if (iTunesStatus.equals("Enabled")) {
302             String iTunesPath = fPrefs.get("iT Path", "default");
303
304             if (!iTunesPath.endsWith("iTunes.exe")) {
305                 iTunesPath += "\\iTunes.exe";
306             }
307
308             try {
309                 Runtime rt = Runtime.getRuntime();
310                 rt.exec(iTunesPath);
311             } catch (IOException e) {
312                 System.out.println(iTunesPath + " not found!  Cannot launch iTunes.");
313             }
314         }
315     }
316 }
Note: See TracBrowser for help on using the browser.