1 /* 2 * Copyright (c) 2002, 2010, 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 */ 54 public static ComponentUI createUI(JComponent x) { 55 return new SynthOptionPaneUI(); 56 } 57 58 /** 59 * @inheritDoc 60 */ 61 @Override 62 protected void installDefaults() { 63 updateStyle(optionPane); 64 } 65 66 /** 67 * @inheritDoc 68 */ 69 @Override 70 protected void installListeners() { 71 super.installListeners(); 72 optionPane.addPropertyChangeListener(this); 73 } 74 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 context.dispose(); 92 } 93 94 /** 95 * @inheritDoc 96 */ 97 @Override 98 protected void uninstallDefaults() { 99 SynthContext context = getContext(optionPane, ENABLED); 100 101 style.uninstallDefaults(context); 102 context.dispose(); 103 style = null; 104 } 105 106 /** 107 * @inheritDoc 108 */ 109 @Override 110 protected void uninstallListeners() { 111 super.uninstallListeners(); 112 optionPane.removePropertyChangeListener(this); 113 } 114 115 /** 116 * @inheritDoc 117 */ 118 @Override 119 protected void installComponents() { 120 optionPane.add(createMessageArea()); 121 122 Container separator = createSeparator(); 123 if (separator != null) { 124 optionPane.add(separator); 125 SynthContext context = getContext(optionPane, ENABLED); 126 optionPane.add(Box.createVerticalStrut(context.getStyle(). 127 getInt(context, "OptionPane.separatorPadding", 6))); 128 context.dispose(); 129 } 130 optionPane.add(createButtonArea()); 131 optionPane.applyComponentOrientation(optionPane.getComponentOrientation()); 132 } 133 134 /** 135 * @inheritDoc 136 */ 137 @Override 138 public SynthContext getContext(JComponent c) { 139 return getContext(c, getComponentState(c)); 140 } 141 142 private SynthContext getContext(JComponent c, int state) { 143 return SynthContext.getContext(SynthContext.class, c, 144 SynthLookAndFeel.getRegion(c), style, state); 145 } 146 147 private int getComponentState(JComponent c) { 148 return SynthLookAndFeel.getComponentState(c); 149 } 150 151 /** 152 * Notifies this UI delegate to repaint the specified component. 153 * This method paints the component background, then calls 154 * the {@link #paint(SynthContext,Graphics)} method. 155 * 156 * <p>In general, this method does not need to be overridden by subclasses. 157 * All Look and Feel rendering code should reside in the {@code paint} method. 158 * 159 * @param g the {@code Graphics} object used for painting 160 * @param c the component being painted 161 * @see #paint(SynthContext,Graphics) 162 */ 163 @Override 164 public void update(Graphics g, JComponent c) { 165 SynthContext context = getContext(c); 166 167 SynthLookAndFeel.update(context, g); 168 context.getPainter().paintOptionPaneBackground(context, 169 g, 0, 0, c.getWidth(), c.getHeight()); 170 paint(context, g); 171 context.dispose(); 172 } 173 174 /** 175 * Paints the specified component according to the Look and Feel. 176 * <p>This method is not used by Synth Look and Feel. 177 * Painting is handled by the {@link #paint(SynthContext,Graphics)} method. 178 * 179 * @param g the {@code Graphics} object used for painting 180 * @param c the component being painted 181 * @see #paint(SynthContext,Graphics) 182 */ 183 @Override 184 public void paint(Graphics g, JComponent c) { 185 SynthContext context = getContext(c); 186 187 paint(context, g); 188 context.dispose(); 189 } 190 191 /** 192 * Paints the specified component. This implementation does nothing. 193 * 194 * @param context context for the component being painted 195 * @param g the {@code Graphics} object used for painting 196 * @see #update(Graphics,JComponent) 197 */ 198 protected void paint(SynthContext context, Graphics g) { 199 } 200 201 /** 202 * @inheritDoc 203 */ 204 @Override 205 public void paintBorder(SynthContext context, Graphics g, int x, 206 int y, int w, int h) { 207 context.getPainter().paintOptionPaneBorder(context, g, x, y, w, h); 208 } 209 210 /** 211 * @inheritDoc 212 */ 213 @Override 214 public void propertyChange(PropertyChangeEvent e) { 215 if (SynthLookAndFeel.shouldUpdateStyle(e)) { 216 updateStyle((JOptionPane)e.getSource()); 217 } 218 } 219 220 /** 221 * @inheritDoc 222 */ 223 @Override 224 protected boolean getSizeButtonsToSameWidth() { 225 return DefaultLookup.getBoolean(optionPane, this, 226 "OptionPane.sameSizeButtons", true); 227 } 228 229 /** 230 * Called from {@link #installComponents} to create a {@code Container} 231 * containing the body of the message. The icon is the created by calling 232 * {@link #addIcon}. 233 */ 234 @Override 235 protected Container createMessageArea() { 236 JPanel top = new JPanel(); 237 top.setName("OptionPane.messageArea"); 238 top.setLayout(new BorderLayout()); 239 240 /* Fill the body. */ 241 Container body = new JPanel(new GridBagLayout()); 242 Container realBody = new JPanel(new BorderLayout()); 243 244 body.setName("OptionPane.body"); 245 realBody.setName("OptionPane.realBody"); 246 247 if (getIcon() != null) { 248 JPanel sep = new JPanel(); 249 sep.setName("OptionPane.separator"); 250 sep.setPreferredSize(new Dimension(15, 1)); 251 realBody.add(sep, BorderLayout.BEFORE_LINE_BEGINS); 252 } 253 realBody.add(body, BorderLayout.CENTER); 254 255 GridBagConstraints cons = new GridBagConstraints(); 256 cons.gridx = cons.gridy = 0; 257 cons.gridwidth = GridBagConstraints.REMAINDER; 258 cons.gridheight = 1; 259 260 SynthContext context = getContext(optionPane, ENABLED); 261 cons.anchor = context.getStyle().getInt(context, 262 "OptionPane.messageAnchor", GridBagConstraints.CENTER); 263 context.dispose(); 264 265 cons.insets = new Insets(0,0,3,0); 266 267 addMessageComponents(body, cons, getMessage(), 268 getMaxCharactersPerLineCount(), false); 269 top.add(realBody, BorderLayout.CENTER); 270 271 addIcon(top); 272 return top; 273 } 274 275 /** 276 * @inheritDoc 277 */ 278 @Override 279 protected Container createSeparator() { 280 JSeparator separator = new JSeparator(SwingConstants.HORIZONTAL); 281 282 separator.setName("OptionPane.separator"); 283 return separator; 284 } 285 }