001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2015 ForgeRock AS. 016 */ 017 018package org.opends.guitools.controlpanel.ui; 019 020import static org.opends.messages.AdminToolMessages.*; 021import static com.forgerock.opendj.util.OperatingSystem.isMacOS; 022 023import java.awt.event.ActionEvent; 024import java.awt.event.ActionListener; 025import java.awt.event.KeyEvent; 026import java.lang.reflect.InvocationHandler; 027import java.lang.reflect.Method; 028import java.lang.reflect.Proxy; 029import java.util.HashSet; 030import java.util.Set; 031 032import javax.swing.JMenu; 033import javax.swing.JMenuItem; 034 035import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 036import org.opends.guitools.controlpanel.task.Task; 037import org.opends.guitools.controlpanel.util.Utilities; 038import org.forgerock.i18n.LocalizableMessage; 039 040/** 041 * The menu bar that appears on the main panel. 042 * 043 */ 044public class MainMenuBar extends GenericMenuBar 045{ 046 private static final long serialVersionUID = 6441273044772077947L; 047 048 private GenericDialog dlg; 049 private RefreshOptionsPanel panel; 050 051 /** 052 * Constructor. 053 * @param info the control panel information. 054 */ 055 public MainMenuBar(ControlPanelInfo info) 056 { 057 super(info); 058 059 addMenus(); 060 061 if (isMacOS()) 062 { 063 setMacOSQuitHandler(); 064 } 065 } 066 067 /** 068 * Method that can be overwritten to set specific menus. 069 * 070 */ 071 protected void addMenus() 072 { 073 add(createFileMenuBar()); 074 add(createViewMenuBar()); 075 add(createHelpMenuBar()); 076 } 077 078 /** 079 * The method called when the user clicks on quick. It will check that there 080 * are not ongoing tasks. If there are tasks, it will ask the user for 081 * confirmation to quit. 082 * 083 */ 084 public void quitClicked() 085 { 086 Set<String> runningTasks = new HashSet<>(); 087 for (Task task : getInfo().getTasks()) 088 { 089 if (task.getState() == Task.State.RUNNING) 090 { 091 runningTasks.add(task.getTaskDescription().toString()); 092 } 093 } 094 boolean confirmed = true; 095 if (!runningTasks.isEmpty()) 096 { 097 String allTasks = Utilities.getStringFromCollection(runningTasks, "<br>"); 098 LocalizableMessage title = INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(); 099 LocalizableMessage msg = 100 INFO_CTRL_PANEL_RUNNING_TASKS_CONFIRMATION_DETAILS.get(allTasks); 101 confirmed = Utilities.displayConfirmationDialog( 102 Utilities.getParentDialog(this), title, msg); 103 } 104 if (confirmed) 105 { 106 System.exit(0); 107 } 108 } 109 110 /** 111 * Creates the File menu bar. 112 * @return the File menu bar. 113 */ 114 protected JMenu createFileMenuBar() 115 { 116 JMenu menu = Utilities.createMenu(INFO_CTRL_PANEL_FILE_MENU.get(), 117 INFO_CTRL_PANEL_FILE_MENU_DESCRIPTION.get()); 118 menu.setMnemonic(KeyEvent.VK_F); 119 JMenuItem menuItem = Utilities.createMenuItem( 120 INFO_CTRL_PANEL_CONNECT_TO_SERVER_MENU.get()); 121 menuItem.addActionListener(new ActionListener() 122 { 123 public void actionPerformed(ActionEvent ev) 124 { 125 connectToServerClicked(); 126 } 127 }); 128 menu.add(menuItem); 129 130 if (!isMacOS()) 131 { 132 menuItem = Utilities.createMenuItem(INFO_CTRL_PANEL_EXIT_MENU.get()); 133 menuItem.addActionListener(new ActionListener() 134 { 135 /** {@inheritDoc} */ 136 public void actionPerformed(ActionEvent ev) 137 { 138 quitClicked(); 139 } 140 }); 141 menu.add(menuItem); 142 } 143 return menu; 144 } 145 146 /** 147 * Creates the View menu bar. 148 * @return the View menu bar. 149 */ 150 protected JMenu createViewMenuBar() 151 { 152 JMenu menu = Utilities.createMenu(INFO_CTRL_PANEL_VIEW_MENU.get(), 153 INFO_CTRL_PANEL_HELP_VIEW_DESCRIPTION.get()); 154 menu.setMnemonic(KeyEvent.VK_V); 155 JMenuItem menuItem = Utilities.createMenuItem( 156 INFO_CTRL_PANEL_REFRESH_MENU.get()); 157 menuItem.addActionListener(new ActionListener() 158 { 159 public void actionPerformed(ActionEvent ev) 160 { 161 refreshOptionsClicked(); 162 } 163 }); 164 menu.add(menuItem); 165 return menu; 166 } 167 168 /** 169 * Specific method to be able to handle the Quit events sent from the COCOA 170 * menu of Mac OS. 171 * 172 */ 173 private void setMacOSQuitHandler() 174 { 175 try 176 { 177 Class<? extends Object> applicationClass = 178 Class.forName("com.apple.eawt.Application"); 179 Class<? extends Object> applicationListenerClass = 180 Class.forName("com.apple.eawt.ApplicationListener"); 181 final Object macApplication = applicationClass.getConstructor( 182 (Class[])null).newInstance((Object[])null); 183 InvocationHandler adapter = new InvocationHandler() 184 { 185 public Object invoke (Object proxy, Method method, Object[] args) 186 throws Throwable 187 { 188 Object event = args[0]; 189 if (method.getName().equals("handleQuit")) 190 { 191 quitClicked(); 192 193 // quitClicked will exit if we must exit 194 Method setHandledMethod = event.getClass().getDeclaredMethod( 195 "setHandled", new Class[] { boolean.class }); 196 setHandledMethod.invoke(event, new Object[] { Boolean.FALSE }); 197 } 198 return null; 199 } 200 }; 201 Method addListenerMethod = 202 applicationClass.getDeclaredMethod("addApplicationListener", 203 new Class[] { applicationListenerClass }); 204 Object proxy = Proxy.newProxyInstance(MainMenuBar.class.getClassLoader(), 205 new Class[] { applicationListenerClass }, adapter); 206 addListenerMethod.invoke(macApplication, new Object[] { proxy }); 207 } catch (Throwable t) { 208 t.printStackTrace(); 209 } 210 } 211 212 /** 213 * The method called when the user clicks on 'Refresh Options'. 214 * 215 */ 216 protected void refreshOptionsClicked() 217 { 218 if (panel == null) 219 { 220 panel = new RefreshOptionsPanel(); 221 panel.setInfo(getInfo()); 222 dlg = new GenericDialog( 223 Utilities.getFrame(MainMenuBar.this), 224 panel); 225 dlg.setModal(true); 226 Utilities.centerGoldenMean(dlg, 227 Utilities.getFrame(MainMenuBar.this)); 228 } 229 dlg.setVisible(true); 230 if (!panel.isCanceled()) 231 { 232 getInfo().setPoolingPeriod(panel.getPoolingPeriod()); 233 getInfo().stopPooling(); 234 getInfo().startPooling(); 235 } 236 } 237 238 /** 239 * The method called when the user clicks on 'Connect to Server...'. 240 */ 241 protected void connectToServerClicked() 242 { 243 Set<String> runningTasks = new HashSet<>(); 244 for (Task task : getInfo().getTasks()) 245 { 246 if (task.getState() == Task.State.RUNNING) 247 { 248 runningTasks.add(task.getTaskDescription().toString()); 249 } 250 } 251 boolean confirmed = true; 252 if (!runningTasks.isEmpty()) 253 { 254 String allTasks = Utilities.getStringFromCollection(runningTasks, "<br>"); 255 LocalizableMessage title = INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(); 256 LocalizableMessage msg = 257 INFO_CTRL_PANEL_RUNNING_TASKS_CHANGE_SERVER_CONFIRMATION_DETAILS.get( 258 allTasks); 259 confirmed = Utilities.displayConfirmationDialog( 260 Utilities.getParentDialog(this), title, msg); 261 } 262 if (confirmed) 263 { 264 GenericDialog dlg = 265 ControlCenterMainPane.getLocalOrRemoteDialog(getInfo()); 266 Utilities.centerGoldenMean(dlg, 267 Utilities.getFrame(MainMenuBar.this)); 268 dlg.setVisible(true); 269 } 270 } 271}