1 /* 2 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package javax.swing.plaf.synth; 27 28 import java.awt.*; 29 import java.beans.*; 30 import javax.swing.*; 31 import javax.swing.plaf.*; 32 import javax.swing.plaf.basic.*; 33 import sun.swing.DefaultLookup; 34 35 /** 36 * Provides the Synth L&F UI delegate for 37 * {@link javax.swing.JOptionPane}. 38 * 39 * @author James Gosling 40 * @author Scott Violet 41 * @author Amy Fowler 42 * @since 1.7 43 */ 44 public class SynthOptionPaneUI extends BasicOptionPaneUI implements 45 PropertyChangeListener, SynthUI { 46 private SynthStyle style; 47 48 /** 49 * Creates a new UI object for the given component. 50 * 51 * @param x component to create UI object for 52 * @return the UI object 53 */ createUI(JComponent x)54 public static ComponentUI createUI(JComponent x) { 55 return new SynthOptionPaneUI(); 56 } 57 58 /** 59 * {@inheritDoc} 60 */ 61 @Override installDefaults()62 protected void installDefaults() { 63 updateStyle(optionPane); 64 } 65 66 /** 67 * {@inheritDoc} 68 */ 69 @Override installListeners()70 protected void installListeners() { 71 super.installListeners(); 72 optionPane.addPropertyChangeListener(this); 73 } 74 updateStyle(JComponent c)75 private void updateStyle(JComponent c) { 76 SynthContext context = getContext(c, ENABLED); 77 SynthStyle oldStyle = style; 78 79 style = SynthLookAndFeel.updateStyle(context, this); 80 if (style != oldStyle) { 81 minimumSize = (Dimension)style.get(context, 82 "OptionPane.minimumSize"); 83 if (minimumSize == null) { 84 minimumSize = new Dimension(262, 90); 85 } 86 if (oldStyle != null) { 87 uninstallKeyboardActions(); 88 installKeyboardActions(); 89 } 90 } 91 } 92 93 /** 94 * {@inheritDoc} 95 */ 96 @Override uninstallDefaults()97 protected void uninstallDefaults() { 98 SynthContext context = getContext(optionPane, ENABLED); 99 100 style.uninstallDefaults(context); 101 style = null; 102 } 103 104 /** 105 * {@inheritDoc} 106 */ 107 @Override uninstallListeners()108 protected void uninstallListeners() { 109 super.uninstallListeners(); 110 optionPane.removePropertyChangeListener(this); 111 } 112 113 /** 114 * {@inheritDoc} 115 */ 116 @Override installComponents()117 protected void installComponents() { 118 optionPane.add(createMessageArea()); 119 120 Container separator = createSeparator(); 121 if (separator != null) { 122 optionPane.add(separator); 123 SynthContext context = getContext(optionPane, ENABLED); 124 optionPane.add(Box.createVerticalStrut(context.getStyle(). 125 getInt(context, "OptionPane.separatorPadding", 6))); 126 } 127 optionPane.add(createButtonArea()); 128 optionPane.applyComponentOrientation(optionPane.getComponentOrientation()); 129 } 130 131 /** 132 * {@inheritDoc} 133 */ 134 @Override getContext(JComponent c)135 public SynthContext getContext(JComponent c) { 136 return getContext(c, getComponentState(c)); 137 } 138 getContext(JComponent c, int state)139 private SynthContext getContext(JComponent c, int state) { 140 return SynthContext.getContext(c, style, state); 141 } 142 getComponentState(JComponent c)143 private int getComponentState(JComponent c) { 144 return SynthLookAndFeel.getComponentState(c); 145 } 146 147 /** 148 * Notifies this UI delegate to repaint the specified component. 149 * This method paints the component background, then calls 150 * the {@link #paint(SynthContext,Graphics)} method. 151 * 152 * <p>In general, this method does not need to be overridden by subclasses. 153 * All Look and Feel rendering code should reside in the {@code paint} method. 154 * 155 * @param g the {@code Graphics} object used for painting 156 * @param c the component being painted 157 * @see #paint(SynthContext,Graphics) 158 */ 159 @Override update(Graphics g, JComponent c)160 public void update(Graphics g, JComponent c) { 161 SynthContext context = getContext(c); 162 163 SynthLookAndFeel.update(context, g); 164 context.getPainter().paintOptionPaneBackground(context, 165 g, 0, 0, c.getWidth(), c.getHeight()); 166 paint(context, g); 167 } 168 169 /** 170 * Paints the specified component according to the Look and Feel. 171 * <p>This method is not used by Synth Look and Feel. 172 * Painting is handled by the {@link #paint(SynthContext,Graphics)} method. 173 * 174 * @param g the {@code Graphics} object used for painting 175 * @param c the component being painted 176 * @see #paint(SynthContext,Graphics) 177 */ 178 @Override paint(Graphics g, JComponent c)179 public void paint(Graphics g, JComponent c) { 180 SynthContext context = getContext(c); 181 182 paint(context, g); 183 } 184 185 /** 186 * Paints the specified component. This implementation does nothing. 187 * 188 * @param context context for the component being painted 189 * @param g the {@code Graphics} object used for painting 190 * @see #update(Graphics,JComponent) 191 */ paint(SynthContext context, Graphics g)192 protected void paint(SynthContext context, Graphics g) { 193 } 194 195 /** 196 * {@inheritDoc} 197 */ 198 @Override paintBorder(SynthContext context, Graphics g, int x, int y, int w, int h)199 public void paintBorder(SynthContext context, Graphics g, int x, 200 int y, int w, int h) { 201 context.getPainter().paintOptionPaneBorder(context, g, x, y, w, h); 202 } 203 204 /** 205 * {@inheritDoc} 206 */ 207 @Override propertyChange(PropertyChangeEvent e)208 public void propertyChange(PropertyChangeEvent e) { 209 if (SynthLookAndFeel.shouldUpdateStyle(e)) { 210 updateStyle((JOptionPane)e.getSource()); 211 } 212 } 213 214 /** 215 * {@inheritDoc} 216 */ 217 @Override getSizeButtonsToSameWidth()218 protected boolean getSizeButtonsToSameWidth() { 219 return DefaultLookup.getBoolean(optionPane, this, 220 "OptionPane.sameSizeButtons", true); 221 } 222 223 /** 224 * Called from {@link #installComponents} to create a {@code Container} 225 * containing the body of the message. The icon is the created by calling 226 * {@link #addIcon}. 227 */ 228 @Override createMessageArea()229 protected Container createMessageArea() { 230 JPanel top = new JPanel(); 231 top.setName("OptionPane.messageArea"); 232 top.setLayout(new BorderLayout()); 233 234 /* Fill the body. */ 235 Container body = new JPanel(new GridBagLayout()); 236 Container realBody = new JPanel(new BorderLayout()); 237 238 body.setName("OptionPane.body"); 239 realBody.setName("OptionPane.realBody"); 240 241 if (getIcon() != null) { 242 JPanel sep = new JPanel(); 243 sep.setName("OptionPane.separator"); 244 sep.setPreferredSize(new Dimension(15, 1)); 245 realBody.add(sep, BorderLayout.BEFORE_LINE_BEGINS); 246 } 247 realBody.add(body, BorderLayout.CENTER); 248 249 GridBagConstraints cons = new GridBagConstraints(); 250 cons.gridx = cons.gridy = 0; 251 cons.gridwidth = GridBagConstraints.REMAINDER; 252 cons.gridheight = 1; 253 254 SynthContext context = getContext(optionPane, ENABLED); 255 cons.anchor = context.getStyle().getInt(context, 256 "OptionPane.messageAnchor", GridBagConstraints.CENTER); 257 258 cons.insets = new Insets(0,0,3,0); 259 260 addMessageComponents(body, cons, getMessage(), 261 getMaxCharactersPerLineCount(), false); 262 top.add(realBody, BorderLayout.CENTER); 263 264 addIcon(top); 265 return top; 266 } 267 268 /** 269 * {@inheritDoc} 270 */ 271 @Override createSeparator()272 protected Container createSeparator() { 273 JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL); 274 275 separator.setName("OptionPane.separator"); 276 return separator; 277 } 278 } 279