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 2009 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2015 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.ui; 018 019import static org.opends.messages.AdminToolMessages.*; 020 021import java.awt.Color; 022import java.awt.Component; 023import java.awt.Container; 024import java.awt.GridBagConstraints; 025import java.awt.GridBagLayout; 026import java.awt.Insets; 027import java.awt.event.ActionEvent; 028import java.awt.event.ActionListener; 029import java.awt.event.FocusAdapter; 030import java.awt.event.FocusEvent; 031import java.awt.event.FocusListener; 032import java.awt.event.KeyEvent; 033import java.awt.event.WindowAdapter; 034import java.awt.event.WindowEvent; 035 036import javax.swing.AbstractButton; 037import javax.swing.BorderFactory; 038import javax.swing.Box; 039import javax.swing.JButton; 040import javax.swing.JComboBox; 041import javax.swing.JComponent; 042import javax.swing.JFrame; 043import javax.swing.JList; 044import javax.swing.JMenuBar; 045import javax.swing.JPanel; 046import javax.swing.JScrollPane; 047import javax.swing.JTable; 048import javax.swing.JViewport; 049import javax.swing.KeyStroke; 050import javax.swing.SwingUtilities; 051import javax.swing.border.EmptyBorder; 052import javax.swing.text.JTextComponent; 053 054import org.opends.guitools.controlpanel.ui.GenericDialog.ButtonType; 055import org.opends.guitools.controlpanel.util.Utilities; 056import org.opends.server.util.DynamicConstants; 057 058/** 059 * The generic frame of the Control Panel. It contains a StatusGenericPanel. 060 */ 061public class GenericFrame extends JFrame 062{ 063 private static final long serialVersionUID = -2643144936460484112L; 064 private static final Color buttonPanelBackground = 065 ColorAndFontConstants.greyBackground; 066 private JButton okButton; 067 068 /** The close button. */ 069 protected JButton closeButton; 070 private JButton cancelButton; 071 /** The panel contained in the frame. */ 072 protected StatusGenericPanel panel; 073 private Component lastComponentWithFocus; 074 075 /** 076 * Constructor of the frame. 077 * @param panel the panel contained in this frame. 078 */ 079 public GenericFrame(StatusGenericPanel panel) 080 { 081 super(); 082 this.panel = panel; 083 if (panel.requiresBorder()) 084 { 085 setDefaultBorder(panel); 086 } 087 JMenuBar menu = panel.getMenuBar(); 088 if (menu != null) 089 { 090 setJMenuBar(menu); 091 } 092 setResizable(true); 093 JScrollPane scroll = Utilities.createScrollPane(panel); 094 JPanel inputPanel = new JPanel(new GridBagLayout()); 095 setContentPane(inputPanel); 096 GridBagConstraints gbc = new GridBagConstraints(); 097 gbc.weightx = 1.0; 098 gbc.weighty = 1.0; 099 gbc.gridx = 0; 100 gbc.gridy = 0; 101 gbc.fill = GridBagConstraints.BOTH; 102 if (panel.requiresScroll()) 103 { 104 inputPanel.add(scroll, gbc); 105 } 106 else 107 { 108 inputPanel.add(panel, gbc); 109 } 110 if (panel.getButtonType() != ButtonType.NO_BUTTON) 111 { 112 gbc.gridy ++; 113 gbc.weighty = 0.0; 114 inputPanel.add(createButtonsPanel(panel), gbc); 115 } 116 117 KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0); 118 ActionListener actionListener = new ActionListener() 119 { 120 /** {@inheritDoc} */ 121 public void actionPerformed(ActionEvent ev) 122 { 123 setVisible(false); 124 } 125 }; 126 getRootPane().registerKeyboardAction(actionListener, stroke, 127 JComponent.WHEN_IN_FOCUSED_WINDOW); 128 129 FocusListener focusListener = new FocusAdapter() 130 { 131 /** {@inheritDoc} */ 132 public void focusGained(FocusEvent ev) 133 { 134 lastComponentWithFocus = ev.getComponent(); 135 } 136 }; 137 addFocusListener(focusListener, panel); 138 139 addWindowListener(new WindowAdapter() { 140 /** {@inheritDoc} */ 141 public void windowClosing(WindowEvent e) { 142 GenericFrame.this.panel.closeClicked(); 143 } 144 }); 145 146 org.opends.quicksetup.ui.Utilities.setFrameIcon(this); 147 pack(); 148 if (!SwingUtilities.isEventDispatchThread()) 149 { 150 Thread.dumpStack(); 151 } 152 } 153 154 /** 155 * Method used to add a focus listeners to all the components in the panel. 156 * This is done to recover the focus on an item when the frame is closed 157 * and then opened again. 158 * @param focusListener the focus listener. 159 * @param container the container where the components are layed out. 160 */ 161 private void addFocusListener(FocusListener focusListener, 162 Container container) 163 { 164 for (int i=0; i < container.getComponentCount(); i++) 165 { 166 Component comp = container.getComponent(i); 167 if (comp instanceof AbstractButton || 168 comp instanceof JTextComponent || 169 comp instanceof JList || 170 comp instanceof JComboBox || 171 comp instanceof JTable) 172 { 173 comp.addFocusListener(focusListener); 174 } 175 else if (comp instanceof JPanel || comp instanceof JScrollPane 176 || comp instanceof JViewport) 177 { 178 addFocusListener(focusListener, (Container)comp); 179 } 180 } 181 } 182 183 /** {@inheritDoc} */ 184 public void setVisible(boolean visible) 185 { 186 if (visible && lastComponentWithFocus == null) 187 { 188 lastComponentWithFocus = panel.getPreferredFocusComponent(); 189 } 190 if (visible && lastComponentWithFocus != null) 191 { 192 lastComponentWithFocus.requestFocusInWindow(); 193 } 194 updateDefaultButton(panel); 195 panel.toBeDisplayed(visible); 196 updateTitle(); 197 super.setVisible(visible); 198 } 199 200 /** 201 * Sets the enable state of the OK button. 202 * @param enable whether the OK button must be enabled or not. 203 */ 204 public void setEnabledOK(boolean enable) 205 { 206 okButton.setEnabled(enable); 207 } 208 209 /** 210 * Sets the enable state of the Cancel button. 211 * @param enable whether the Cancel button must be enabled or not. 212 */ 213 public void setEnabledCancel(boolean enable) 214 { 215 cancelButton.setEnabled(enable); 216 } 217 218 /** 219 * Sets the enable state of the Close button. 220 * @param enable whether the Close button must be enabled or not. 221 */ 222 public void setEnabledClose(boolean enable) 223 { 224 closeButton.setEnabled(enable); 225 } 226 227 /** 228 * Updates the title of the frame using the title of the panel. 229 * 230 */ 231 public void updateTitle() 232 { 233 if (panel.getTitle() != null) 234 { 235 setTitle(INFO_CTRL_PANEL_GENERIC_TITLE.get( 236 DynamicConstants.PRODUCT_NAME, 237 panel.getTitle()).toString()); 238 } 239 } 240 241 private void setDefaultBorder(JComponent comp) 242 { 243 Utilities.setBorder(comp, new EmptyBorder(20, 20, 20, 20)); 244 } 245 246 247 private JPanel createButtonsPanel(final StatusGenericPanel panel) 248 { 249 JPanel buttonsPanel = new JPanel(new GridBagLayout()); 250 GridBagConstraints gbc = new GridBagConstraints(); 251 ButtonType buttonType = panel.getButtonType(); 252 gbc.gridx = 0; 253 gbc.weightx = 1.0; 254 gbc.fill = GridBagConstraints.HORIZONTAL; 255 buttonsPanel.add(Box.createHorizontalGlue(), gbc); 256 buttonsPanel.setOpaque(true); 257 buttonsPanel.setBackground(buttonPanelBackground); 258 gbc.insets = new Insets(10, 0, 10, 0); 259 gbc.insets.left = 5; 260 261 if (buttonType == ButtonType.OK_CANCEL) 262 { 263 gbc.gridx ++; 264 gbc.weightx = 0.0; 265 okButton = Utilities.createButton( 266 INFO_CTRL_PANEL_OK_BUTTON_LABEL.get()); 267 okButton.setOpaque(false); 268 buttonsPanel.add(okButton, gbc); 269 okButton.addActionListener(new ActionListener() 270 { 271 public void actionPerformed(ActionEvent ev) 272 { 273 panel.okClicked(); 274 } 275 }); 276 okButton.setEnabled(panel.isEnableOK()); 277 278 gbc.gridx ++; 279 cancelButton = Utilities.createButton( 280 INFO_CTRL_PANEL_CANCEL_BUTTON_LABEL.get()); 281 cancelButton.setOpaque(false); 282 cancelButton.addActionListener(new ActionListener() 283 { 284 public void actionPerformed(ActionEvent ev) 285 { 286 panel.cancelClicked(); 287 } 288 }); 289 cancelButton.setEnabled(panel.isEnableCancel()); 290 gbc.insets.right = 10; 291 buttonsPanel.add(cancelButton, gbc); 292 } 293 294 if (buttonType == ButtonType.OK) 295 { 296 gbc.gridx ++; 297 gbc.weightx = 0.0; 298 okButton = Utilities.createButton( 299 INFO_CTRL_PANEL_OK_BUTTON_LABEL.get()); 300 okButton.setOpaque(false); 301 gbc.insets.right = 10; 302 buttonsPanel.add(okButton, gbc); 303 okButton.addActionListener(new ActionListener() 304 { 305 public void actionPerformed(ActionEvent ev) 306 { 307 panel.okClicked(); 308 } 309 }); 310 okButton.setEnabled(panel.isEnableOK()); 311 } 312 313 if (buttonType == ButtonType.CLOSE) 314 { 315 gbc.gridx ++; 316 gbc.weightx = 0.0; 317 closeButton = Utilities.createButton( 318 INFO_CTRL_PANEL_CLOSE_BUTTON_LABEL.get()); 319 closeButton.setOpaque(false); 320 gbc.insets.right = 10; 321 buttonsPanel.add(closeButton, gbc); 322 closeButton.addActionListener(new ActionListener() 323 { 324 public void actionPerformed(ActionEvent ev) 325 { 326 panel.closeClicked(); 327 } 328 }); 329 closeButton.setEnabled(panel.isEnableClose()); 330 } 331 332 333 334 buttonsPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, 335 ColorAndFontConstants.defaultBorderColor)); 336 return buttonsPanel; 337 } 338 339 /** 340 * Updates the default button of the frame, depending on the type of 341 * generic panel that it contains. 342 * @param panel the generic panel contained in this frame. 343 */ 344 private void updateDefaultButton(StatusGenericPanel panel) 345 { 346 ButtonType buttonType = panel.getButtonType(); 347 348 if (buttonType == ButtonType.OK_CANCEL) 349 { 350 getRootPane().setDefaultButton(okButton); 351 } 352 else if (buttonType == ButtonType.OK) 353 { 354 getRootPane().setDefaultButton(okButton); 355 } 356 else if (buttonType == ButtonType.CLOSE) 357 { 358 getRootPane().setDefaultButton(closeButton); 359 } 360 } 361} 362