home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
jfc.bin
/
MacOptionPaneUI.java
< prev
next >
Wrap
Text File
|
1998-02-26
|
18KB
|
576 lines
/*
* @(#)MacOptionPaneUI.java 1.6 98/02/02
*
* Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
*
* This software is the confidential and proprietary information of Sun
* Microsystems, Inc. ("Confidential Information"). You shall not
* disclose such Confidential Information and shall use it only in
* accordance with the terms of the license agreement you entered into
* with Sun.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
* SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
* IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
* SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
* THIS SOFTWARE OR ITS DERIVATIVES.
*
*/
package com.sun.java.swing.plaf.mac;
import com.sun.java.swing.*;
import com.sun.java.swing.plaf.basic.*;
import com.sun.java.swing.plaf.ComponentUI;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
/**
* Provides the CDE/Mac look and feel for a JOptionPane.
* <p>
* Warning: serialized objects of this class will not be compatible with
* future swing releases. The current serialization support is appropriate
* for short term storage or RMI between Swing1.0 applications. It will
* not be possible to load serialized Swing1.0 objects with future releases
* of Swing. The JDK1.2 release of Swing will be the compatibility
* baseline for the serialized form of Swing objects.
*
* @version @(#)MacOptionPaneUI.java 1.0 11/24/97
* @author Symantec
*/
public class MacOptionPaneUI extends BasicOptionPaneUI
{
/** Option names for YES_NO_OPTION. */
public static final String[] yesNoOptions = { "No", "Yes" };
public static final int[] yesNoReturnValue = { JOptionPane.NO_OPTION, JOptionPane.YES_OPTION };
/** Options names for YES_NO_CANCEL_OPTION. */
public static final String[] yesNoCancelOptions = { "Cancel", "No", "Yes" };
public static final int[] yesNoCancelReturnValue = { JOptionPane.CANCEL_OPTION, JOptionPane.NO_OPTION, JOptionPane.YES_OPTION };
/** Default option names, when none are supplied. */
public static final String[] defaultOptions = { "OK" };
/** Option names for OK_CANCEL_OPTION. */
public static final String[] okCancelOptions = { "Cancel", "OK" };
public static final int[] okCancelReturnValue = { JOptionPane.CANCEL_OPTION, JOptionPane.OK_OPTION };
private boolean hasIcon = false;
/**
* Creates a new MacOptionPaneUI instance.
*/
public static ComponentUI createUI(JComponent x) {
return new MacOptionPaneUI();
}
/**
* Returns the buttons to display from the JOptionPane the receiver is
* providing the look and feel for. If the JOptionPane has options
* set, they will be provided, otherwise if the optionType is
* YES_NO_OPTION, yesNoOptions is returned, if the type is
* YES_NO_CANCEL_OPTION yesNoCancelOptions is returned, otherwise
* defaultButtons are returned.
*
* Overrides the basic UI implementation because the buttons are in the
* opposite order on the Mac
*/
public Object[] getButtons() {
if (optionPane != null) {
Object[] suppliedOptions = optionPane.getOptions();
if (suppliedOptions == null) {
int type = optionPane.getOptionType();
if (type == JOptionPane.YES_NO_OPTION)
return MacOptionPaneUI.yesNoOptions;
else if (type == JOptionPane.YES_NO_CANCEL_OPTION)
return MacOptionPaneUI.yesNoCancelOptions;
else if (type == JOptionPane.OK_CANCEL_OPTION)
return MacOptionPaneUI.okCancelOptions;
return MacOptionPaneUI.defaultOptions;
}
return suppliedOptions;
}
return null;
}
/**
* Messaged when a JButton as created from validateComponent is clicked
* Invokes setValue on the JOptionPane with the appropriate value.
* <p>
* If you are creating your own look and feel and subclassing this
* be sure to set the value to an Integer value representing
* YES_OPTION, NO_OPTION or CANCEL_OPTION.
*/
public void createdButtonFired(int buttonIndex) {
if (optionPane != null) {
Object[] options = optionPane.getOptions();
if (options == null) {
int messageType = optionPane.getOptionType();
int returnVal;
if (messageType == JOptionPane.YES_NO_OPTION)
returnVal = yesNoReturnValue[buttonIndex];
else if (messageType == JOptionPane.OK_CANCEL_OPTION)
returnVal = okCancelReturnValue[buttonIndex];
else if (messageType == JOptionPane.YES_NO_CANCEL_OPTION)
returnVal = yesNoCancelReturnValue[buttonIndex];
else
returnVal = JOptionPane.OK_OPTION;
// OK or Yes button was pressed in an input dialog
// (!!! duplicating the strange BasicUI behaviour of not reseting for default options !!!)
if (inputComponent != null && returnVal == JOptionPane.OK_OPTION &&
messageType != JOptionPane.DEFAULT_OPTION)
resetInputValue();
optionPane.setValue(new Integer(returnVal));
}
else
optionPane.setValue(options[buttonIndex]);
}
}
/**
* Returns the icon to use for the passed in type.
*
* No icon for Mac input dialogs (no question icon)
*/
public Icon getIconForType(int messageType) {
switch(messageType) {
case 0:
return UIManager.getIcon("OptionPane.errorIcon");
case 1:
return UIManager.getIcon("OptionPane.informationIcon");
case 2:
return UIManager.getIcon("OptionPane.warningIcon");
}
return null;
}
/**
* Make the dialog box non-resizeable - like they ought to be on the Mac
*/
public void selectInitialValue() {
super.selectInitialValue();
Container dialog = optionPane.getParent();
while (dialog != null) {
if (dialog instanceof JDialog) {
((JDialog) dialog).setBackground(UIManager.getColor("window"));
((JDialog) dialog).setResizable(false);
break;
}
dialog = dialog.getParent();
}
}
/**
* Creates and adds a JLabel representing the icon returned from
* <code>getIcon</code> to <code>top</code>. This is messaged from
* <code>createBody</code>
*/
protected void addIcon(Container top) {
/* Create the icon. */
Icon sideIcon = getIcon();
if (sideIcon != null) {
JLabel iconLabel = new JLabel(sideIcon);
iconLabel.setVerticalAlignment(SwingConstants.TOP);
iconLabel.setHorizontalAlignment(SwingConstants.LEFT);
top.add(iconLabel, "West");
hasIcon = true;
} else
hasIcon = false;
}
/**
* Messaged from validateComponent to create a Container containing the
* body of the message. The icon is the created by calling
* <code>addIcon</code>.
*/
protected Container createBody() {
Container top = new Container() {
public Insets getInsets() {
return getBodyInsets();
}
};
top.setLayout(new BorderLayout());
/* Fill the body. */
GridBagConstraints cons = new GridBagConstraints();
Container body = new Container() {};
Container realBody = new Container() {};
realBody.setLayout(new BorderLayout());
realBody.add(new Container() {
public Dimension getPreferredSize() {
return (hasIcon) ? new Dimension(23, 1) : new Dimension(1, 1);
}
}, BorderLayout.WEST);
Container anotherBody = new Container() {};
anotherBody.setLayout(new BorderLayout());
anotherBody.add(body, BorderLayout.NORTH);
realBody.add(anotherBody, BorderLayout.CENTER);
// realBody.add(body, BorderLayout.CENTER);
body.setLayout(new GridBagLayout());
cons.gridx = cons.gridy = 0;
cons.gridwidth = GridBagConstraints.REMAINDER;
cons.gridheight = 1;
cons.anchor = GridBagConstraints.WEST;
cons.insets = new Insets(0,0,3,0);
appendDescription(body, cons, getMessage(),
getMaxCharactersPerLineCount(), false);
top.add(realBody, BorderLayout.CENTER);
addIcon(top);
return top;
}
/**
* Returns the maximum number of characters to place on a line.
*/
public int getMaxCharactersPerLineCount() {
int max = optionPane.getMaxCharactersPerLineCount();
if (max == Integer.MAX_VALUE)
return 60;
else
return max;
}
/**
* Returns the insets to be used for the body, the body contains both
* the image and the actual message.
*/
protected Insets getBodyInsets() {
return new Insets(0, 7, 0, 6);
}
/**
* Returns false. This is queried to determine if the buttons should
* be sized to the same width.
*/
public boolean getSizeButtonsToSameWidth() {
return false;
}
/**
* Creates the appropriate object to represent each of the objects in
* <code>buttons</code> and adds it to <code>container</code>. This
* differs from appendDescription in that it will recurse on
* <code>buttons</code> and that if button is not a Component
* it will create an instance of JButton, that when pressed will
* invoke <code>createdButtonFired</code> with the appropriate
* index.
*/
protected void appendButtons(Container container, Object[] buttons,
int initialIndex) {
if(buttons != null && buttons.length > 0) {
boolean sizeButtonsToSame = getSizeButtonsToSameWidth();
boolean createdAll = true;
int numButtons = buttons.length;
JButton[] createdButtons = null;
int maxWidth = 0;
if(sizeButtonsToSame)
createdButtons = new JButton[numButtons];
for(int counter = 0; counter < numButtons; counter++) {
Object anO = buttons[counter];
Component newComponent;
if(anO instanceof Component) {
createdAll = false;
newComponent = (Component)anO;
container.add(newComponent);
hasCustomComponents = true;
}
else {
JButton aButton;
if(anO instanceof Icon)
aButton = new JButton((Icon)anO);
else
aButton = new JButton(anO.toString());
container.add(aButton);
final int buttonIndex = counter;
aButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
createdButtonFired(buttonIndex);
}
});
newComponent = aButton;
}
if(sizeButtonsToSame && createdAll &&
(newComponent instanceof JButton)) {
createdButtons[counter] = (JButton)newComponent;
maxWidth = Math.max(maxWidth,
newComponent.getMinimumSize().width);
}
if(counter == initialIndex) {
initialFocusComponent = newComponent;
}
}
((MacSyncingLayoutManager)container.getLayout()).
setSyncsAll((sizeButtonsToSame && createdAll));
/* Set the padding, windows seems to use 8 if <= 2 components,
otherwise 4 is used. It may actually just be the size of the
buttons is always the same, not sure. */
if(sizeButtonsToSame && createdAll) {
JButton aButton;
int padSize;
if(numButtons <= 2)
padSize = 8;
else
padSize = 4;
for(int counter = 0; counter < numButtons; counter++) {
aButton = createdButtons[counter];
aButton.setMargin(new Insets(2, padSize, 2, padSize));
}
}
}
}
/**
* Creates and returns a Container containin the buttons. The buttons
* are created by calling <code>getButtons</code>.
*/
protected Container createButtons() {
/* And the bottom for all the buttons. */
Container b = new Container() {
public Insets getInsets() {
return getButtonInsets();
}
};
b.setLayout(new MacSyncingLayoutManager(true, 13));
appendButtons(b, getButtons(), getInitialIndex());
// move everything over to the right
Container outerContainer = new Container() {};
outerContainer.setLayout(new BorderLayout());
outerContainer.add(new Container() {}, BorderLayout.CENTER);
outerContainer.add(b, BorderLayout.EAST);
((MacSyncingLayoutManager)b.getLayout()).setCentersChildren(true);
((MacSyncingLayoutManager)b.getLayout()).setMinButtonWidth(58);
return outerContainer;
}
/**
* Returns the insets to be used in the Container housing the buttons.
*/
protected Insets getButtonInsets() {
return new Insets(11, 16, 0, 6);
}
/**
* Returns the minumum size of a button in a dialog for this look & feel.
*/
protected int getMinimumButtonWidth() {
return 58;
}
/**
* MacSyncingLayoutManager acts similiar to FlowLayout. It lays out all
* components from left to right. If syncsAll is true, the widths
* of each component will be set to the largest preferred size width.
*/
protected static class MacSyncingLayoutManager implements LayoutManager,
Serializable {
protected boolean syncsAll;
protected int padding;
/** If true, children are lumped together in parent. */
protected boolean centersChildren;
protected int minButtonWidth;
public MacSyncingLayoutManager(boolean syncsAll, int padding) {
this.syncsAll = syncsAll;
this.padding = padding;
this.minButtonWidth = 0;
centersChildren = true;
}
public void setSyncsAll(boolean newValue) {
syncsAll = newValue;
}
public boolean getSyncsAll() {
return syncsAll;
}
public void setPadding(int newPadding) {
this.padding = newPadding;
}
public int getPadding() {
return padding;
}
public void setCentersChildren(boolean newValue) {
centersChildren = newValue;
}
public boolean getCentersChildren() {
return centersChildren;
}
public void setMinButtonWidth(int minButtonWidth) {
this.minButtonWidth = minButtonWidth;
}
public int getMinButtonWidth() {
return minButtonWidth;
}
public void addLayoutComponent(String string, Component comp) {
}
public void layoutContainer(Container container) {
Component[] children = container.getComponents();
if(children != null && children.length > 0) {
int numChildren = children.length;
Dimension[] sizes = new Dimension[numChildren];
int counter;
int yLocation = container.getInsets().top;
if (syncsAll) {
int maxWidth = minButtonWidth;
for(counter = 0; counter < numChildren; counter++) {
sizes[counter] = children[counter].getPreferredSize();
maxWidth = Math.max(maxWidth, sizes[counter].width);
}
int xLocation;
int xOffset;
if (getCentersChildren()) {
xLocation = (container.getSize().width -
(maxWidth * numChildren +
(numChildren - 1) * padding)) / 2;
xOffset = padding + maxWidth;
}
else {
if(numChildren > 1) {
xLocation = 0;
xOffset = (container.getSize().width -
(maxWidth * numChildren)) /
(numChildren - 1) + maxWidth;
}
else {
xLocation = (container.getSize().width -
maxWidth) / 2;
xOffset = 0;
}
}
for(counter = 0; counter < numChildren; counter++) {
children[counter].setBounds(xLocation, yLocation,
maxWidth,
sizes[counter].height);
xLocation += xOffset;
}
}
else {
int totalWidth = 0;
for(counter = 0; counter < numChildren; counter++) {
sizes[counter] = children[counter].getPreferredSize();
sizes[counter].width = Math.max(sizes[counter].width, minButtonWidth);
totalWidth += sizes[counter].width;
}
totalWidth += ((numChildren - 1) * padding);
boolean cc = getCentersChildren();
int xOffset;
int xLocation;
if(cc) {
xLocation = (container.getSize().width -
totalWidth) / 2;
xOffset = padding;
}
else {
if(numChildren > 1) {
xOffset = (container.getSize().width -
totalWidth) / (numChildren - 1);
xLocation = 0;
}
else {
xLocation = (container.getSize().width -
totalWidth) / 2;
xOffset = 0;
}
}
for(counter = 0; counter < numChildren; counter++) {
children[counter].setBounds(xLocation, yLocation,
sizes[counter].width, sizes[counter].height);
xLocation += xOffset + sizes[counter].width;
}
}
}
}
public Dimension minimumLayoutSize(Container c) {
if(c != null) {
Component[] children = c.getComponents();
if(children != null && children.length > 0) {
Dimension aSize;
int numChildren = children.length;
int height = 0;
Insets cInsets = c.getInsets();
int extraHeight = cInsets.top + cInsets.bottom;
if(syncsAll) {
int maxWidth = minButtonWidth;
for(int counter = 0; counter < numChildren; counter++){
aSize = children[counter].getPreferredSize();
height = Math.max(height, aSize.height);
maxWidth = Math.max(maxWidth, aSize.width);
}
return new Dimension(maxWidth * numChildren +
(numChildren - 1) * padding,
extraHeight + height);
}
else {
int totalWidth = 0;
for(int counter = 0; counter < numChildren; counter++){
aSize = children[counter].getPreferredSize();
height = Math.max(height, aSize.height);
totalWidth += Math.max(aSize.width, minButtonWidth);
}
totalWidth += ((numChildren - 1) * padding);
return new Dimension(totalWidth, extraHeight + height);
}
}
}
return new Dimension(0, 0);
}
public Dimension preferredLayoutSize(Container c) {
return minimumLayoutSize(c);
}
public void removeLayoutComponent(Component c) { }
}
}