/*
|
* The contents of this file are subject to the terms of the Common Development and
|
* Distribution License (the License). You may not use this file except in compliance with the
|
* License.
|
*
|
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
|
* specific language governing permission and limitations under the License.
|
*
|
* When distributing Covered Software, include this CDDL Header Notice in each file and include
|
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
|
* Header, with the fields enclosed by brackets [] replaced by your own identifying
|
* information: "Portions Copyright [year] [name of copyright owner]".
|
*
|
* Copyright 2008-2009 Sun Microsystems, Inc.
|
* Portions Copyright 2014-2016 ForgeRock AS.
|
*/
|
package org.opends.guitools.controlpanel.ui;
|
|
import static org.opends.messages.AdminToolMessages.*;
|
|
import java.awt.Color;
|
import java.awt.Component;
|
import java.awt.Container;
|
import java.awt.GridBagConstraints;
|
import java.awt.GridBagLayout;
|
import java.awt.Insets;
|
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionListener;
|
import java.awt.event.FocusAdapter;
|
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusListener;
|
import java.awt.event.KeyEvent;
|
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowEvent;
|
|
import javax.swing.AbstractButton;
|
import javax.swing.BorderFactory;
|
import javax.swing.Box;
|
import javax.swing.JButton;
|
import javax.swing.JComboBox;
|
import javax.swing.JComponent;
|
import javax.swing.JDialog;
|
import javax.swing.JFrame;
|
import javax.swing.JList;
|
import javax.swing.JMenuBar;
|
import javax.swing.JPanel;
|
import javax.swing.JScrollPane;
|
import javax.swing.JTable;
|
import javax.swing.JViewport;
|
import javax.swing.KeyStroke;
|
import javax.swing.SwingUtilities;
|
import javax.swing.border.EmptyBorder;
|
import javax.swing.text.JTextComponent;
|
|
import org.opends.guitools.controlpanel.util.Utilities;
|
import org.opends.server.util.DynamicConstants;
|
|
/** The generic dialog of the Control Panel. It contains a StatusGenericPanel. */
|
public class GenericDialog extends JDialog
|
{
|
private static final long serialVersionUID = -2643144936460484112L;
|
private static final Color buttonPanelBackground =
|
ColorAndFontConstants.greyBackground;
|
private JButton okButton;
|
|
/** The close button. */
|
private JButton closeButton;
|
private JButton cancelButton;
|
/** The panel contained in the dialog. */
|
protected StatusGenericPanel panel;
|
private Component lastComponentWithFocus;
|
|
/** The different combinations of buttons that the dialog can have. */
|
public enum ButtonType
|
{
|
/** The dialog contains OK and CANCEL buttons. */
|
OK_CANCEL,
|
/** The dialog contains a OK button. */
|
OK,
|
/** The dialog contains a CLOSE button. */
|
CLOSE,
|
/** The dialog has no buttons. */
|
NO_BUTTON
|
}
|
|
/**
|
* Constructor of the dialog.
|
* @param parentFrame the parent frame of the dialog.
|
* @param panel the panel contained in this dialog.
|
*/
|
public GenericDialog(JFrame parentFrame, StatusGenericPanel panel)
|
{
|
super(parentFrame);
|
this.panel = panel;
|
if (panel.requiresBorder())
|
{
|
setDefaultBorder(panel);
|
}
|
JMenuBar menu = panel.getMenuBar();
|
if (menu != null)
|
{
|
parentFrame.setJMenuBar(menu);
|
}
|
setResizable(true);
|
JScrollPane scroll = Utilities.createScrollPane(panel);
|
JPanel inputPanel = new JPanel(new GridBagLayout());
|
setContentPane(inputPanel);
|
GridBagConstraints gbc = new GridBagConstraints();
|
gbc.weightx = 1.0;
|
gbc.weighty = 1.0;
|
gbc.gridx = 0;
|
gbc.gridy = 0;
|
gbc.fill = GridBagConstraints.BOTH;
|
if (panel.requiresScroll())
|
{
|
inputPanel.add(scroll, gbc);
|
}
|
else
|
{
|
inputPanel.add(panel, gbc);
|
}
|
if (panel.getButtonType() != ButtonType.NO_BUTTON)
|
{
|
gbc.gridy ++;
|
gbc.weighty = 0.0;
|
inputPanel.add(createButtonsPanel(panel), gbc);
|
}
|
|
KeyStroke stroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
|
ActionListener actionListener = new ActionListener()
|
{
|
@Override
|
public void actionPerformed(ActionEvent ev)
|
{
|
setVisible(false);
|
}
|
};
|
getRootPane().registerKeyboardAction(actionListener, stroke,
|
JComponent.WHEN_IN_FOCUSED_WINDOW);
|
|
FocusListener focusListener = new FocusAdapter()
|
{
|
@Override
|
public void focusGained(FocusEvent ev)
|
{
|
lastComponentWithFocus = ev.getComponent();
|
}
|
};
|
addFocusListener(focusListener, panel);
|
|
addWindowListener(new WindowAdapter() {
|
@Override
|
public void windowClosing(WindowEvent e) {
|
GenericDialog.this.panel.closeClicked();
|
}
|
});
|
|
pack();
|
if (!SwingUtilities.isEventDispatchThread())
|
{
|
Thread.dumpStack();
|
}
|
}
|
|
/**
|
* Method used to add a focus listeners to all the components in the panel.
|
* This is done to recover the focus on an item when the dialog is closed
|
* and then opened again.
|
* @param focusListener the focus listener.
|
* @param container the container where the components are layed out.
|
*/
|
private void addFocusListener(FocusListener focusListener,
|
Container container)
|
{
|
for (int i=0; i < container.getComponentCount(); i++)
|
{
|
Component comp = container.getComponent(i);
|
if (comp instanceof AbstractButton ||
|
comp instanceof JTextComponent ||
|
comp instanceof JList ||
|
comp instanceof JComboBox ||
|
comp instanceof JTable)
|
{
|
comp.addFocusListener(focusListener);
|
}
|
else if (comp instanceof JPanel || comp instanceof JScrollPane
|
|| comp instanceof JViewport)
|
{
|
addFocusListener(focusListener, (Container)comp);
|
}
|
}
|
}
|
|
@Override
|
public void setVisible(boolean visible)
|
{
|
if (visible && lastComponentWithFocus == null)
|
{
|
lastComponentWithFocus = panel.getPreferredFocusComponent();
|
}
|
if (visible && lastComponentWithFocus != null && lastComponentWithFocus.isVisible())
|
{
|
if (lastComponentWithFocus == null)
|
{
|
lastComponentWithFocus = panel.getPreferredFocusComponent();
|
}
|
lastComponentWithFocus.requestFocusInWindow();
|
}
|
updateDefaultButton(panel);
|
panel.toBeDisplayed(visible);
|
updateTitle();
|
super.setVisible(visible);
|
}
|
|
/**
|
* Sets the enable state of the OK button.
|
* @param enable whether the OK button must be enabled or not.
|
*/
|
public void setEnabledOK(boolean enable)
|
{
|
okButton.setEnabled(enable);
|
}
|
|
/**
|
* Sets the enable state of the Cancel button.
|
* @param enable whether the Cancel button must be enabled or not.
|
*/
|
public void setEnabledCancel(boolean enable)
|
{
|
cancelButton.setEnabled(enable);
|
}
|
|
/**
|
* Sets the enable state of the Close button.
|
* @param enable whether the Close button must be enabled or not.
|
*/
|
public void setEnabledClose(boolean enable)
|
{
|
closeButton.setEnabled(enable);
|
}
|
|
/** Updates the title of the dialog using the title of the panel. */
|
public void updateTitle()
|
{
|
if (panel.getTitle() != null)
|
{
|
setTitle(INFO_CTRL_PANEL_GENERIC_TITLE.get(
|
DynamicConstants.PRODUCT_NAME, panel.getTitle()).toString());
|
}
|
}
|
|
private void setDefaultBorder(JComponent comp)
|
{
|
Utilities.setBorder(comp, new EmptyBorder(20, 20, 20, 20));
|
}
|
|
private JPanel createButtonsPanel(final StatusGenericPanel panel)
|
{
|
JPanel buttonsPanel = new JPanel(new GridBagLayout());
|
GridBagConstraints gbc = new GridBagConstraints();
|
ButtonType buttonType = panel.getButtonType();
|
gbc.gridx = 0;
|
gbc.weightx = 1.0;
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
buttonsPanel.add(Box.createHorizontalGlue(), gbc);
|
buttonsPanel.setOpaque(true);
|
buttonsPanel.setBackground(buttonPanelBackground);
|
gbc.insets = new Insets(10, 0, 10, 0);
|
gbc.insets.left = 5;
|
|
if (buttonType == ButtonType.OK_CANCEL)
|
{
|
gbc.gridx ++;
|
gbc.weightx = 0.0;
|
okButton = Utilities.createButton(
|
INFO_CTRL_PANEL_OK_BUTTON_LABEL.get());
|
okButton.setOpaque(false);
|
buttonsPanel.add(okButton, gbc);
|
okButton.addActionListener(new ActionListener()
|
{
|
@Override
|
public void actionPerformed(ActionEvent ev)
|
{
|
panel.okClicked();
|
}
|
});
|
okButton.setEnabled(panel.isEnableOK());
|
|
gbc.gridx ++;
|
cancelButton = Utilities.createButton(
|
INFO_CTRL_PANEL_CANCEL_BUTTON_LABEL.get());
|
cancelButton.setOpaque(false);
|
cancelButton.addActionListener(new ActionListener()
|
{
|
@Override
|
public void actionPerformed(ActionEvent ev)
|
{
|
panel.cancelClicked();
|
}
|
});
|
cancelButton.setEnabled(panel.isEnableCancel());
|
gbc.insets.right = 10;
|
buttonsPanel.add(cancelButton, gbc);
|
}
|
|
if (buttonType == ButtonType.OK)
|
{
|
gbc.gridx ++;
|
gbc.weightx = 0.0;
|
okButton = Utilities.createButton(
|
INFO_CTRL_PANEL_OK_BUTTON_LABEL.get());
|
okButton.setOpaque(false);
|
gbc.insets.right = 10;
|
buttonsPanel.add(okButton, gbc);
|
okButton.addActionListener(new ActionListener()
|
{
|
@Override
|
public void actionPerformed(ActionEvent ev)
|
{
|
panel.okClicked();
|
}
|
});
|
okButton.setEnabled(panel.isEnableOK());
|
}
|
|
if (buttonType == ButtonType.CLOSE)
|
{
|
gbc.gridx ++;
|
gbc.weightx = 0.0;
|
closeButton = Utilities.createButton(
|
INFO_CTRL_PANEL_CLOSE_BUTTON_LABEL.get());
|
closeButton.setOpaque(false);
|
gbc.insets.right = 10;
|
buttonsPanel.add(closeButton, gbc);
|
closeButton.addActionListener(new ActionListener()
|
{
|
@Override
|
public void actionPerformed(ActionEvent ev)
|
{
|
panel.closeClicked();
|
}
|
});
|
closeButton.setEnabled(panel.isEnableClose());
|
}
|
|
|
|
buttonsPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0,
|
ColorAndFontConstants.defaultBorderColor));
|
return buttonsPanel;
|
}
|
|
/**
|
* Updates the default button of the dialog, depending on the type of
|
* generic panel that it contains.
|
* @param panel the generic panel contained in this dialog.
|
*/
|
private void updateDefaultButton(StatusGenericPanel panel)
|
{
|
ButtonType buttonType = panel.getButtonType();
|
|
if (buttonType == ButtonType.OK_CANCEL)
|
{
|
getRootPane().setDefaultButton(okButton);
|
}
|
else if (buttonType == ButtonType.OK)
|
{
|
getRootPane().setDefaultButton(okButton);
|
}
|
else if (buttonType == ButtonType.CLOSE)
|
{
|
getRootPane().setDefaultButton(closeButton);
|
}
|
}
|
}
|