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