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