1455 lines · 54.9 KB · Java
RawDownload
/* * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation.  Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package javax.swing.plaf.basic; import sun.swing.DefaultLookup;import sun.swing.UIAction;import javax.swing.border.Border;import javax.swing.border.EmptyBorder;import javax.swing.*;import javax.swing.event.*;import javax.swing.plaf.ActionMapUIResource;import javax.swing.plaf.ComponentUI;import javax.swing.plaf.OptionPaneUI;import java.awt.*;import java.awt.event.*;import java.beans.PropertyChangeEvent;import java.beans.PropertyChangeListener;import java.util.Locale;import java.security.AccessController; import sun.security.action.GetPropertyAction;  /** * Provides the basic look and feel for a <code>JOptionPane</code>. * <code>BasicMessagePaneUI</code> provides a means to place an icon, * message and buttons into a <code>Container</code>. * Generally, the layout will look like:<p> * <pre> *        ------------------ *        | i | message    | *        | c | message    | *        | o | message    | *        | n | message    | *        ------------------ *        |     buttons    | *        |________________| * </pre> * icon is an instance of <code>Icon</code> that is wrapped inside a * <code>JLabel</code>.  The message is an opaque object and is tested * for the following: if the message is a <code>Component</code> it is * added to the <code>Container</code>, if it is an <code>Icon</code> * it is wrapped inside a <code>JLabel</code> and added to the * <code>Container</code> otherwise it is wrapped inside a <code>JLabel</code>. * <p> * The above layout is used when the option pane's * <code>ComponentOrientation</code> property is horizontal, left-to-right. * The layout will be adjusted appropriately for other orientations. * <p> * The <code>Container</code>, message, icon, and buttons are all * determined from abstract methods. * * @author James Gosling * @author Scott Violet * @author Amy Fowler */public class BasicOptionPaneUI extends OptionPaneUI {     public static final int MinimumWidth = 262;    public static final int MinimumHeight = 90;     private static String newline;     /**     * <code>JOptionPane</code> that the receiver is providing the     * look and feel for.     */    protected JOptionPane         optionPane;     protected Dimension minimumSize;     /** JComponent provide for input if optionPane.getWantsInput() returns     * true. */    protected JComponent          inputComponent;     /** Component to receive focus when messaged with selectInitialValue. */    protected Component           initialFocusComponent;     /** This is set to true in validateComponent if a Component is contained     * in either the message or the buttons. */    protected boolean             hasCustomComponents;     protected PropertyChangeListener propertyChangeListener;     private Handler handler;      static {        newline = java.security.AccessController.doPrivileged(                                new GetPropertyAction("line.separator"));        if (newline == null) {            newline = "\n";        }    }     static void loadActionMap(LazyActionMap map) {        map.put(new Actions(Actions.CLOSE));        BasicLookAndFeel.installAudioActionMap(map);    }       /**      * Creates a new BasicOptionPaneUI instance.      */    public static ComponentUI createUI(JComponent x) {        return new BasicOptionPaneUI();    }     /**      * Installs the receiver as the L&F for the passed in      * <code>JOptionPane</code>.      */    public void installUI(JComponent c) {        optionPane = (JOptionPane)c;        installDefaults();        optionPane.setLayout(createLayoutManager());        installComponents();        installListeners();        installKeyboardActions();    }     /**      * Removes the receiver from the L&F controller of the passed in split      * pane.      */    public void uninstallUI(JComponent c) {        uninstallComponents();        optionPane.setLayout(null);        uninstallKeyboardActions();        uninstallListeners();        uninstallDefaults();        optionPane = null;    }     protected void installDefaults() {        LookAndFeel.installColorsAndFont(optionPane, "OptionPane.background",                                         "OptionPane.foreground", "OptionPane.font");        LookAndFeel.installBorder(optionPane, "OptionPane.border");        minimumSize = UIManager.getDimension("OptionPane.minimumSize");        LookAndFeel.installProperty(optionPane, "opaque", Boolean.TRUE);    }     protected void uninstallDefaults() {        LookAndFeel.uninstallBorder(optionPane);    }     protected void installComponents() {        optionPane.add(createMessageArea());         Container separator = createSeparator();        if (separator != null) {            optionPane.add(separator);        }        optionPane.add(createButtonArea());        optionPane.applyComponentOrientation(optionPane.getComponentOrientation());    }     protected void uninstallComponents() {        hasCustomComponents = false;        inputComponent = null;        initialFocusComponent = null;        optionPane.removeAll();    }     protected LayoutManager createLayoutManager() {        return new BoxLayout(optionPane, BoxLayout.Y_AXIS);    }     protected void installListeners() {        if ((propertyChangeListener = createPropertyChangeListener()) != null) {            optionPane.addPropertyChangeListener(propertyChangeListener);        }    }     protected void uninstallListeners() {        if (propertyChangeListener != null) {            optionPane.removePropertyChangeListener(propertyChangeListener);            propertyChangeListener = null;        }        handler = null;    }     protected PropertyChangeListener createPropertyChangeListener() {        return getHandler();    }     private Handler getHandler() {        if (handler == null) {            handler = new Handler();        }        return handler;    }     protected void installKeyboardActions() {        InputMap map = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);         SwingUtilities.replaceUIInputMap(optionPane, JComponent.                                       WHEN_IN_FOCUSED_WINDOW, map);         LazyActionMap.installLazyActionMap(optionPane, BasicOptionPaneUI.class,                                           "OptionPane.actionMap");    }     protected void uninstallKeyboardActions() {        SwingUtilities.replaceUIInputMap(optionPane, JComponent.                                       WHEN_IN_FOCUSED_WINDOW, null);        SwingUtilities.replaceUIActionMap(optionPane, null);    }     InputMap getInputMap(int condition) {        if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {            Object[] bindings = (Object[])DefaultLookup.get(                             optionPane, this, "OptionPane.windowBindings");            if (bindings != null) {                return LookAndFeel.makeComponentInputMap(optionPane, bindings);            }        }        return null;    }     /**     * Returns the minimum size the option pane should be. Primarily     * provided for subclassers wishing to offer a different minimum size.     */    public Dimension getMinimumOptionPaneSize() {        if (minimumSize == null) {            return new Dimension(MinimumWidth, MinimumHeight);        }        return new Dimension(minimumSize.width,                             minimumSize.height);    }     /**     * If <code>c</code> is the <code>JOptionPane</code> the receiver     * is contained in, the preferred     * size that is returned is the maximum of the preferred size of     * the <code>LayoutManager</code> for the <code>JOptionPane</code>, and     * <code>getMinimumOptionPaneSize</code>.     */    public Dimension getPreferredSize(JComponent c) {        if (c == optionPane) {            Dimension            ourMin = getMinimumOptionPaneSize();            LayoutManager        lm = c.getLayout();             if (lm != null) {                Dimension         lmSize = lm.preferredLayoutSize(c);                 if (ourMin != null)                    return new Dimension                        (Math.max(lmSize.width, ourMin.width),                         Math.max(lmSize.height, ourMin.height));                return lmSize;            }            return ourMin;        }        return null;    }     /**     * Messaged from installComponents to create a Container containing the     * body of the message. The icon is the created by calling     * <code>addIcon</code>.     */    protected Container createMessageArea() {        JPanel top = new JPanel();        Border topBorder = (Border)DefaultLookup.get(optionPane, this,                                             "OptionPane.messageAreaBorder");        if (topBorder != null) {            top.setBorder(topBorder);        }        top.setLayout(new BorderLayout());         /* Fill the body. */        Container          body = new JPanel(new GridBagLayout());        Container          realBody = new JPanel(new BorderLayout());         body.setName("OptionPane.body");        realBody.setName("OptionPane.realBody");         if (getIcon() != null) {            JPanel sep = new JPanel();            sep.setName("OptionPane.separator");            sep.setPreferredSize(new Dimension(15, 1));            realBody.add(sep, BorderLayout.BEFORE_LINE_BEGINS);        }        realBody.add(body, BorderLayout.CENTER);         GridBagConstraints cons = new GridBagConstraints();        cons.gridx = cons.gridy = 0;        cons.gridwidth = GridBagConstraints.REMAINDER;        cons.gridheight = 1;        cons.anchor = DefaultLookup.getInt(optionPane, this,                      "OptionPane.messageAnchor", GridBagConstraints.CENTER);        cons.insets = new Insets(0,0,3,0);         addMessageComponents(body, cons, getMessage(),                          getMaxCharactersPerLineCount(), false);        top.add(realBody, BorderLayout.CENTER);         addIcon(top);        return top;    }     /**     * Creates the appropriate object to represent <code>msg</code> and     * places it into <code>container</code>. If <code>msg</code> is an     * instance of Component, it is added directly, if it is an Icon,     * a JLabel is created to represent it, otherwise a JLabel is     * created for the string, if <code>d</code> is an Object[], this     * method will be recursively invoked for the children.     * <code>internallyCreated</code> is true if Objc is an instance     * of Component and was created internally by this method (this is     * used to correctly set hasCustomComponents only if !internallyCreated).     */    protected void addMessageComponents(Container container,                                     GridBagConstraints cons,                                     Object msg, int maxll,                                     boolean internallyCreated) {        if (msg == null) {            return;        }        if (msg instanceof Component) {            // To workaround problem where Gridbad will set child            // to its minimum size if its preferred size will not fit            // within allocated cells            if (msg instanceof JScrollPane || msg instanceof JPanel) {                cons.fill = GridBagConstraints.BOTH;                cons.weighty = 1;            } else {                cons.fill = GridBagConstraints.HORIZONTAL;            }            cons.weightx = 1;             container.add((Component) msg, cons);            cons.weightx = 0;            cons.weighty = 0;            cons.fill = GridBagConstraints.NONE;            cons.gridy++;            if (!internallyCreated) {                hasCustomComponents = true;            }         } else if (msg instanceof Object[]) {            Object [] msgs = (Object[]) msg;            for (Object o : msgs) {                addMessageComponents(container, cons, o, maxll, false);            }         } else if (msg instanceof Icon) {            JLabel label = new JLabel( (Icon)msg, SwingConstants.CENTER );            configureMessageLabel(label);            addMessageComponents(container, cons, label, maxll, true);         } else {            String s = msg.toString();            int len = s.length();            if (len <= 0) {                return;            }            int nl;            int nll = 0;             if ((nl = s.indexOf(newline)) >= 0) {                nll = newline.length();            } else if ((nl = s.indexOf("\r\n")) >= 0) {                nll = 2;            } else if ((nl = s.indexOf('\n')) >= 0) {                nll = 1;            }            if (nl >= 0) {                // break up newlines                if (nl == 0) {                    JPanel breakPanel = new JPanel() {                        public Dimension getPreferredSize() {                            Font       f = getFont();                             if (f != null) {                                return new Dimension(1, f.getSize() + 2);                            }                            return new Dimension(0, 0);                        }                    };                    breakPanel.setName("OptionPane.break");                    addMessageComponents(container, cons, breakPanel, maxll,                                         true);                } else {                    addMessageComponents(container, cons, s.substring(0, nl),                                      maxll, false);                }                addMessageComponents(container, cons, s.substring(nl + nll), maxll,                                  false);             } else if (len > maxll) {                Container c = Box.createVerticalBox();                c.setName("OptionPane.verticalBox");                burstStringInto(c, s, maxll);                addMessageComponents(container, cons, c, maxll, true );             } else {                JLabel label;                label = new JLabel( s, JLabel.LEADING );                label.setName("OptionPane.label");                configureMessageLabel(label);                addMessageComponents(container, cons, label, maxll, true);            }        }    }     /**     * Returns the message to display from the JOptionPane the receiver is     * providing the look and feel for.     */    protected Object getMessage() {        inputComponent = null;        if (optionPane != null) {            if (optionPane.getWantsInput()) {                /* Create a user component to capture the input. If the                   selectionValues are non null the component and there                   are < 20 values it'll be a combobox, if non null and                   >= 20, it'll be a list, otherwise it'll be a textfield. */                Object             message = optionPane.getMessage();                Object[]           sValues = optionPane.getSelectionValues();                Object             inputValue = optionPane                                           .getInitialSelectionValue();                JComponent         toAdd;                 if (sValues != null) {                    if (sValues.length < 20) {                        JComboBox            cBox = new JComboBox();                         cBox.setName("OptionPane.comboBox");                        for(int counter = 0, maxCounter = sValues.length;                            counter < maxCounter; counter++) {                            cBox.addItem(sValues[counter]);                        }                        if (inputValue != null) {                            cBox.setSelectedItem(inputValue);                        }                        inputComponent = cBox;                        toAdd = cBox;                     } else {                        JList                list = new JList(sValues);                        JScrollPane          sp = new JScrollPane(list);                         sp.setName("OptionPane.scrollPane");                        list.setName("OptionPane.list");                        list.setVisibleRowCount(10);                        list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);                        if(inputValue != null)                            list.setSelectedValue(inputValue, true);                        list.addMouseListener(getHandler());                        toAdd = sp;                        inputComponent = list;                    }                 } else {                    MultiplexingTextField   tf = new MultiplexingTextField(20);                     tf.setName("OptionPane.textField");                    tf.setKeyStrokes(new KeyStroke[] {                                     KeyStroke.getKeyStroke("ENTER") } );                    if (inputValue != null) {                        String inputString = inputValue.toString();                        tf.setText(inputString);                        tf.setSelectionStart(0);                        tf.setSelectionEnd(inputString.length());                    }                    tf.addActionListener(getHandler());                    toAdd = inputComponent = tf;                }                 Object[]           newMessage;                 if (message == null) {                    newMessage = new Object[1];

Lines 1–500 of 1455.