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.BasicDesktopIconUI; 33 import java.beans.*; 34 35 36 /** 37 * Provides the Synth L&F UI delegate for a minimized internal frame on a desktop. 38 * 39 * @author Joshua Outwater 40 * @since 1.7 41 */ 42 public class SynthDesktopIconUI extends BasicDesktopIconUI 43 implements SynthUI, PropertyChangeListener { 44 private SynthStyle style; 45 private Handler handler = new Handler(); 46 47 /** 48 * Creates a new UI object for the given component. 49 * 50 * @param c component to create UI object for 51 * @return the UI object 52 */ 53 public static ComponentUI createUI(JComponent c) { 54 return new SynthDesktopIconUI(); 55 } 56 57 /** 58 * {@inheritDoc} 59 */ 60 @Override 61 protected void installComponents() { 62 if (UIManager.getBoolean("InternalFrame.useTaskBar")) { 63 iconPane = new JToggleButton(frame.getTitle(), frame.getFrameIcon()) { 64 @Override public String getToolTipText() { 65 return getText(); 66 } 67 68 @Override public JPopupMenu getComponentPopupMenu() { 69 return frame.getComponentPopupMenu(); 70 } 71 }; 72 ToolTipManager.sharedInstance().registerComponent(iconPane); 73 iconPane.setFont(desktopIcon.getFont()); 74 iconPane.setBackground(desktopIcon.getBackground()); 75 iconPane.setForeground(desktopIcon.getForeground()); 76 } else { 77 iconPane = new SynthInternalFrameTitlePane(frame); 78 iconPane.setName("InternalFrame.northPane"); 79 } 80 desktopIcon.setLayout(new BorderLayout()); 81 desktopIcon.add(iconPane, BorderLayout.CENTER); 82 } 83 84 /** 85 * {@inheritDoc} 86 */ 87 @Override 88 protected void installListeners() { 89 super.installListeners(); 90 desktopIcon.addPropertyChangeListener(this); 91 92 if (iconPane instanceof JToggleButton) { 93 frame.addPropertyChangeListener(this); 94 ((JToggleButton)iconPane).addActionListener(handler); 95 } 96 } 97 98 /** 99 * {@inheritDoc} 100 */ 101 @Override 102 protected void uninstallListeners() { 103 if (iconPane instanceof JToggleButton) { 104 ((JToggleButton)iconPane).removeActionListener(handler); 105 frame.removePropertyChangeListener(this); 106 } 107 desktopIcon.removePropertyChangeListener(this); 108 super.uninstallListeners(); 109 } 110 111 /** 112 * {@inheritDoc} 113 */ 114 @Override 115 protected void installDefaults() { 116 updateStyle(desktopIcon); 117 } 118 119 private void updateStyle(JComponent c) { 120 SynthContext context = getContext(c, ENABLED); 121 style = SynthLookAndFeel.updateStyle(context, this); 122 context.dispose(); 123 } 124 125 /** 126 * {@inheritDoc} 127 */ 128 @Override 129 protected void uninstallDefaults() { 130 SynthContext context = getContext(desktopIcon, ENABLED); 131 style.uninstallDefaults(context); 132 context.dispose(); 133 style = null; 134 } 135 136 /** 137 * {@inheritDoc} 138 */ 139 @Override 140 public SynthContext getContext(JComponent c) { 141 return getContext(c, getComponentState(c)); 142 } 143 144 private SynthContext getContext(JComponent c, int state) { 145 Region region = SynthLookAndFeel.getRegion(c); 146 return SynthContext.getContext(SynthContext.class, c, region, 147 style, state); 148 } 149 150 private int getComponentState(JComponent c) { 151 return SynthLookAndFeel.getComponentState(c); 152 } 153 154 /** 155 * Notifies this UI delegate to repaint the specified component. 156 * This method paints the component background, then calls 157 * the {@link #paint(SynthContext,Graphics)} method. 158 * 159 * <p>In general, this method does not need to be overridden by subclasses. 160 * All Look and Feel rendering code should reside in the {@code paint} method. 161 * 162 * @param g the {@code Graphics} object used for painting 163 * @param c the component being painted 164 * @see #paint(SynthContext,Graphics) 165 */ 166 @Override 167 public void update(Graphics g, JComponent c) { 168 SynthContext context = getContext(c); 169 170 SynthLookAndFeel.update(context, g); 171 context.getPainter().paintDesktopIconBackground(context, g, 0, 0, 172 c.getWidth(), c.getHeight()); 173 paint(context, g); 174 context.dispose(); 175 } 176 177 /** 178 * Paints the specified component according to the Look and Feel. 179 * <p>This method is not used by Synth Look and Feel. 180 * Painting is handled by the {@link #paint(SynthContext,Graphics)} method. 181 * 182 * @param g the {@code Graphics} object used for painting 183 * @param c the component being painted 184 * @see #paint(SynthContext,Graphics) 185 */ 186 @Override 187 public void paint(Graphics g, JComponent c) { 188 SynthContext context = getContext(c); 189 190 paint(context, g); 191 context.dispose(); 192 } 193 194 /** 195 * Paints the specified component. This implementation does nothing. 196 * 197 * @param context context for the component being painted 198 * @param g the {@code Graphics} object used for painting 199 * @see #update(Graphics,JComponent) 200 */ 201 protected void paint(SynthContext context, Graphics g) { 202 } 203 204 /** 205 * {@inheritDoc} 206 */ 207 @Override 208 public void paintBorder(SynthContext context, Graphics g, int x, 209 int y, int w, int h) { 210 context.getPainter().paintDesktopIconBorder(context, g, x, y, w, h); 211 } 212 213 public void propertyChange(PropertyChangeEvent evt) { 214 if (evt.getSource() instanceof JInternalFrame.JDesktopIcon) { 215 if (SynthLookAndFeel.shouldUpdateStyle(evt)) { 216 updateStyle((JInternalFrame.JDesktopIcon)evt.getSource()); 217 } 218 } else if (evt.getSource() instanceof JInternalFrame) { 219 JInternalFrame frame = (JInternalFrame)evt.getSource(); 220 if (iconPane instanceof JToggleButton) { 221 JToggleButton button = (JToggleButton)iconPane; 222 String prop = evt.getPropertyName(); 223 if (prop == "title") { 224 button.setText((String)evt.getNewValue()); 225 } else if (prop == "frameIcon") { 226 button.setIcon((Icon)evt.getNewValue()); 227 } else if (prop == JInternalFrame.IS_ICON_PROPERTY || 228 prop == JInternalFrame.IS_SELECTED_PROPERTY) { 229 button.setSelected(!frame.isIcon() && frame.isSelected()); 230 } 231 } 232 } 233 } 234 235 private final class Handler implements ActionListener { 236 public void actionPerformed(ActionEvent evt) { 237 if (evt.getSource() instanceof JToggleButton) { 238 // Either iconify the frame or deiconify and activate it. 239 JToggleButton button = (JToggleButton)evt.getSource(); 240 try { 241 boolean selected = button.isSelected(); 242 if (!selected && !frame.isIconifiable()) { 243 button.setSelected(true); 244 } else { 245 frame.setIcon(!selected); 246 if (selected) { 247 frame.setSelected(true); 248 } 249 } 250 } catch (PropertyVetoException e2) { 251 } 252 } 253 } 254 } 255 }