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