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.awt.event.*; 30 import javax.swing.*; 31 import javax.swing.plaf.*; 32 import javax.swing.plaf.basic.BasicInternalFrameUI; 33 import java.beans.*; 34 35 36 /** 37 * Provides the Synth L&F UI delegate for 38 * {@link javax.swing.JInternalFrame}. 39 * 40 * @author David Kloba 41 * @author Joshua Outwater 42 * @author Rich Schiavi 43 * @since 1.7 44 */ 45 public class SynthInternalFrameUI extends BasicInternalFrameUI 46 implements SynthUI, PropertyChangeListener { 47 private SynthStyle style; 48 49 /** 50 * Creates a new UI object for the given component. 51 * 52 * @param b component to create UI object for 53 * @return the UI object 54 */ 55 public static ComponentUI createUI(JComponent b) { 56 return new SynthInternalFrameUI((JInternalFrame)b); 57 } 58 59 protected SynthInternalFrameUI(JInternalFrame b) { 60 super(b); 61 } 62 63 /** 64 * @inheritDoc 65 */ 66 @Override 67 public void installDefaults() { 68 frame.setLayout(internalFrameLayout = createLayoutManager()); 69 updateStyle(frame); 70 } 71 72 /** 73 * @inheritDoc 74 */ 75 @Override 76 protected void installListeners() { 77 super.installListeners(); 78 frame.addPropertyChangeListener(this); 79 } 80 81 /** 82 * @inheritDoc 83 */ 84 @Override 85 protected void uninstallComponents() { 86 if (frame.getComponentPopupMenu() instanceof UIResource) { 87 frame.setComponentPopupMenu(null); 88 } 89 super.uninstallComponents(); 90 } 91 92 /** 93 * @inheritDoc 94 */ 95 @Override 96 protected void uninstallListeners() { 97 frame.removePropertyChangeListener(this); 98 super.uninstallListeners(); 99 } 100 101 private void updateStyle(JComponent c) { 102 SynthContext context = getContext(c, ENABLED); 103 SynthStyle oldStyle = style; 104 105 style = SynthLookAndFeel.updateStyle(context, this); 106 if (style != oldStyle) { 107 Icon frameIcon = frame.getFrameIcon(); 108 if (frameIcon == null || frameIcon instanceof UIResource) { 109 frame.setFrameIcon(context.getStyle().getIcon( 110 context, "InternalFrame.icon")); 111 } 112 if (oldStyle != null) { 113 uninstallKeyboardActions(); 114 installKeyboardActions(); 115 } 116 } 117 context.dispose(); 118 } 119 120 /** 121 * @inheritDoc 122 */ 123 @Override 124 protected void uninstallDefaults() { 125 SynthContext context = getContext(frame, ENABLED); 126 style.uninstallDefaults(context); 127 context.dispose(); 128 style = null; 129 if(frame.getLayout() == internalFrameLayout) { 130 frame.setLayout(null); 131 } 132 133 } 134 135 /** 136 * @inheritDoc 137 */ 138 @Override 139 public SynthContext getContext(JComponent c) { 140 return getContext(c, getComponentState(c)); 141 } 142 143 private SynthContext getContext(JComponent c, int state) { 144 return SynthContext.getContext(SynthContext.class, c, 145 SynthLookAndFeel.getRegion(c), style, state); 146 } 147 148 private int getComponentState(JComponent c) { 149 return SynthLookAndFeel.getComponentState(c); 150 } 151 152 /** 153 * @inheritDoc 154 */ 155 @Override 156 protected JComponent createNorthPane(JInternalFrame w) { 157 titlePane = new SynthInternalFrameTitlePane(w); 158 titlePane.setName("InternalFrame.northPane"); 159 return titlePane; 160 } 161 162 /** 163 * @inheritDoc 164 */ 165 @Override 166 protected ComponentListener createComponentListener() { 167 if (UIManager.getBoolean("InternalFrame.useTaskBar")) { 168 return new ComponentHandler() { 169 @Override public void componentResized(ComponentEvent e) { 170 if (frame != null && frame.isMaximum()) { 171 JDesktopPane desktop = (JDesktopPane)e.getSource(); 172 for (Component comp : desktop.getComponents()) { 173 if (comp instanceof SynthDesktopPaneUI.TaskBar) { 174 frame.setBounds(0, 0, 175 desktop.getWidth(), 176 desktop.getHeight() - comp.getHeight()); 177 frame.revalidate(); 178 break; 179 } 180 } 181 } 182 183 // Update the new parent bounds for next resize, but don't 184 // let the super method touch this frame 185 JInternalFrame f = frame; 186 frame = null; 187 super.componentResized(e); 188 frame = f; 189 } 190 }; 191 } else { 192 return super.createComponentListener(); 193 } 194 } 195 196 /** 197 * Notifies this UI delegate to repaint the specified component. 198 * This method paints the component background, then calls 199 * the {@link #paint(SynthContext,Graphics)} method. 200 * 201 * <p>In general, this method does not need to be overridden by subclasses. 202 * All Look and Feel rendering code should reside in the {@code paint} method. 203 * 204 * @param g the {@code Graphics} object used for painting 205 * @param c the component being painted 206 * @see #paint(SynthContext,Graphics) 207 */ 208 @Override 209 public void update(Graphics g, JComponent c) { 210 SynthContext context = getContext(c); 211 212 SynthLookAndFeel.update(context, g); 213 context.getPainter().paintInternalFrameBackground(context, 214 g, 0, 0, c.getWidth(), c.getHeight()); 215 paint(context, g); 216 context.dispose(); 217 } 218 219 /** 220 * Paints the specified component according to the Look and Feel. 221 * <p>This method is not used by Synth Look and Feel. 222 * Painting is handled by the {@link #paint(SynthContext,Graphics)} method. 223 * 224 * @param g the {@code Graphics} object used for painting 225 * @param c the component being painted 226 * @see #paint(SynthContext,Graphics) 227 */ 228 @Override 229 public void paint(Graphics g, JComponent c) { 230 SynthContext context = getContext(c); 231 232 paint(context, g); 233 context.dispose(); 234 } 235 236 /** 237 * Paints the specified component. This implementation does nothing. 238 * 239 * @param context context for the component being painted 240 * @param g the {@code Graphics} object used for painting 241 * @see #update(Graphics,JComponent) 242 */ 243 protected void paint(SynthContext context, Graphics g) { 244 } 245 246 /** 247 * @inheritDoc 248 */ 249 @Override 250 public void paintBorder(SynthContext context, Graphics g, int x, 251 int y, int w, int h) { 252 context.getPainter().paintInternalFrameBorder(context, 253 g, x, y, w, h); 254 } 255 256 /** 257 * @inheritDoc 258 */ 259 @Override 260 public void propertyChange(PropertyChangeEvent evt) { 261 SynthStyle oldStyle = style; 262 JInternalFrame f = (JInternalFrame)evt.getSource(); 263 String prop = evt.getPropertyName(); 264 265 if (SynthLookAndFeel.shouldUpdateStyle(evt)) { 266 updateStyle(f); 267 } 268 269 if (style == oldStyle && 270 (prop == JInternalFrame.IS_MAXIMUM_PROPERTY || 271 prop == JInternalFrame.IS_SELECTED_PROPERTY)) { 272 // Border (and other defaults) may need to change 273 SynthContext context = getContext(f, ENABLED); 274 style.uninstallDefaults(context); 275 style.installDefaults(context, this); 276 } 277 } 278 }