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