001 /* BasicColorChooserUI.java -- 002 Copyright (C) 2004, 2005 Free Software Foundation, Inc. 003 004 This file is part of GNU Classpath. 005 006 GNU Classpath is free software; you can redistribute it and/or modify 007 it under the terms of the GNU General Public License as published by 008 the Free Software Foundation; either version 2, or (at your option) 009 any later version. 010 011 GNU Classpath is distributed in the hope that it will be useful, but 012 WITHOUT ANY WARRANTY; without even the implied warranty of 013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 General Public License for more details. 015 016 You should have received a copy of the GNU General Public License 017 along with GNU Classpath; see the file COPYING. If not, write to the 018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 02110-1301 USA. 020 021 Linking this library statically or dynamically with other modules is 022 making a combined work based on this library. Thus, the terms and 023 conditions of the GNU General Public License cover the whole 024 combination. 025 026 As a special exception, the copyright holders of this library give you 027 permission to link this library with independent modules to produce an 028 executable, regardless of the license terms of these independent 029 modules, and to copy and distribute the resulting executable under 030 terms of your choice, provided that you also meet, for each linked 031 independent module, the terms and conditions of the license of that 032 module. An independent module is a module which is not derived from 033 or based on this library. If you modify this library, you may extend 034 this exception to your version of the library, but you are not 035 obligated to do so. If you do not wish to do so, delete this 036 exception statement from your version. */ 037 038 039 package javax.swing.plaf.basic; 040 041 import java.awt.BorderLayout; 042 import java.awt.Container; 043 import java.beans.PropertyChangeEvent; 044 import java.beans.PropertyChangeListener; 045 046 import javax.swing.JColorChooser; 047 import javax.swing.JComponent; 048 import javax.swing.JPanel; 049 import javax.swing.JTabbedPane; 050 import javax.swing.LookAndFeel; 051 import javax.swing.colorchooser.AbstractColorChooserPanel; 052 import javax.swing.colorchooser.ColorChooserComponentFactory; 053 import javax.swing.event.ChangeEvent; 054 import javax.swing.event.ChangeListener; 055 import javax.swing.plaf.ColorChooserUI; 056 import javax.swing.plaf.ComponentUI; 057 058 /** 059 * This is the UI Class for the JColorChooser in the Basic Look and Feel. 060 */ 061 public class BasicColorChooserUI extends ColorChooserUI 062 { 063 /** 064 * This helper class handles property changes from the JColorChooser. 065 */ 066 public class PropertyHandler implements PropertyChangeListener 067 { 068 /** 069 * This method is called when any of the properties of the JColorChooser 070 * change. 071 * 072 * @param e The PropertyChangeEvent. 073 */ 074 public void propertyChange(PropertyChangeEvent e) 075 { 076 if (e.getPropertyName() == JColorChooser.CHOOSER_PANELS_PROPERTY) 077 makeTabs(chooser.getChooserPanels()); 078 else if (e.getPropertyName() == JColorChooser.PREVIEW_PANEL_PROPERTY) 079 updatePreviewPanel(chooser.getPreviewPanel()); 080 else if (e.getPropertyName() == JColorChooser.SELECTION_MODEL_PROPERTY) 081 ((AbstractColorChooserPanel) pane.getSelectedComponent()) 082 .updateChooser(); 083 084 chooser.repaint(); 085 } 086 } 087 088 /** 089 * This is a helper class that listens to the Model of the JColorChooser for 090 * color change events so it can update the preview panel. 091 */ 092 private class PreviewListener implements ChangeListener 093 { 094 /** 095 * This method is called whenever the JColorChooser's color changes. 096 * 097 * @param e The ChangeEvent. 098 */ 099 public void stateChanged(ChangeEvent e) 100 { 101 if (pane != null) 102 { 103 AbstractColorChooserPanel panel = (AbstractColorChooserPanel) pane 104 .getSelectedComponent(); 105 if (panel != null) 106 panel.updateChooser(); 107 } 108 chooser.repaint(); 109 } 110 } 111 112 /** 113 * This helper class listens to the JTabbedPane that is used for tab 114 * changes. 115 */ 116 private class TabPaneListener implements ChangeListener 117 { 118 /** 119 * This method is called whenever a different tab is selected in the 120 * JTabbedPane. 121 * 122 * @param e The ChangeEvent. 123 */ 124 public void stateChanged(ChangeEvent e) 125 { 126 // Need to do this because we don't update all the tabs when they're not 127 // visible, so they are not informed of new colors when they're hidden. 128 AbstractColorChooserPanel comp = (AbstractColorChooserPanel) pane 129 .getSelectedComponent(); 130 comp.updateChooser(); 131 } 132 } 133 134 /** An array of default choosers to use in the JColorChooser. */ 135 protected AbstractColorChooserPanel[] defaultChoosers; 136 137 /** The listener for the preview panel. */ 138 protected ChangeListener previewListener; 139 140 /** The PropertyChangeListener for the JColorChooser. */ 141 protected PropertyChangeListener propertyChangeListener; 142 143 /** 144 * The JColorChooser this is installed on. 145 */ 146 protected JColorChooser chooser; 147 148 /** The JTabbedPane that is used. */ 149 JTabbedPane pane; 150 151 /** The Container that holds the preview panel. */ 152 private Container prevContainer; 153 154 /** 155 * Creates a new BasicColorChooserUI object. 156 */ 157 public BasicColorChooserUI() 158 { 159 super(); 160 } 161 162 /** 163 * This method creates a new UI Component for the given JComponent. 164 * 165 * @param c The JComponent to create an UI for. 166 * 167 * @return A new BasicColorChooserUI. 168 */ 169 public static ComponentUI createUI(JComponent c) 170 { 171 return new BasicColorChooserUI(); 172 } 173 174 /** 175 * This method creates the default chooser panels for the JColorChooser. 176 * 177 * @return The default chooser panels. 178 */ 179 protected AbstractColorChooserPanel[] createDefaultChoosers() 180 { 181 return ColorChooserComponentFactory.getDefaultChooserPanels(); 182 } 183 184 /** 185 * This method installs the UI Component for the given JComponent. 186 * 187 * @param c The JComponent to install this UI for. 188 */ 189 public void installUI(JComponent c) 190 { 191 if (c instanceof JColorChooser) 192 { 193 chooser = (JColorChooser) c; 194 chooser.setLayout(new BorderLayout()); 195 196 // Do this first, so we avoid doing work for property change events. 197 defaultChoosers = createDefaultChoosers(); 198 chooser.setChooserPanels(defaultChoosers); 199 pane = new JTabbedPane(); 200 201 pane.addChangeListener(new ChangeListener() 202 { 203 public void stateChanged(ChangeEvent e) 204 { 205 pane.repaint(); 206 } 207 }); 208 209 makeTabs(defaultChoosers); 210 211 chooser.add(pane, BorderLayout.NORTH); 212 213 installPreviewPanel(); 214 215 installDefaults(); 216 installListeners(); 217 } 218 } 219 220 /** 221 * This method adds tabs to the JTabbedPane for the chooserPanels defined in 222 * the JColorChooser. 223 * This is package-private to avoid an accessor method. 224 * 225 * @param panels The Panels that need tabs to be made for them. 226 */ 227 void makeTabs(AbstractColorChooserPanel[] panels) 228 { 229 pane.removeAll(); 230 for (int i = 0; i < panels.length; i++) 231 pane.addTab(panels[i].getDisplayName(), panels[i].getSmallDisplayIcon(), 232 panels[i]); 233 } 234 235 /** 236 * This method uninstalls this UI for the given JComponent. 237 * 238 * @param c The JComponent that will have this UI removed. 239 */ 240 public void uninstallUI(JComponent c) 241 { 242 uninstallListeners(); 243 uninstallDefaults(); 244 uninstallDefaultChoosers(); 245 246 pane = null; 247 chooser = null; 248 } 249 250 /** 251 * Uninstalls the default color choosers that have been installed by this UI. 252 */ 253 protected void uninstallDefaultChoosers() 254 { 255 defaultChoosers = null; 256 } 257 258 /** 259 * This method installs the preview panel for the JColorChooser. 260 */ 261 protected void installPreviewPanel() 262 { 263 updatePreviewPanel(ColorChooserComponentFactory.getPreviewPanel()); 264 } 265 266 /** 267 * This is a helper method that swaps the existing preview panel with the 268 * given panel. 269 * This is package-private to avoid an accessor method. 270 * 271 * @param preview The new preview panel. 272 */ 273 void updatePreviewPanel(JComponent preview) 274 { 275 if (prevContainer == null) 276 { 277 prevContainer = new JPanel(); 278 prevContainer.setLayout(new BorderLayout()); 279 chooser.add(prevContainer, BorderLayout.CENTER); 280 } 281 prevContainer.removeAll(); 282 prevContainer.add(preview, BorderLayout.CENTER); 283 } 284 285 /** 286 * This method installs the default properties given by the Basic Look and 287 * Feel. 288 */ 289 protected void installDefaults() 290 { 291 LookAndFeel.installColorsAndFont(chooser, "ColorChooser.background", 292 "ColorChooser.foreground", 293 "ColorChooser.font"); 294 } 295 296 /** 297 * This method uninstalls the default properties given by the Basic Look and 298 * Feel. 299 */ 300 protected void uninstallDefaults() 301 { 302 chooser.setBackground(null); 303 chooser.setForeground(null); 304 chooser.setFont(null); 305 } 306 307 /** 308 * This method installs any listeners required for this UI to function. 309 */ 310 protected void installListeners() 311 { 312 propertyChangeListener = createPropertyChangeListener(); 313 previewListener = new PreviewListener(); 314 315 chooser.addPropertyChangeListener(propertyChangeListener); 316 chooser.getSelectionModel().addChangeListener(previewListener); 317 318 pane.addChangeListener(new TabPaneListener()); 319 } 320 321 /** 322 * This method creates the PropertyChangeListener used for listening to the 323 * JColorChooser. 324 * 325 * @return A PropertyChangeListener. 326 */ 327 protected PropertyChangeListener createPropertyChangeListener() 328 { 329 return new PropertyHandler(); 330 } 331 332 /** 333 * This method uninstalls any listeners that were previously installed by 334 * the UI. 335 */ 336 protected void uninstallListeners() 337 { 338 chooser.removePropertyChangeListener(propertyChangeListener); 339 chooser.getSelectionModel().removeChangeListener(previewListener); 340 341 previewListener = null; 342 propertyChangeListener = null; 343 } 344 }