1 19 20 package org.netbeans.modules.project.ui.actions; 21 22 import java.awt.event.ActionEvent ; 23 import java.awt.event.ActionListener ; 24 import java.beans.PropertyChangeEvent ; 25 import java.beans.PropertyChangeListener ; 26 import java.io.IOException ; 27 import java.net.URL ; 28 import java.util.Iterator ; 29 import java.util.List ; 30 import javax.swing.AbstractAction ; 31 import javax.swing.Action ; 32 import javax.swing.ImageIcon ; 33 import javax.swing.JComponent ; 34 import javax.swing.JMenu ; 35 import javax.swing.JMenuItem ; 36 import javax.swing.event.ChangeEvent ; 37 import javax.swing.event.ChangeListener ; 38 import javax.swing.event.PopupMenuEvent ; 39 import javax.swing.event.PopupMenuListener ; 40 import org.netbeans.api.project.Project; 41 import org.netbeans.api.project.ProjectUtils; 42 import org.netbeans.modules.project.ui.OpenProjectList; 43 import org.netbeans.api.project.ProjectInformation; 44 import org.netbeans.api.project.ProjectManager; 45 import org.netbeans.modules.project.ui.ProjectTab; 46 import org.openide.filesystems.FileStateInvalidException; 47 import org.openide.nodes.Node; 48 import org.openide.util.NbBundle; 49 import org.openide.util.Utilities; 50 import org.openide.awt.DynamicMenuContent; 51 import org.openide.util.WeakListeners; 52 import org.openide.util.actions.Presenter; 53 import org.openide.filesystems.FileChangeAdapter; 54 import org.openide.filesystems.FileEvent; 55 import org.openide.filesystems.FileObject; 56 import org.openide.filesystems.URLMapper; 57 58 public class RecentProjects extends AbstractAction implements Presenter.Menu, Presenter.Popup, PropertyChangeListener { 59 60 62 private static final String PROJECT_URL_KEY = "org.netbeans.modules.project.ui.RecentProjectItem.Project_URL"; private final ProjectDirListener prjDirListener = new ProjectDirListener(); 64 65 private UpdatingMenu subMenu; 66 67 private boolean recreate; 68 69 public RecentProjects() { 70 super( NbBundle.getMessage(RecentProjects.class, "LBL_RecentProjectsAction_Name")); OpenProjectList.getDefault().addPropertyChangeListener( WeakListeners.propertyChange( this, OpenProjectList.getDefault() ) ); 72 recreate = true; 73 } 74 75 76 public boolean isEnabled() { 77 return !OpenProjectList.getDefault().isRecentProjectsEmpty(); 78 } 79 80 83 public void actionPerformed(ActionEvent ev) { 84 } 86 87 public JMenuItem getMenuPresenter() { 88 createMainSubMenu(); 89 return subMenu; 90 } 91 92 public JMenuItem getPopupPresenter() { 93 JMenu menu = createSubMenu(); 94 fillSubMenu(menu); 95 return menu; 96 } 97 98 private UpdatingMenu createSubMenu() { 99 UpdatingMenu menu = new UpdatingMenu(this); 100 menu.setMnemonic(NbBundle.getMessage(RecentProjects.class, "MNE_RecentProjectsAction_Name").charAt(0)); 102 return menu; 103 } 104 105 private void createMainSubMenu() { 106 if ( subMenu == null ) { 107 subMenu = createSubMenu(); 108 subMenu.getModel().addChangeListener(subMenu); 110 111 } 112 } 113 114 private void fillSubMenu(JMenu menu) { 115 menu.removeAll(); 116 117 List projects = OpenProjectList.getDefault().getRecentProjects(); 118 if ( projects.isEmpty() ) { 119 menu.setEnabled( false ); 120 return; 121 } 122 123 menu.setEnabled( true ); 124 ActionListener jmiActionListener = new MenuItemActionListener(); 125 126 128 for ( Iterator it = projects.iterator(); it.hasNext(); ) { 129 Project p = (Project)it.next(); 130 FileObject prjDir = p.getProjectDirectory(); 131 try { 132 URL prjDirURL = prjDir.getURL(); 133 if ( prjDirURL == null || prjDir == null || !prjDir.isValid()) { 134 continue; 135 } 136 prjDir.removeFileChangeListener(prjDirListener); 137 prjDir.addFileChangeListener(prjDirListener); 138 ProjectInformation pi = ProjectUtils.getInformation(p); 139 JMenuItem jmi = new JMenuItem (pi.getDisplayName(), pi.getIcon()); 140 menu.add( jmi ); 141 jmi.putClientProperty( PROJECT_URL_KEY, prjDirURL ); 142 jmi.addActionListener( jmiActionListener ); 143 } 144 catch( FileStateInvalidException ex ) { 145 } 147 } 148 } 149 150 152 153 public void propertyChange( PropertyChangeEvent e ) { 154 155 if ( OpenProjectList.PROPERTY_RECENT_PROJECTS.equals( e.getPropertyName() ) ) { 156 createMainSubMenu(); 157 subMenu.setEnabled( !OpenProjectList.getDefault().isRecentProjectsEmpty() ); 158 recreate = true; 159 } 160 161 } 162 163 164 165 167 private static class MenuItemActionListener implements ActionListener { 168 169 public void actionPerformed( ActionEvent e ) { 170 171 if ( e.getSource() instanceof JMenuItem ) { 172 JMenuItem jmi = (JMenuItem )e.getSource(); 173 174 URL url = (URL )jmi.getClientProperty( PROJECT_URL_KEY ); 175 Project project = null; 176 177 FileObject dir = URLMapper.findFileObject( url ); 178 if ( dir != null && dir.isFolder() ) { 179 try { 180 project = ProjectManager.getDefault().findProject( dir ); 181 } 182 catch ( IOException ioEx ) { 183 } 185 } 186 187 if ( project != null ) { 188 OpenProjectList.getDefault().open( new Project[] {project}, false, true ); 189 ProjectTab ptLogial = ProjectTab.findDefault (ProjectTab.ID_LOGICAL); 190 Node root = ptLogial.getExplorerManager ().getRootContext (); 191 Node projNode = root.getChildren ().findChild ( project.getProjectDirectory().getName ()); 192 try { 193 ptLogial.getExplorerManager ().setSelectedNodes (new Node[] {projNode}); 194 ptLogial.open (); 195 ptLogial.requestActive (); 196 } catch (Exception ignore) { 197 } 199 } 200 201 } 202 203 } 204 205 } 206 207 private class ProjectDirListener extends FileChangeAdapter { 208 public void fileDeleted(FileEvent fe) { 209 recreate = true; 210 } 211 } 212 213 private class UpdatingMenu extends JMenu implements ChangeListener { 214 215 public UpdatingMenu(Action action) { 216 super(action); 217 } 218 219 227 public void stateChanged(ChangeEvent e) { 228 if (recreate && getModel().isSelected()) { 229 fillSubMenu(this); 230 recreate = false; 231 } 232 } 233 234 } 235 236 } 237 | Popular Tags |