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