001/* BasicColorChooserUI.java -- 002 Copyright (C) 2004, 2005 Free Software Foundation, Inc. 003 004This file is part of GNU Classpath. 005 006GNU Classpath is free software; you can redistribute it and/or modify 007it under the terms of the GNU General Public License as published by 008the Free Software Foundation; either version 2, or (at your option) 009any later version. 010 011GNU Classpath is distributed in the hope that it will be useful, but 012WITHOUT ANY WARRANTY; without even the implied warranty of 013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014General Public License for more details. 015 016You should have received a copy of the GNU General Public License 017along with GNU Classpath; see the file COPYING. If not, write to the 018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 01902110-1301 USA. 020 021Linking this library statically or dynamically with other modules is 022making a combined work based on this library. Thus, the terms and 023conditions of the GNU General Public License cover the whole 024combination. 025 026As a special exception, the copyright holders of this library give you 027permission to link this library with independent modules to produce an 028executable, regardless of the license terms of these independent 029modules, and to copy and distribute the resulting executable under 030terms of your choice, provided that you also meet, for each linked 031independent module, the terms and conditions of the license of that 032module. An independent module is a module which is not derived from 033or based on this library. If you modify this library, you may extend 034this exception to your version of the library, but you are not 035obligated to do so. If you do not wish to do so, delete this 036exception statement from your version. */ 037 038 039package javax.swing.plaf.basic; 040 041import java.awt.BorderLayout; 042import java.awt.Container; 043import java.beans.PropertyChangeEvent; 044import java.beans.PropertyChangeListener; 045 046import javax.swing.JColorChooser; 047import javax.swing.JComponent; 048import javax.swing.JPanel; 049import javax.swing.JTabbedPane; 050import javax.swing.LookAndFeel; 051import javax.swing.colorchooser.AbstractColorChooserPanel; 052import javax.swing.colorchooser.ColorChooserComponentFactory; 053import javax.swing.event.ChangeEvent; 054import javax.swing.event.ChangeListener; 055import javax.swing.plaf.ColorChooserUI; 056import javax.swing.plaf.ComponentUI; 057 058/** 059 * This is the UI Class for the JColorChooser in the Basic Look and Feel. 060 */ 061public 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}