BasicOptionPaneUI.java [plain text]
package javax.swing.plaf.basic;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Polygon;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.OptionPaneUI;
public class BasicOptionPaneUI extends OptionPaneUI
{
protected class ButtonActionListener implements ActionListener
{
protected int buttonIndex;
public ButtonActionListener(int buttonIndex)
{
this.buttonIndex = buttonIndex;
}
public void actionPerformed(ActionEvent e)
{
Object value = new Integer(JOptionPane.CLOSED_OPTION);
Object[] options = optionPane.getOptions();
if (options != null)
value = new Integer(buttonIndex);
else
{
String text = ((JButton) e.getSource()).getText();
if (text.equals(OK_STRING))
value = new Integer(JOptionPane.OK_OPTION);
if (text.equals(CANCEL_STRING))
value = new Integer(JOptionPane.CANCEL_OPTION);
if (text.equals(YES_STRING))
value = new Integer(JOptionPane.YES_OPTION);
if (text.equals(NO_STRING))
value = new Integer(JOptionPane.NO_OPTION);
}
optionPane.setValue(value);
resetInputValue();
Window owner = SwingUtilities.windowForComponent(optionPane);
if (owner instanceof JDialog)
((JDialog) owner).dispose();
JInternalFrame inf = (JInternalFrame) SwingUtilities.getAncestorOfClass(JInternalFrame.class,
optionPane);
if (inf != null)
{
try
{
inf.setClosed(true);
}
catch (PropertyVetoException pve)
{
}
}
}
}
protected class ButtonAreaLayout implements LayoutManager
{
protected boolean centersChildren = true;
protected int padding;
protected boolean syncAllWidths;
private transient int widthOfWidestButton;
private transient int tallestButton;
public ButtonAreaLayout(boolean syncAllWidths, int padding)
{
this.syncAllWidths = syncAllWidths;
this.padding = padding;
}
public void addLayoutComponent(String string, Component comp)
{
}
public boolean getCentersChildren()
{
return centersChildren;
}
public int getPadding()
{
return padding;
}
public boolean getSyncAllWidths()
{
return syncAllWidths;
}
public void layoutContainer(Container container)
{
Component[] buttonList = container.getComponents();
int x = container.getInsets().left;
if (getCentersChildren())
x += (int) ((double) (container.getSize().width) / 2
- (double) (buttonRowLength(container)) / 2);
for (int i = 0; i < buttonList.length; i++)
{
Dimension dims = buttonList[i].getPreferredSize();
if (getSizeButtonsToSameWidth())
{
buttonList[i].setBounds(x, 0, widthOfWidestButton, dims.height);
x += widthOfWidestButton + getPadding();
}
else
{
buttonList[i].setBounds(x, 0, dims.width, dims.height);
x += dims.width + getPadding();
}
}
}
private int buttonRowLength(Container c)
{
Component[] buttonList = c.getComponents();
int buttonLength = 0;
int widest = 0;
int tallest = 0;
for (int i = 0; i < buttonList.length; i++)
{
Dimension dims = buttonList[i].getPreferredSize();
buttonLength += dims.width + getPadding();
widest = Math.max(widest, dims.width);
tallest = Math.max(tallest, dims.height);
}
widthOfWidestButton = widest;
tallestButton = tallest;
int width;
if (getSyncAllWidths())
width = widest * buttonList.length
+ getPadding() * (buttonList.length - 1);
else
width = buttonLength;
Insets insets = c.getInsets();
width += insets.left + insets.right;
return width;
}
public Dimension minimumLayoutSize(Container c)
{
return preferredLayoutSize(c);
}
public Dimension preferredLayoutSize(Container c)
{
int w = buttonRowLength(c);
return new Dimension(w, tallestButton);
}
public void removeLayoutComponent(Component c)
{
}
public void setCentersChildren(boolean newValue)
{
centersChildren = newValue;
optionPane.invalidate();
}
public void setPadding(int newPadding)
{
padding = newPadding;
optionPane.invalidate();
}
public void setSyncAllWidths(boolean newValue)
{
syncAllWidths = newValue;
optionPane.invalidate();
}
}
public class PropertyChangeHandler implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent e)
{
if (e.getPropertyName().equals(JOptionPane.ICON_PROPERTY)
|| e.getPropertyName().equals(JOptionPane.MESSAGE_TYPE_PROPERTY))
addIcon(messageAreaContainer);
else if (e.getPropertyName().equals(JOptionPane.INITIAL_SELECTION_VALUE_PROPERTY))
resetSelectedValue();
else if (e.getPropertyName().equals(JOptionPane.INITIAL_VALUE_PROPERTY)
|| e.getPropertyName().equals(JOptionPane.OPTIONS_PROPERTY)
|| e.getPropertyName().equals(JOptionPane.OPTION_TYPE_PROPERTY))
{
Container newButtons = createButtonArea();
optionPane.remove(buttonContainer);
optionPane.add(newButtons);
buttonContainer = newButtons;
}
else if (e.getPropertyName().equals(JOptionPane.MESSAGE_PROPERTY)
|| e.getPropertyName().equals(JOptionPane.WANTS_INPUT_PROPERTY)
|| e.getPropertyName().equals(JOptionPane.SELECTION_VALUES_PROPERTY))
{
optionPane.removeAll();
messageAreaContainer = createMessageArea();
optionPane.add(messageAreaContainer);
optionPane.add(buttonContainer);
}
optionPane.invalidate();
optionPane.repaint();
}
}
protected boolean hasCustomComponents = false;
protected Component initialFocusComponent;
protected JComponent inputComponent;
public static int minimumHeight;
public static int minimumWidth;
protected Dimension minimumSize;
protected PropertyChangeListener propertyChangeListener;
protected JOptionPane optionPane;
private static int iconSize = 36;
private transient Color messageForeground;
private transient Border messageBorder;
private transient Border buttonBorder;
private static String OK_STRING = "OK";
private static String YES_STRING = "Yes";
private static String NO_STRING = "No";
private static String CANCEL_STRING = "Cancel";
private transient Container messageAreaContainer;
private transient Container buttonContainer;
private static class MessageIcon implements Icon
{
public int getIconWidth()
{
return iconSize;
}
public int getIconHeight()
{
return iconSize;
}
public void paintIcon(Component c, Graphics g, int x, int y)
{
}
}
private static MessageIcon errorIcon = new MessageIcon()
{
public void paintIcon(Component c, Graphics g, int x, int y)
{
Polygon oct = new Polygon(new int[] { 0, 0, 9, 27, 36, 36, 27, 9 },
new int[] { 9, 27, 36, 36, 27, 9, 0, 0 }, 8);
g.translate(x, y);
Color saved = g.getColor();
g.setColor(Color.RED);
g.fillPolygon(oct);
g.setColor(Color.BLACK);
g.drawRect(13, 16, 10, 4);
g.setColor(saved);
g.translate(-x, -y);
}
};
private static MessageIcon infoIcon = new MessageIcon()
{
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.translate(x, y);
Color saved = g.getColor();
g.setColor(Color.RED);
g.fillOval(0, 0, iconSize, iconSize);
g.setColor(Color.BLACK);
g.drawOval(16, 6, 4, 4);
Polygon bottomI = new Polygon(new int[] { 15, 15, 13, 13, 23, 23, 21, 21 },
new int[] { 12, 28, 28, 30, 30, 28, 28, 12 },
8);
g.drawPolygon(bottomI);
g.setColor(saved);
g.translate(-x, -y);
}
};
private static MessageIcon warningIcon = new MessageIcon()
{
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.translate(x, y);
Color saved = g.getColor();
g.setColor(Color.YELLOW);
Polygon triangle = new Polygon(new int[] { 0, 18, 36 },
new int[] { 36, 0, 36 }, 3);
g.fillPolygon(triangle);
g.setColor(Color.BLACK);
Polygon excl = new Polygon(new int[] { 15, 16, 20, 21 },
new int[] { 8, 26, 26, 8 }, 4);
g.drawPolygon(excl);
g.drawOval(16, 30, 4, 4);
g.setColor(saved);
g.translate(-x, -y);
}
};
private static MessageIcon questionIcon = new MessageIcon()
{
public void paintIcon(Component c, Graphics g, int x, int y)
{
g.translate(x, y);
Color saved = g.getColor();
g.setColor(Color.GREEN);
g.fillRect(0, 0, iconSize, iconSize);
g.setColor(Color.BLACK);
g.drawOval(11, 2, 16, 16);
g.drawOval(14, 5, 10, 10);
g.setColor(Color.GREEN);
g.fillRect(0, 10, iconSize, iconSize - 10);
g.setColor(Color.BLACK);
g.drawLine(11, 10, 14, 10);
g.drawLine(24, 10, 17, 22);
g.drawLine(27, 10, 20, 22);
g.drawLine(17, 22, 20, 22);
g.drawOval(17, 25, 3, 3);
g.setColor(saved);
g.translate(-x, -y);
}
};
public BasicOptionPaneUI()
{
}
protected void addButtonComponents(Container container, Object[] buttons,
int initialIndex)
{
if (buttons == null)
return;
for (int i = 0; i < buttons.length; i++)
{
if (buttons[i] != null)
{
Component toAdd;
if (buttons[i] instanceof Component)
toAdd = (Component) buttons[i];
else
{
if (buttons[i] instanceof Icon)
toAdd = new JButton((Icon) buttons[i]);
else
toAdd = new JButton(buttons[i].toString());
hasCustomComponents = true;
}
if (toAdd instanceof JButton)
((JButton) toAdd).addActionListener(createButtonActionListener(i));
if (i == initialIndex)
initialFocusComponent = toAdd;
container.add(toAdd);
}
}
selectInitialValue(optionPane);
}
protected void addIcon(Container top)
{
JLabel iconLabel = null;
Icon icon = getIcon();
if (icon != null)
{
iconLabel = new JLabel(icon);
top.add(iconLabel, BorderLayout.WEST);
}
}
private static GridBagConstraints createConstraints()
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = GridBagConstraints.REMAINDER;
constraints.gridy = GridBagConstraints.REMAINDER;
constraints.gridwidth = 0;
constraints.anchor = GridBagConstraints.LINE_START;
constraints.fill = GridBagConstraints.NONE;
constraints.insets = new Insets(0, 0, 3, 0);
return constraints;
}
protected void addMessageComponents(Container container,
GridBagConstraints cons, Object msg,
int maxll, boolean internallyCreated)
{
if (msg == null)
return;
hasCustomComponents = internallyCreated;
if (msg instanceof Object[])
{
Object[] arr = (Object[]) msg;
for (int i = 0; i < arr.length; i++)
addMessageComponents(container, cons, arr[i], maxll,
internallyCreated);
return;
}
else if (msg instanceof Component)
{
container.add((Component) msg, cons);
cons.gridy++;
}
else if (msg instanceof Icon)
{
container.add(new JLabel((Icon) msg), cons);
cons.gridy++;
}
else
{
if (msg.toString().length() > maxll)
{
Box tmp = new Box(BoxLayout.Y_AXIS);
burstStringInto(tmp, msg.toString(), maxll);
addMessageComponents(container, cons, tmp, maxll, true);
}
else
addMessageComponents(container, cons, new JLabel(msg.toString()),
maxll, true);
}
}
protected void burstStringInto(Container c, String d, int maxll)
{
if (d == null || c == null)
return;
JLabel label = new JLabel(d);
c.add(label);
}
public boolean containsCustomComponents(JOptionPane op)
{
return hasCustomComponents;
}
protected ActionListener createButtonActionListener(int buttonIndex)
{
return new ButtonActionListener(buttonIndex);
}
protected Container createButtonArea()
{
JPanel buttonPanel = new JPanel();
buttonPanel.setLayout(createLayoutManager());
addButtonComponents(buttonPanel, getButtons(), getInitialValueIndex());
return buttonPanel;
}
protected LayoutManager createLayoutManager()
{
return new ButtonAreaLayout(getSizeButtonsToSameWidth(), 6);
}
protected Container createMessageArea()
{
JPanel messageArea = new JPanel();
messageArea.setLayout(new BorderLayout());
addIcon(messageArea);
JPanel rightSide = new JPanel()
{
public Dimension getPreferredSize()
{
int w = Math.max(optionPane.getSize().width, minimumWidth);
Insets i = optionPane.getInsets();
Dimension orig = super.getPreferredSize();
Dimension value = new Dimension(w - i.left - i.right - iconSize,
orig.height);
return value;
}
};
rightSide.setLayout(new GridBagLayout());
GridBagConstraints con = createConstraints();
addMessageComponents(rightSide, con, getMessage(),
getMaxCharactersPerLineCount(), false);
if (optionPane.getWantsInput())
{
Object[] selection = optionPane.getSelectionValues();
if (selection == null)
inputComponent = null;
else
inputComponent = new JList(selection);
if (inputComponent != null)
{
addMessageComponents(rightSide, con, inputComponent,
getMaxCharactersPerLineCount(), true);
resetSelectedValue();
selectInitialValue(optionPane);
}
}
messageArea.add(rightSide, BorderLayout.EAST);
return messageArea;
}
protected PropertyChangeListener createPropertyChangeListener()
{
return new PropertyChangeHandler();
}
protected Container createSeparator()
{
return null;
}
public static ComponentUI createUI(JComponent x)
{
return new BasicOptionPaneUI();
}
protected Object[] getButtons()
{
if (optionPane.getOptions() != null)
return optionPane.getOptions();
switch (optionPane.getOptionType())
{
case JOptionPane.YES_NO_OPTION:
return new Object[] { YES_STRING, NO_STRING };
case JOptionPane.YES_NO_CANCEL_OPTION:
return new Object[] { YES_STRING, NO_STRING, CANCEL_STRING };
case JOptionPane.OK_CANCEL_OPTION:
case JOptionPane.DEFAULT_OPTION:
return new Object[] { OK_STRING, CANCEL_STRING };
}
return null;
}
protected Icon getIcon()
{
if (optionPane.getIcon() != null)
return optionPane.getIcon();
else
return getIconForType(optionPane.getMessageType());
}
protected Icon getIconForType(int messageType)
{
Icon tmp = null;
switch (messageType)
{
case JOptionPane.ERROR_MESSAGE:
tmp = errorIcon;
break;
case JOptionPane.INFORMATION_MESSAGE:
tmp = infoIcon;
break;
case JOptionPane.WARNING_MESSAGE:
tmp = warningIcon;
break;
case JOptionPane.QUESTION_MESSAGE:
tmp = questionIcon;
break;
}
return tmp;
}
protected int getInitialValueIndex()
{
Object[] buttons = getButtons();
if (buttons == null)
return -1;
Object select = optionPane.getInitialValue();
for (int i = 0; i < buttons.length; i++)
{
if (select == buttons[i])
return i;
}
return 0;
}
protected int getMaxCharactersPerLineCount()
{
return optionPane.getMaxCharactersPerLineCount();
}
public Dimension getMaximumSize(JComponent c)
{
return getPreferredSize(c);
}
protected Object getMessage()
{
return optionPane.getMessage();
}
public Dimension getMinimumOptionPaneSize()
{
return minimumSize;
}
public Dimension getMinimumSize(JComponent c)
{
return getPreferredSize(c);
}
public Dimension getPreferredSize(JComponent c)
{
Dimension d = optionPane.getLayout().preferredLayoutSize(optionPane);
Dimension d2 = getMinimumOptionPaneSize();
int w = Math.max(d.width, d2.width);
int h = Math.max(d.height, d2.height);
return new Dimension(w, h);
}
protected boolean getSizeButtonsToSameWidth()
{
return true;
}
protected void installComponents()
{
hasCustomComponents = false;
Container msg = createMessageArea();
if (msg != null)
{
((JComponent) msg).setBorder(messageBorder);
msg.setForeground(messageForeground);
messageAreaContainer = msg;
optionPane.add(msg);
}
Container sep = createSeparator();
if (sep != null)
optionPane.add(sep);
Container button = createButtonArea();
if (button != null)
{
((JComponent) button).setBorder(buttonBorder);
buttonContainer = button;
optionPane.add(button);
}
optionPane.invalidate();
}
protected void installDefaults()
{
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
optionPane.setFont(defaults.getFont("OptionPane.font"));
optionPane.setBackground(defaults.getColor("OptionPane.background"));
optionPane.setForeground(defaults.getColor("OptionPane.foreground"));
optionPane.setBorder(defaults.getBorder("OptionPane.border"));
messageBorder = defaults.getBorder("OptionPane.messageAreaBorder");
messageForeground = defaults.getColor("OptionPane.messageForeground");
buttonBorder = defaults.getBorder("OptionPane.buttonAreaBorder");
minimumSize = defaults.getDimension("OptionPane.minimumSize");
minimumWidth = minimumSize.width;
minimumHeight = minimumSize.height;
}
protected void installKeyboardActions()
{
}
protected void installListeners()
{
propertyChangeListener = createPropertyChangeListener();
optionPane.addPropertyChangeListener(propertyChangeListener);
}
public void installUI(JComponent c)
{
if (c instanceof JOptionPane)
{
optionPane = (JOptionPane) c;
installDefaults();
installComponents();
installListeners();
installKeyboardActions();
}
}
protected void resetInputValue()
{
if (optionPane.getWantsInput() && inputComponent != null)
{
Object output = null;
if (inputComponent instanceof JTextField)
output = ((JTextField) inputComponent).getText();
else if (inputComponent instanceof JComboBox)
output = ((JComboBox) inputComponent).getSelectedItem();
else if (inputComponent instanceof JList)
output = ((JList) inputComponent).getSelectedValue();
if (output != null)
optionPane.setInputValue(output);
}
}
public void selectInitialValue(JOptionPane op)
{
if (inputComponent != null)
{
inputComponent.requestFocus();
return;
}
if (initialFocusComponent != null)
initialFocusComponent.requestFocus();
}
private void resetSelectedValue()
{
if (inputComponent != null)
{
Object init = optionPane.getInitialSelectionValue();
if (init == null)
return;
if (inputComponent instanceof JTextField)
((JTextField) inputComponent).setText((String) init);
else if (inputComponent instanceof JComboBox)
((JComboBox) inputComponent).setSelectedItem(init);
else if (inputComponent instanceof JList)
{
}
}
}
protected void uninstallComponents()
{
optionPane.removeAll();
buttonContainer = null;
messageAreaContainer = null;
}
protected void uninstallDefaults()
{
optionPane.setFont(null);
optionPane.setForeground(null);
optionPane.setBackground(null);
minimumSize = null;
messageBorder = null;
buttonBorder = null;
messageForeground = null;
}
protected void uninstallKeyboardActions()
{
}
protected void uninstallListeners()
{
optionPane.removePropertyChangeListener(propertyChangeListener);
propertyChangeListener = null;
}
public void uninstallUI(JComponent c)
{
uninstallKeyboardActions();
uninstallListeners();
uninstallComponents();
uninstallDefaults();
optionPane = null;
}
}