< prev index next >

src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java

Print this page




  28 import sun.swing.DefaultLookup;
  29 import sun.swing.UIAction;
  30 import javax.swing.border.Border;
  31 import javax.swing.border.EmptyBorder;
  32 import javax.swing.*;
  33 import javax.swing.event.*;
  34 import javax.swing.plaf.ActionMapUIResource;
  35 import javax.swing.plaf.ComponentUI;
  36 import javax.swing.plaf.OptionPaneUI;
  37 import java.awt.*;
  38 import java.awt.event.*;
  39 import java.beans.PropertyChangeEvent;
  40 import java.beans.PropertyChangeListener;
  41 import java.util.Locale;
  42 import java.security.AccessController;
  43 
  44 import sun.security.action.GetPropertyAction;
  45 
  46 
  47 /**
  48  * Provides the basic look and feel for a <code>JOptionPane</code>.
  49  * <code>BasicMessagePaneUI</code> provides a means to place an icon,
  50  * message and buttons into a <code>Container</code>.
  51  * Generally, the layout will look like:
  52  * <pre>
  53  *        ------------------
  54  *        | i | message    |
  55  *        | c | message    |
  56  *        | o | message    |
  57  *        | n | message    |
  58  *        ------------------
  59  *        |     buttons    |
  60  *        |________________|
  61  * </pre>
  62  * icon is an instance of <code>Icon</code> that is wrapped inside a
  63  * <code>JLabel</code>.  The message is an opaque object and is tested
  64  * for the following: if the message is a <code>Component</code> it is
  65  * added to the <code>Container</code>, if it is an <code>Icon</code>
  66  * it is wrapped inside a <code>JLabel</code> and added to the
  67  * <code>Container</code> otherwise it is wrapped inside a <code>JLabel</code>.
  68  * <p>
  69  * The above layout is used when the option pane's
  70  * <code>ComponentOrientation</code> property is horizontal, left-to-right.
  71  * The layout will be adjusted appropriately for other orientations.
  72  * <p>
  73  * The <code>Container</code>, message, icon, and buttons are all
  74  * determined from abstract methods.
  75  *
  76  * @author James Gosling
  77  * @author Scott Violet
  78  * @author Amy Fowler
  79  */
  80 public class BasicOptionPaneUI extends OptionPaneUI {
  81 
  82     /**
  83      * The mininum width of {@code JOptionPane}.
  84      */
  85     public static final int MinimumWidth = 262;
  86     /**
  87      * The mininum height of {@code JOptionPane}.
  88      */
  89     public static final int MinimumHeight = 90;
  90 
  91     private static String newline;
  92 
  93     /**


 128     }
 129 
 130     static void loadActionMap(LazyActionMap map) {
 131         map.put(new Actions(Actions.CLOSE));
 132         BasicLookAndFeel.installAudioActionMap(map);
 133     }
 134 
 135 
 136 
 137     /**
 138      * Creates a new {@code BasicOptionPaneUI} instance.
 139      * @param x the component
 140      * @return a new {@code BasicOptionPaneUI} instance
 141      */
 142     public static ComponentUI createUI(JComponent x) {
 143         return new BasicOptionPaneUI();
 144     }
 145 
 146     /**
 147       * Installs the receiver as the L&amp;F for the passed in
 148       * <code>JOptionPane</code>.
 149       */
 150     public void installUI(JComponent c) {
 151         optionPane = (JOptionPane)c;
 152         installDefaults();
 153         optionPane.setLayout(createLayoutManager());
 154         installComponents();
 155         installListeners();
 156         installKeyboardActions();
 157     }
 158 
 159     /**
 160       * Removes the receiver from the L&amp;F controller of the passed in split
 161       * pane.
 162       */
 163     public void uninstallUI(JComponent c) {
 164         uninstallComponents();
 165         optionPane.setLayout(null);
 166         uninstallKeyboardActions();
 167         uninstallListeners();
 168         uninstallDefaults();


 287             }
 288         }
 289         return null;
 290     }
 291 
 292     /**
 293      * Returns the minimum size the option pane should be. Primarily
 294      * provided for subclassers wishing to offer a different minimum size.
 295      *
 296      * @return the minimum size of the option pane
 297      */
 298     public Dimension getMinimumOptionPaneSize() {
 299         if (minimumSize == null) {
 300             return new Dimension(MinimumWidth, MinimumHeight);
 301         }
 302         return new Dimension(minimumSize.width,
 303                              minimumSize.height);
 304     }
 305 
 306     /**
 307      * If <code>c</code> is the <code>JOptionPane</code> the receiver
 308      * is contained in, the preferred
 309      * size that is returned is the maximum of the preferred size of
 310      * the <code>LayoutManager</code> for the <code>JOptionPane</code>, and
 311      * <code>getMinimumOptionPaneSize</code>.
 312      */
 313     public Dimension getPreferredSize(JComponent c) {
 314         if (c == optionPane) {
 315             Dimension            ourMin = getMinimumOptionPaneSize();
 316             LayoutManager        lm = c.getLayout();
 317 
 318             if (lm != null) {
 319                 Dimension         lmSize = lm.preferredLayoutSize(c);
 320 
 321                 if (ourMin != null)
 322                     return new Dimension
 323                         (Math.max(lmSize.width, ourMin.width),
 324                          Math.max(lmSize.height, ourMin.height));
 325                 return lmSize;
 326             }
 327             return ourMin;
 328         }
 329         return null;
 330     }
 331 


 816                 }
 817             }
 818         }
 819     }
 820 
 821     /**
 822      * Constructs a new instance of a {@code ButtonActionListener}.
 823      *
 824      * @param buttonIndex an index of the button
 825      * @return a new instance of a {@code ButtonActionListener}
 826      */
 827     protected ActionListener createButtonActionListener(int buttonIndex) {
 828         return new ButtonActionListener(buttonIndex);
 829     }
 830 
 831     /**
 832      * Returns the buttons to display from the {@code JOptionPane} the receiver is
 833      * providing the look and feel for. If the {@code JOptionPane} has options
 834      * set, they will be provided, otherwise if the optionType is
 835      * {@code YES_NO_OPTION}, {@code yesNoOptions} is returned, if the type is
 836      * {@code YES_NO_CANCEL_OPTION} {@code yesNoCancelOptions} is returned, otherwise
 837      * {@code defaultButtons} are returned.
 838      *
 839      * @return the buttons to display from the JOptionPane
 840      */
 841     protected Object[] getButtons() {
 842         if (optionPane != null) {
 843             Object[] suppliedOptions = optionPane.getOptions();
 844 
 845             if (suppliedOptions == null) {
 846                 Object[] defaultOptions;
 847                 int type = optionPane.getOptionType();
 848                 Locale l = optionPane.getLocale();
 849                 int minimumWidth =
 850                     DefaultLookup.getInt(optionPane, this,
 851                                         "OptionPane.buttonMinimumWidth",-1);
 852                 if (type == JOptionPane.YES_NO_OPTION) {
 853                     defaultOptions = new ButtonFactory[2];
 854                     defaultOptions[0] = new ButtonFactory(
 855                         UIManager.getString("OptionPane.yesButtonText", l),
 856                         getMnemonic("OptionPane.yesButtonMnemonic", l),


 986 
 987             if (initialFocusComponent instanceof JButton) {
 988                 JRootPane root = SwingUtilities.getRootPane(initialFocusComponent);
 989                 if (root != null) {
 990                     root.setDefaultButton((JButton)initialFocusComponent);
 991                 }
 992             }
 993         }
 994     }
 995 
 996     /**
 997      * Returns true if in the last call to validateComponent the message
 998      * or buttons contained a subclass of Component.
 999      */
1000     public boolean containsCustomComponents(JOptionPane op) {
1001         return hasCustomComponents;
1002     }
1003 
1004 
1005     /**
1006      * <code>ButtonAreaLayout</code> behaves in a similar manner to
1007      * <code>FlowLayout</code>. It lays out all components from left to
1008      * right. If <code>syncAllWidths</code> is true, the widths of each
1009      * component will be set to the largest preferred size width.
1010      *
1011      * This class should be treated as a &quot;protected&quot; inner class.
1012      * Instantiate it only within subclasses of {@code BasicOptionPaneUI}.
1013      */
1014     public static class ButtonAreaLayout implements LayoutManager {
1015         /**
1016          * The value represents if the width of children should be synchronized.
1017          */
1018         protected boolean           syncAllWidths;
1019         /**
1020          * The padding value.
1021          */
1022         protected int               padding;
1023         /** If true, children are lumped together in parent. */
1024         protected boolean           centersChildren;
1025         private int orientation;
1026         private boolean reverseButtons;
1027         /**
1028          * Indicates whether or not centersChildren should be used vs


1241                     }
1242                 }
1243             }
1244             return new Dimension(0, 0);
1245         }
1246 
1247         public Dimension preferredLayoutSize(Container c) {
1248             return minimumLayoutSize(c);
1249         }
1250 
1251         public void removeLayoutComponent(Component c) { }
1252     }
1253 
1254 
1255     /**
1256      * This class should be treated as a &quot;protected&quot; inner class.
1257      * Instantiate it only within subclasses of {@code BasicOptionPaneUI}.
1258      */
1259     public class PropertyChangeHandler implements PropertyChangeListener {
1260         /**
1261          * If the source of the PropertyChangeEvent <code>e</code> equals the
1262          * optionPane and is one of the ICON_PROPERTY, MESSAGE_PROPERTY,
1263          * OPTIONS_PROPERTY or INITIAL_VALUE_PROPERTY,
1264          * validateComponent is invoked.
1265          */
1266         public void propertyChange(PropertyChangeEvent e) {
1267             getHandler().propertyChange(e);
1268         }
1269     }
1270 
1271     /**
1272      * Configures any necessary colors/fonts for the specified label
1273      * used representing the message.
1274      */
1275     private void configureMessageLabel(JLabel label) {
1276         Color color = (Color)DefaultLookup.get(optionPane, this,
1277                                                "OptionPane.messageForeground");
1278         if (color != null) {
1279             label.setForeground(color);
1280         }
1281         Font messageFont = (Font)DefaultLookup.get(optionPane, this,


1509 
1510             if (processed && condition != JComponent.WHEN_IN_FOCUSED_WINDOW) {
1511                 for (int counter = strokes.length - 1; counter >= 0;
1512                          counter--) {
1513                     if (strokes[counter].equals(ks)) {
1514                         // Returning false will allow further processing
1515                         // of the bindings, eg our parent Containers will get a
1516                         // crack at them.
1517                         return false;
1518                     }
1519                 }
1520             }
1521             return processed;
1522         }
1523     }
1524 
1525 
1526 
1527     /**
1528      * Registered in the ActionMap. Sets the value of the option pane
1529      * to <code>JOptionPane.CLOSED_OPTION</code>.
1530      */
1531     private static class Actions extends UIAction {
1532         private static final String CLOSE = "close";
1533 
1534         Actions(String key) {
1535             super(key);
1536         }
1537 
1538         public void actionPerformed(ActionEvent e) {
1539             if (getName() == CLOSE) {
1540                 JOptionPane optionPane = (JOptionPane)e.getSource();
1541 
1542                 optionPane.setValue(Integer.valueOf(JOptionPane.CLOSED_OPTION));
1543             }
1544         }
1545     }
1546 
1547 
1548     /**
1549      * This class is used to create the default buttons. This indirection is




  28 import sun.swing.DefaultLookup;
  29 import sun.swing.UIAction;
  30 import javax.swing.border.Border;
  31 import javax.swing.border.EmptyBorder;
  32 import javax.swing.*;
  33 import javax.swing.event.*;
  34 import javax.swing.plaf.ActionMapUIResource;
  35 import javax.swing.plaf.ComponentUI;
  36 import javax.swing.plaf.OptionPaneUI;
  37 import java.awt.*;
  38 import java.awt.event.*;
  39 import java.beans.PropertyChangeEvent;
  40 import java.beans.PropertyChangeListener;
  41 import java.util.Locale;
  42 import java.security.AccessController;
  43 
  44 import sun.security.action.GetPropertyAction;
  45 
  46 
  47 /**
  48  * Provides the basic look and feel for a {@code JOptionPane}.
  49  * {@code BasicMessagePaneUI} provides a means to place an icon,
  50  * message and buttons into a {@code Container}.
  51  * Generally, the layout will look like:
  52  * <pre>
  53  *        ------------------
  54  *        | i | message    |
  55  *        | c | message    |
  56  *        | o | message    |
  57  *        | n | message    |
  58  *        ------------------
  59  *        |     buttons    |
  60  *        |________________|
  61  * </pre>
  62  * icon is an instance of {@code Icon} that is wrapped inside a
  63  * {@code JLabel}.  The message is an opaque object and is tested
  64  * for the following: if the message is a {@code Component} it is
  65  * added to the {@code Container}, if it is an {@code Icon}
  66  * it is wrapped inside a {@code JLabel} and added to the
  67  * {@code Container} otherwise it is wrapped inside a {@code JLabel}.
  68  * <p>
  69  * The above layout is used when the option pane's
  70  * {@code ComponentOrientation} property is horizontal, left-to-right.
  71  * The layout will be adjusted appropriately for other orientations.
  72  * <p>
  73  * The {@code Container}, message, icon, and buttons are all
  74  * determined from abstract methods.
  75  *
  76  * @author James Gosling
  77  * @author Scott Violet
  78  * @author Amy Fowler
  79  */
  80 public class BasicOptionPaneUI extends OptionPaneUI {
  81 
  82     /**
  83      * The mininum width of {@code JOptionPane}.
  84      */
  85     public static final int MinimumWidth = 262;
  86     /**
  87      * The mininum height of {@code JOptionPane}.
  88      */
  89     public static final int MinimumHeight = 90;
  90 
  91     private static String newline;
  92 
  93     /**


 128     }
 129 
 130     static void loadActionMap(LazyActionMap map) {
 131         map.put(new Actions(Actions.CLOSE));
 132         BasicLookAndFeel.installAudioActionMap(map);
 133     }
 134 
 135 
 136 
 137     /**
 138      * Creates a new {@code BasicOptionPaneUI} instance.
 139      * @param x the component
 140      * @return a new {@code BasicOptionPaneUI} instance
 141      */
 142     public static ComponentUI createUI(JComponent x) {
 143         return new BasicOptionPaneUI();
 144     }
 145 
 146     /**
 147       * Installs the receiver as the L&amp;F for the passed in
 148       * {@code JOptionPane}.
 149       */
 150     public void installUI(JComponent c) {
 151         optionPane = (JOptionPane)c;
 152         installDefaults();
 153         optionPane.setLayout(createLayoutManager());
 154         installComponents();
 155         installListeners();
 156         installKeyboardActions();
 157     }
 158 
 159     /**
 160       * Removes the receiver from the L&amp;F controller of the passed in split
 161       * pane.
 162       */
 163     public void uninstallUI(JComponent c) {
 164         uninstallComponents();
 165         optionPane.setLayout(null);
 166         uninstallKeyboardActions();
 167         uninstallListeners();
 168         uninstallDefaults();


 287             }
 288         }
 289         return null;
 290     }
 291 
 292     /**
 293      * Returns the minimum size the option pane should be. Primarily
 294      * provided for subclassers wishing to offer a different minimum size.
 295      *
 296      * @return the minimum size of the option pane
 297      */
 298     public Dimension getMinimumOptionPaneSize() {
 299         if (minimumSize == null) {
 300             return new Dimension(MinimumWidth, MinimumHeight);
 301         }
 302         return new Dimension(minimumSize.width,
 303                              minimumSize.height);
 304     }
 305 
 306     /**
 307      * If {@code c} is the {@code JOptionPane} the receiver
 308      * is contained in, the preferred
 309      * size that is returned is the maximum of the preferred size of
 310      * the {@code LayoutManager} for the {@code JOptionPane}, and
 311      * {@code getMinimumOptionPaneSize}.
 312      */
 313     public Dimension getPreferredSize(JComponent c) {
 314         if (c == optionPane) {
 315             Dimension            ourMin = getMinimumOptionPaneSize();
 316             LayoutManager        lm = c.getLayout();
 317 
 318             if (lm != null) {
 319                 Dimension         lmSize = lm.preferredLayoutSize(c);
 320 
 321                 if (ourMin != null)
 322                     return new Dimension
 323                         (Math.max(lmSize.width, ourMin.width),
 324                          Math.max(lmSize.height, ourMin.height));
 325                 return lmSize;
 326             }
 327             return ourMin;
 328         }
 329         return null;
 330     }
 331 


 816                 }
 817             }
 818         }
 819     }
 820 
 821     /**
 822      * Constructs a new instance of a {@code ButtonActionListener}.
 823      *
 824      * @param buttonIndex an index of the button
 825      * @return a new instance of a {@code ButtonActionListener}
 826      */
 827     protected ActionListener createButtonActionListener(int buttonIndex) {
 828         return new ButtonActionListener(buttonIndex);
 829     }
 830 
 831     /**
 832      * Returns the buttons to display from the {@code JOptionPane} the receiver is
 833      * providing the look and feel for. If the {@code JOptionPane} has options
 834      * set, they will be provided, otherwise if the optionType is
 835      * {@code YES_NO_OPTION}, {@code yesNoOptions} is returned, if the type is
 836      * {@code YES_NO_CANCEL_OPTION yesNoCancelOptions} is returned, otherwise
 837      * {@code defaultButtons} are returned.
 838      *
 839      * @return the buttons to display from the JOptionPane
 840      */
 841     protected Object[] getButtons() {
 842         if (optionPane != null) {
 843             Object[] suppliedOptions = optionPane.getOptions();
 844 
 845             if (suppliedOptions == null) {
 846                 Object[] defaultOptions;
 847                 int type = optionPane.getOptionType();
 848                 Locale l = optionPane.getLocale();
 849                 int minimumWidth =
 850                     DefaultLookup.getInt(optionPane, this,
 851                                         "OptionPane.buttonMinimumWidth",-1);
 852                 if (type == JOptionPane.YES_NO_OPTION) {
 853                     defaultOptions = new ButtonFactory[2];
 854                     defaultOptions[0] = new ButtonFactory(
 855                         UIManager.getString("OptionPane.yesButtonText", l),
 856                         getMnemonic("OptionPane.yesButtonMnemonic", l),


 986 
 987             if (initialFocusComponent instanceof JButton) {
 988                 JRootPane root = SwingUtilities.getRootPane(initialFocusComponent);
 989                 if (root != null) {
 990                     root.setDefaultButton((JButton)initialFocusComponent);
 991                 }
 992             }
 993         }
 994     }
 995 
 996     /**
 997      * Returns true if in the last call to validateComponent the message
 998      * or buttons contained a subclass of Component.
 999      */
1000     public boolean containsCustomComponents(JOptionPane op) {
1001         return hasCustomComponents;
1002     }
1003 
1004 
1005     /**
1006      * {@code ButtonAreaLayout} behaves in a similar manner to
1007      * {@code FlowLayout}. It lays out all components from left to
1008      * right. If {@code syncAllWidths} is true, the widths of each
1009      * component will be set to the largest preferred size width.
1010      *
1011      * This class should be treated as a &quot;protected&quot; inner class.
1012      * Instantiate it only within subclasses of {@code BasicOptionPaneUI}.
1013      */
1014     public static class ButtonAreaLayout implements LayoutManager {
1015         /**
1016          * The value represents if the width of children should be synchronized.
1017          */
1018         protected boolean           syncAllWidths;
1019         /**
1020          * The padding value.
1021          */
1022         protected int               padding;
1023         /** If true, children are lumped together in parent. */
1024         protected boolean           centersChildren;
1025         private int orientation;
1026         private boolean reverseButtons;
1027         /**
1028          * Indicates whether or not centersChildren should be used vs


1241                     }
1242                 }
1243             }
1244             return new Dimension(0, 0);
1245         }
1246 
1247         public Dimension preferredLayoutSize(Container c) {
1248             return minimumLayoutSize(c);
1249         }
1250 
1251         public void removeLayoutComponent(Component c) { }
1252     }
1253 
1254 
1255     /**
1256      * This class should be treated as a &quot;protected&quot; inner class.
1257      * Instantiate it only within subclasses of {@code BasicOptionPaneUI}.
1258      */
1259     public class PropertyChangeHandler implements PropertyChangeListener {
1260         /**
1261          * If the source of the PropertyChangeEvent {@code e} equals the
1262          * optionPane and is one of the ICON_PROPERTY, MESSAGE_PROPERTY,
1263          * OPTIONS_PROPERTY or INITIAL_VALUE_PROPERTY,
1264          * validateComponent is invoked.
1265          */
1266         public void propertyChange(PropertyChangeEvent e) {
1267             getHandler().propertyChange(e);
1268         }
1269     }
1270 
1271     /**
1272      * Configures any necessary colors/fonts for the specified label
1273      * used representing the message.
1274      */
1275     private void configureMessageLabel(JLabel label) {
1276         Color color = (Color)DefaultLookup.get(optionPane, this,
1277                                                "OptionPane.messageForeground");
1278         if (color != null) {
1279             label.setForeground(color);
1280         }
1281         Font messageFont = (Font)DefaultLookup.get(optionPane, this,


1509 
1510             if (processed && condition != JComponent.WHEN_IN_FOCUSED_WINDOW) {
1511                 for (int counter = strokes.length - 1; counter >= 0;
1512                          counter--) {
1513                     if (strokes[counter].equals(ks)) {
1514                         // Returning false will allow further processing
1515                         // of the bindings, eg our parent Containers will get a
1516                         // crack at them.
1517                         return false;
1518                     }
1519                 }
1520             }
1521             return processed;
1522         }
1523     }
1524 
1525 
1526 
1527     /**
1528      * Registered in the ActionMap. Sets the value of the option pane
1529      * to {@code JOptionPane.CLOSED_OPTION}.
1530      */
1531     private static class Actions extends UIAction {
1532         private static final String CLOSE = "close";
1533 
1534         Actions(String key) {
1535             super(key);
1536         }
1537 
1538         public void actionPerformed(ActionEvent e) {
1539             if (getName() == CLOSE) {
1540                 JOptionPane optionPane = (JOptionPane)e.getSource();
1541 
1542                 optionPane.setValue(Integer.valueOf(JOptionPane.CLOSED_OPTION));
1543             }
1544         }
1545     }
1546 
1547 
1548     /**
1549      * This class is used to create the default buttons. This indirection is


< prev index next >