/* * Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * * Neither the name of Business Objects nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ /* * DetailsDialog.java * Creation date: Sep 30, 2002. * By: Edward Lam */ package org.openquark.util.ui; import java.awt.Dialog; import java.awt.Dimension; import java.awt.Font; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.KeyStroke; import org.openquark.util.Messages; /** * A message dialog very similar to the type displayed by JOptionPane, * but with two buttons: OK and Details. * The Details button shows or hides an additional panel with details in it. * @author Edward Lam */ public class DetailsDialog extends DialogBase { private static final long serialVersionUID = -5170897673341834973L; /** The font to use for the details. */ private static final Font DETAILS_FONT = new Font("sansserif", Font.PLAIN, 11); //$NON-NLS-1$ /** Use this message bundle to get string resources. */ private static Messages messages = UIMessages.instance; private static final String EXPAND_DETAILS_STRING = messages.getString("DD_ExpandDetails"); //$NON-NLS-1$ private static final String CONTRACT_DETAILS_STRING = messages.getString("DD_ContractDetails"); //$NON-NLS-1$ private static final int DETAILS_BUTTON_MNEMONIC = KeyStroke.getKeyStroke(messages.getString("DD_DetailsMnemonic")).getKeyCode(); //$NON-NLS-1$ /** The ok button. */ private JButton okButton; /** The details button. */ private JButton detailsButton; /** The details pane. */ private JScrollPane detailsPane; /** * Message Type enum pattern. * @author Edward Lam */ public enum MessageType { PLAIN, ERROR, INFORMATION, WARNING, QUESTION } /** * Constructor for a DetailsDialog constructor. * @param owner the Dialog from which the dialog is displayed * @param title the String to display in the dialog's title bar * @param message a message to be placed in the dialog box * @param details the details displayed in the details pane * @param icon the (optional) icon to use. Null for no icon. */ public DetailsDialog(Dialog owner, String title, String message, String details, Icon icon) { super(owner, title); initialize(message, details, icon); } /** * Constructor for a DetailsDialog constructor. * @param owner the Dialog from which the dialog is displayed * @param title the String to display in the dialog's title bar * @param message a message to be placed in the dialog box * @param details the details displayed in the details pane * @param type the type of message. This is used to set the icon. */ public DetailsDialog(Dialog owner, String title, String message, String details, MessageType type) { super(owner, title); initialize(message, details, getIconForType(type)); } /** * Constructor for a DetailsDialog constructor. * @param owner the Frame from which the dialog is displayed * @param title the String to display in the dialog's title bar * @param message a message to be placed in the dialog box * @param details the details displayed in the details pane * @param icon the (optional) icon to use. Null for no icon. */ public DetailsDialog(Frame owner, String title, String message, String details, Icon icon) { super(owner, title); initialize(message, details, icon); } /** * Constructor for a DetailsDialog constructor. * @param owner the Frame from which the dialog is displayed * @param title the String to display in the dialog's title bar * @param message a message to be placed in the dialog box * @param details the details displayed in the details pane * @param type the type of message. This is used to set the icon. */ public DetailsDialog(Frame owner, String title, String message, String details, MessageType type) { super(owner, title); initialize(message, details, getIconForType(type)); } /** * Initialize the dialog. * @param message the dialog message * @param details the details to display in the details pane * @param icon the (optional) icon to display. Null to display no icon */ private void initialize(String message, String details, Icon icon) { setName("DetailsDialog"); //$NON-NLS-1$ setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); // main panel JPanel topPanel = getTopPanel(); setContentPane(topPanel); // Keep track of the number of rows. int numRows = 0; // Add the message text area { GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = 0; constraints.gridy = numRows; constraints.fill = GridBagConstraints.HORIZONTAL; constraints.anchor = GridBagConstraints.NORTHWEST; constraints.insets = new Insets(5, 10, 5, 5); JTextArea messageArea = new JTextArea(); messageArea.setText(message); messageArea.setLineWrap(true); messageArea.setWrapStyleWord(true); messageArea.setEditable(false); messageArea.setBackground(getBackground()); messageArea.setForeground(getForeground()); messageArea.setSelectionColor(getBackground()); messageArea.setSelectedTextColor(getForeground()); messageArea.setCaretColor(getBackground()); // icon label JLabel iconLabel = null; if (icon != null) { iconLabel = new JLabel(); iconLabel.setIcon(icon); iconLabel.setText(""); //$NON-NLS-1$ } // icon/message box JPanel iconMessageBox = new JPanel(); iconMessageBox.setLayout(new BoxLayout(iconMessageBox, BoxLayout.X_AXIS)); if (iconLabel != null) { iconMessageBox.add(iconLabel); iconMessageBox.add(Box.createHorizontalStrut(15)); } iconMessageBox.add(messageArea); iconMessageBox.add(Box.createHorizontalGlue()); getTopPanel().add(iconMessageBox, constraints); numRows++; } // Add an invisible area which will expand if there is no details area. { GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = 0; constraints.gridy = numRows; constraints.weightx = 0.00001; constraints.weighty = 0.00001; JPanel panel = new JPanel(); getTopPanel().add(panel, constraints); numRows++; } // Add the button area. { GridBagConstraints constraints = new GridBagConstraints(); constraints.gridy = numRows; constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.anchor = GridBagConstraints.SOUTHEAST; // ok button okButton = makeOKButton(); // details button detailsButton = new JButton(); detailsButton.setText(EXPAND_DETAILS_STRING); detailsButton.setMnemonic(DETAILS_BUTTON_MNEMONIC); // button box Box buttonBox = Box.createHorizontalBox(); buttonBox.add(Box.createHorizontalGlue()); buttonBox.add(Box.createHorizontalStrut(150)); // to make the dialog pack to a reasonable width buttonBox.add(okButton); buttonBox.add(Box.createHorizontalStrut(10)); buttonBox.add(detailsButton); getTopPanel().add(buttonBox, constraints); numRows++; } // Add the details text area { GridBagConstraints constraints = new GridBagConstraints(); constraints.gridx = 0; constraints.gridy = numRows; constraints.weightx = 1.0; constraints.weighty = 1.0; constraints.gridwidth = GridBagConstraints.REMAINDER; constraints.fill = GridBagConstraints.BOTH; constraints.insets = new Insets(5, 5, 5, 5); final JTextArea displayComponent = new JTextArea(); displayComponent.setFont(DETAILS_FONT); displayComponent.setText(details); displayComponent.setEditable(false); displayComponent.setLineWrap(false); displayComponent.setCaretPosition(0); detailsPane = new JScrollPane(displayComponent); detailsPane.setVisible(false); // Clamp preferred size to between 100 and 500. Dimension preferredDim = detailsPane.getPreferredSize(); preferredDim.width += 10; if (preferredDim.width < 100) { preferredDim.width = 100; } else if (preferredDim.width > 500) { preferredDim.width = 500; } preferredDim.height += 10; if (preferredDim.height < 100) { preferredDim.height = 100; } else if (preferredDim.height > 500) { preferredDim.height = 500; } detailsPane.setPreferredSize(preferredDim); getTopPanel().add(detailsPane, constraints); numRows++; } // final setup pack(); addComponentListener(new SizeConstrainer(getSize())); getRootPane().setDefaultButton(okButton); setupCancelAction(""); //$NON-NLS-1$ // handle details button event detailsButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { boolean visible = !detailsPane.isVisible(); setDetailsVisible(visible); } }); } /** * Set whether the details area is visible. * @param visible the new visibility of the details area. */ public void setDetailsVisible(boolean visible) { detailsButton.setText(visible ? CONTRACT_DETAILS_STRING : EXPAND_DETAILS_STRING); detailsPane.setVisible(visible); pack(); } /** * Returns the icon to use for the passed in type. * @param messageType the message type. Null for no icon. * @return Icon the corresponding icon */ private Icon getIconForType(MessageType messageType) { // Just take the corresponding icon for the JOptionPane if (messageType == MessageType.ERROR) { return UIUtilities.getJOptionPaneIcon(JOptionPane.ERROR_MESSAGE); } else if (messageType == MessageType.INFORMATION) { return UIUtilities.getJOptionPaneIcon(JOptionPane.INFORMATION_MESSAGE); } else if (messageType == MessageType.WARNING) { return UIUtilities.getJOptionPaneIcon(JOptionPane.WARNING_MESSAGE); } else if (messageType == MessageType.QUESTION) { return UIUtilities.getJOptionPaneIcon(JOptionPane.QUESTION_MESSAGE); } return null; } }