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 26package javax.swing.plaf.synth; 27 28import java.awt.*; 29import java.awt.event.*; 30import javax.swing.*; 31import javax.swing.plaf.*; 32import javax.swing.plaf.basic.BasicDesktopIconUI; 33import 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 */ 42public 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 } 125 126 /** 127 * {@inheritDoc} 128 */ 129 @Override 130 protected void uninstallDefaults() { 131 SynthContext context = getContext(desktopIcon, ENABLED); 132 style.uninstallDefaults(context); 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 return SynthContext.getContext(c, style, state); 146 } 147 148 private int getComponentState(JComponent c) { 149 return SynthLookAndFeel.getComponentState(c); 150 } 151 152 /** 153 * Notifies this UI delegate to repaint the specified component. 154 * This method paints the component background, then calls 155 * the {@link #paint(SynthContext,Graphics)} method. 156 * 157 * <p>In general, this method does not need to be overridden by subclasses. 158 * All Look and Feel rendering code should reside in the {@code paint} method. 159 * 160 * @param g the {@code Graphics} object used for painting 161 * @param c the component being painted 162 * @see #paint(SynthContext,Graphics) 163 */ 164 @Override 165 public void update(Graphics g, JComponent c) { 166 SynthContext context = getContext(c); 167 168 SynthLookAndFeel.update(context, g); 169 context.getPainter().paintDesktopIconBackground(context, g, 0, 0, 170 c.getWidth(), c.getHeight()); 171 paint(context, g); 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 } 189 190 /** 191 * Paints the specified component. This implementation does nothing. 192 * 193 * @param context context for the component being painted 194 * @param g the {@code Graphics} object used for painting 195 * @see #update(Graphics,JComponent) 196 */ 197 protected void paint(SynthContext context, Graphics g) { 198 } 199 200 /** 201 * {@inheritDoc} 202 */ 203 @Override 204 public void paintBorder(SynthContext context, Graphics g, int x, 205 int y, int w, int h) { 206 context.getPainter().paintDesktopIconBorder(context, g, x, y, w, h); 207 } 208 209 public void propertyChange(PropertyChangeEvent evt) { 210 if (evt.getSource() instanceof JInternalFrame.JDesktopIcon) { 211 if (SynthLookAndFeel.shouldUpdateStyle(evt)) { 212 updateStyle((JInternalFrame.JDesktopIcon)evt.getSource()); 213 } 214 } else if (evt.getSource() instanceof JInternalFrame) { 215 JInternalFrame frame = (JInternalFrame)evt.getSource(); 216 if (iconPane instanceof JToggleButton) { 217 JToggleButton button = (JToggleButton)iconPane; 218 String prop = evt.getPropertyName(); 219 if (prop == "title") { 220 button.setText((String)evt.getNewValue()); 221 } else if (prop == "frameIcon") { 222 button.setIcon((Icon)evt.getNewValue()); 223 } else if (prop == JInternalFrame.IS_ICON_PROPERTY || 224 prop == JInternalFrame.IS_SELECTED_PROPERTY) { 225 button.setSelected(!frame.isIcon() && frame.isSelected()); 226 } 227 } 228 } 229 } 230 231 private final class Handler implements ActionListener { 232 public void actionPerformed(ActionEvent evt) { 233 if (evt.getSource() instanceof JToggleButton) { 234 // Either iconify the frame or deiconify and activate it. 235 JToggleButton button = (JToggleButton)evt.getSource(); 236 try { 237 boolean selected = button.isSelected(); 238 if (!selected && !frame.isIconifiable()) { 239 button.setSelected(true); 240 } else { 241 frame.setIcon(!selected); 242 if (selected) { 243 frame.setSelected(true); 244 } 245 } 246 } catch (PropertyVetoException e2) { 247 } 248 } 249 } 250 } 251} 252