Changeset 59

Show
Ignore:
Timestamp:
05/17/07 22:00:07 (3 years ago)
Author:
chris
Message:

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

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/bin/build.xml

    r52 r59  
    112112 
    113113    <copy file="${src.home}/../COPYING" todir="${bin.home}/org/lastpod"/> 
     114    <copy todir="${bin.home}/org/lastpod/images"> 
     115        <fileset dir="${src.home}/../images"/> 
     116    </copy> 
    114117  </target> 
    115118 
  • trunk/src/main/org/lastpod/UI.java

    r58 r59  
    1919package org.lastpod; 
    2020 
    21 import org.lastpod.util.SwingWorker; 
     21import org.lastpod.action.ExitApplication; 
     22import org.lastpod.action.OpenPreferencesEditor; 
     23import org.lastpod.action.SubmitTracks; 
     24import org.lastpod.action.UnselectAll; 
     25 
     26import org.lastpod.util.SwingUtils; 
    2227 
    2328import java.awt.Dimension; 
    2429import java.awt.GridBagConstraints; 
    2530import java.awt.GridBagLayout; 
     31import java.awt.Insets; 
    2632import java.awt.Toolkit; 
    27 import java.awt.event.ActionEvent; 
    28 import java.awt.event.ActionListener; 
    2933import java.awt.event.KeyEvent; 
    3034import java.awt.event.WindowAdapter; 
     
    3539import java.util.prefs.Preferences; 
    3640 
     41import javax.swing.Action; 
     42import javax.swing.ImageIcon; 
    3743import javax.swing.JButton; 
    3844import javax.swing.JFrame; 
     45import javax.swing.JLabel; 
     46import javax.swing.JMenu; 
     47import javax.swing.JMenuBar; 
     48import javax.swing.JMenuItem; 
     49import javax.swing.JPanel; 
    3950import javax.swing.JProgressBar; 
    4051import javax.swing.JScrollPane; 
    4152import javax.swing.JTextArea; 
     53import javax.swing.JToolBar; 
    4254import javax.swing.SwingUtilities; 
    4355 
     
    5466 
    5567    /** 
    56      * The submit button. 
    57      */ 
    58     private JButton submitButton; 
    59  
    60     /** 
    6168     * Displays the progress of the submit. 
    6269     */ 
     
    6471 
    6572    /** 
    66      * This worker is used to perform the submission and is a nice threaded 
    67      * implementation. 
    68      */ 
    69     private SwingWorker worker; 
     73     * The label used to display the idle and busy icons. 
     74     */ 
     75    private JLabel statusAnimationLabel; 
    7076    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    } 
    71124 
    72125    /** 
     
    80133    public void buildUI() { 
    81134        JFrame.setDefaultLookAndFeelDecorated(true); 
    82         frame = new JFrame("LastPod"); 
    83135 
    84136        /* If enabled launch iTunes after exiting the application. */ 
    85137        frame.addWindowListener(new WindowAdapter() { 
    86138                public void windowClosing(WindowEvent windowEvent) { 
    87                     Preferences fPrefs = Preferences.userRoot().node("ws/afterglo/audioPod"); 
    88                     String iTunesStatus = fPrefs.get("iTunes Status", "Disabled"); 
    89  
    90                     if (iTunesStatus.equals("Enabled")) { 
    91                         String iTunesPath = fPrefs.get("iT Path", "default"); 
    92  
    93                         if (!iTunesPath.endsWith("iTunes.exe")) { 
    94                             iTunesPath += "\\iTunes.exe"; 
    95                         } 
    96  
    97                         try { 
    98                             Runtime rt = Runtime.getRuntime(); 
    99                             rt.exec(iTunesPath); 
    100                         } catch (IOException e) { 
    101                             System.out.println(iTunesPath + " not found!  Cannot launch iTunes."); 
    102                         } 
    103                     } 
    104  
     139                    launchItunes(); 
    105140                    System.exit(0); 
    106141                } 
     
    123158 
    124159        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; 
    125207        c.fill = GridBagConstraints.BOTH; 
    126208        c.weightx = 1.0; 
     
    132214        frame.getContentPane().add(this.recentpanel); 
    133215 
     216        c.gridy = 2; 
    134217        c.weighty = 0.5; 
    135218        this.logtextarea = new JTextArea("=====LOG=====\n"); 
     
    146229        c.weighty = 0.0; 
    147230 
    148         //TODO Add button mnemonics for kbd shortcut access 
    149         JButton button; 
    150         button = new JButton("Preferences.."); 
    151         button.setMnemonic(KeyEvent.VK_P); 
    152         button.addActionListener(new ActionListener() { 
    153                 public void actionPerformed(ActionEvent ev) { 
    154                     PreferencesEditor prefeditor = new PreferencesEditor(frame); 
    155                     prefeditor.buildUI(); 
    156                 } 
    157             }); 
    158         layout.setConstraints(button, c); 
    159         frame.getContentPane().add(button); 
    160  
    161         button = new JButton("Unselect All"); 
    162         button.setMnemonic(KeyEvent.VK_A); 
    163         button.addActionListener(new ActionListener() { 
    164                 public void actionPerformed(ActionEvent ev) { 
    165                     JButton selectionButton = (JButton) ev.getSource(); 
    166  
    167                     if ("Unselect All".equals(selectionButton.getText())) { 
    168                         LastPod.unselectAll(); 
    169                         selectionButton.setText("Select All"); 
    170                     } else if ("Select All".equals(selectionButton.getText())) { 
    171                         LastPod.selectAll(); 
    172                         selectionButton.setText("Unselect All"); 
    173                     } 
    174  
    175                     frame.repaint(); 
    176                 } 
    177             }); 
    178         layout.setConstraints(button, c); 
    179         frame.getContentPane().add(button); 
    180  
    181         submitButton = new JButton("Submit Tracks"); 
    182         submitButton.setMnemonic(KeyEvent.VK_S); 
    183         submitButton.addActionListener(new ActionListener() { 
    184                 public void actionPerformed(ActionEvent ev) { 
    185                     submitButton.setEnabled(false); 
    186  
    187                     /* Invoking start() on the SwingWorker causes a new Thread 
    188                      * to be created that will call construct(), and then 
    189                      * finished().  Note that finished() is called even if 
    190                      * the worker is interrupted because we catch the 
    191                      * InterruptedException in doWork(). 
    192                      */ 
    193                     worker = 
    194                         new SwingWorker() { 
    195                                 public Object construct() { 
    196                                     return LastPod.submitTracks(); 
    197                                 } 
    198  
    199                                 public void finished() { 
    200                                     submitButton.setEnabled(true); 
    201                                 } 
    202                             }; 
    203                     worker.start(); 
    204                 } 
    205             }); 
    206         layout.setConstraints(submitButton, c); 
    207         frame.getContentPane().add(submitButton); 
     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); 
    208239 
    209240        progressBar = new JProgressBar(); 
     241 
     242        c.gridx = 0; 
     243        c.gridy = 0; 
     244        c.insets = new Insets(3, 10, 3, 5); 
    210245        layout.setConstraints(progressBar, c); 
    211         frame.getContentPane().add(progressBar); 
     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); 
    212254    } 
    213255 
     
    249291        progressBar.setMaximum(numberOfChunks); 
    250292    } 
     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    } 
    251316}