1 /* 2 * Copyright (c) 1997, 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.basic; 27 28 import javax.swing.*; 29 import javax.swing.colorchooser.*; 30 import javax.swing.event.*; 31 import javax.swing.border.*; 32 import javax.swing.plaf.*; 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.beans.PropertyChangeEvent; 36 import java.beans.PropertyChangeListener; 37 38 import sun.swing.DefaultLookup; 39 40 /** 41 * Provides the basic look and feel for a JColorChooser. 42 * <p> 43 * @author Tom Santos 44 * @author Steve Wilson 45 */ 46 47 public class BasicColorChooserUI extends ColorChooserUI 48 { 49 /** 50 * JColorChooser this BasicColorChooserUI is installed on. 51 * 52 * @since 1.5 53 */ 54 protected JColorChooser chooser; 55 56 JTabbedPane tabbedPane; 57 JPanel singlePanel; 58 59 JPanel previewPanelHolder; 60 JComponent previewPanel; 61 boolean isMultiPanel = false; 62 private static TransferHandler defaultTransferHandler = new ColorTransferHandler(); 63 64 protected AbstractColorChooserPanel[] defaultChoosers; 65 66 protected ChangeListener previewListener; 67 protected PropertyChangeListener propertyChangeListener; 68 private Handler handler; 69 70 public static ComponentUI createUI(JComponent c) { 71 return new BasicColorChooserUI(); 72 } 73 74 protected AbstractColorChooserPanel[] createDefaultChoosers() { 75 AbstractColorChooserPanel[] panels = ColorChooserComponentFactory.getDefaultChooserPanels(); 76 return panels; 77 } 78 79 protected void uninstallDefaultChoosers() { 80 AbstractColorChooserPanel[] choosers = chooser.getChooserPanels(); 81 for( int i = 0 ; i < choosers.length; i++) { 82 chooser.removeChooserPanel( choosers[i] ); 83 } 84 } 85 86 public void installUI( JComponent c ) { 87 chooser = (JColorChooser)c; 88 89 super.installUI( c ); 90 91 installDefaults(); 92 installListeners(); 93 94 tabbedPane = new JTabbedPane(); 95 tabbedPane.setName("ColorChooser.tabPane"); 96 tabbedPane.setInheritsPopupMenu(true); 97 tabbedPane.getAccessibleContext().setAccessibleDescription(tabbedPane.getName()); 98 singlePanel = new JPanel(new CenterLayout()); 99 singlePanel.setName("ColorChooser.panel"); 100 singlePanel.setInheritsPopupMenu(true); 101 102 chooser.setLayout( new BorderLayout() ); 103 104 defaultChoosers = createDefaultChoosers(); 105 chooser.setChooserPanels(defaultChoosers); 106 107 previewPanelHolder = new JPanel(new CenterLayout()); 108 previewPanelHolder.setName("ColorChooser.previewPanelHolder"); 109 110 if (DefaultLookup.getBoolean(chooser, this, 111 "ColorChooser.showPreviewPanelText", true)) { 112 String previewString = UIManager.getString( 113 "ColorChooser.previewText", chooser.getLocale()); 114 previewPanelHolder.setBorder(new TitledBorder(previewString)); 115 } 116 previewPanelHolder.setInheritsPopupMenu(true); 117 118 installPreviewPanel(); 119 chooser.applyComponentOrientation(c.getComponentOrientation()); 120 } 121 122 public void uninstallUI( JComponent c ) { 123 chooser.remove(tabbedPane); 124 chooser.remove(singlePanel); 125 chooser.remove(previewPanelHolder); 126 127 uninstallDefaultChoosers(); 128 uninstallListeners(); 129 uninstallPreviewPanel(); 130 uninstallDefaults(); 131 132 previewPanelHolder = null; 133 previewPanel = null; 134 defaultChoosers = null; 135 chooser = null; 136 tabbedPane = null; 137 138 handler = null; 139 } 140 141 protected void installPreviewPanel() { 142 JComponent previewPanel = this.chooser.getPreviewPanel(); 143 if (previewPanel == null) { 144 previewPanel = ColorChooserComponentFactory.getPreviewPanel(); 145 } 146 else if (JPanel.class.equals(previewPanel.getClass()) && (0 == previewPanel.getComponentCount())) { 147 previewPanel = null; 148 } 149 this.previewPanel = previewPanel; 150 if (previewPanel != null) { 151 chooser.add(previewPanelHolder, BorderLayout.SOUTH); 152 previewPanel.setForeground(chooser.getColor()); 153 previewPanelHolder.add(previewPanel); 154 previewPanel.addMouseListener(getHandler()); 155 previewPanel.setInheritsPopupMenu(true); 156 } 157 } 158 159 /** 160 * Removes installed preview panel from the UI delegate. 161 * 162 * @since 1.7 163 */ 164 protected void uninstallPreviewPanel() { 165 if (this.previewPanel != null) { 166 this.previewPanel.removeMouseListener(getHandler()); 167 this.previewPanelHolder.remove(this.previewPanel); 168 } 169 this.chooser.remove(this.previewPanelHolder); 170 } 171 172 protected void installDefaults() { 173 LookAndFeel.installColorsAndFont(chooser, "ColorChooser.background", 174 "ColorChooser.foreground", 175 "ColorChooser.font"); 176 LookAndFeel.installProperty(chooser, "opaque", Boolean.TRUE); 177 TransferHandler th = chooser.getTransferHandler(); 178 if (th == null || th instanceof UIResource) { 179 chooser.setTransferHandler(defaultTransferHandler); 180 } 181 } 182 183 protected void uninstallDefaults() { 184 if (chooser.getTransferHandler() instanceof UIResource) { 185 chooser.setTransferHandler(null); 186 } 187 } 188 189 190 protected void installListeners() { 191 propertyChangeListener = createPropertyChangeListener(); 192 chooser.addPropertyChangeListener( propertyChangeListener ); 193 194 previewListener = getHandler(); 195 chooser.getSelectionModel().addChangeListener(previewListener); 196 } 197 198 private Handler getHandler() { 199 if (handler == null) { 200 handler = new Handler(); 201 } 202 return handler; 203 } 204 205 protected PropertyChangeListener createPropertyChangeListener() { 206 return getHandler(); 207 } 208 209 protected void uninstallListeners() { 210 chooser.removePropertyChangeListener( propertyChangeListener ); 211 chooser.getSelectionModel().removeChangeListener(previewListener); 212 previewListener = null; 213 } 214 215 private void selectionChanged(ColorSelectionModel model) { 216 JComponent previewPanel = this.chooser.getPreviewPanel(); 217 if (previewPanel != null) { 218 previewPanel.setForeground(model.getSelectedColor()); 219 previewPanel.repaint(); 220 } 221 AbstractColorChooserPanel[] panels = this.chooser.getChooserPanels(); 222 if (panels != null) { 223 for (AbstractColorChooserPanel panel : panels) { 224 if (panel != null) { 225 panel.updateChooser(); 226 } 227 } 228 } 229 } 230 231 private class Handler implements ChangeListener, MouseListener, 232 PropertyChangeListener { 233 // 234 // ChangeListener 235 // 236 public void stateChanged(ChangeEvent evt) { 237 selectionChanged((ColorSelectionModel) evt.getSource()); 238 } 239 240 // 241 // MouseListener 242 public void mousePressed(MouseEvent evt) { 243 if (chooser.getDragEnabled()) { 244 TransferHandler th = chooser.getTransferHandler(); 245 th.exportAsDrag(chooser, evt, TransferHandler.COPY); 246 } 247 } 248 public void mouseReleased(MouseEvent evt) {} 249 public void mouseClicked(MouseEvent evt) {} 250 public void mouseEntered(MouseEvent evt) {} 251 public void mouseExited(MouseEvent evt) {} 252 253 // 254 // PropertyChangeListener 255 // 256 public void propertyChange(PropertyChangeEvent evt) { 257 String prop = evt.getPropertyName(); 258 259 if (prop == JColorChooser.CHOOSER_PANELS_PROPERTY) { 260 AbstractColorChooserPanel[] oldPanels = 261 (AbstractColorChooserPanel[])evt.getOldValue(); 262 AbstractColorChooserPanel[] newPanels = 263 (AbstractColorChooserPanel[])evt.getNewValue(); 264 265 for (int i = 0; i < oldPanels.length; i++) { // remove old panels 266 Container wrapper = oldPanels[i].getParent(); 267 if (wrapper != null) { 268 Container parent = wrapper.getParent(); 269 if (parent != null) 270 parent.remove(wrapper); // remove from hierarchy 271 oldPanels[i].uninstallChooserPanel(chooser); // uninstall 272 } 273 } 274 275 int numNewPanels = newPanels.length; 276 if (numNewPanels == 0) { // removed all panels and added none 277 chooser.remove(tabbedPane); 278 return; 279 } 280 else if (numNewPanels == 1) { // one panel case 281 chooser.remove(tabbedPane); 282 JPanel centerWrapper = new JPanel( new CenterLayout() ); 283 centerWrapper.setInheritsPopupMenu(true); 284 centerWrapper.add(newPanels[0]); 285 singlePanel.add(centerWrapper, BorderLayout.CENTER); 286 chooser.add(singlePanel); 287 } 288 else { // multi-panel case 289 if ( oldPanels.length < 2 ) {// moving from single to multiple 290 chooser.remove(singlePanel); 291 chooser.add(tabbedPane, BorderLayout.CENTER); 292 } 293 294 for (int i = 0; i < newPanels.length; i++) { 295 JPanel centerWrapper = new JPanel( new CenterLayout() ); 296 centerWrapper.setInheritsPopupMenu(true); 297 String name = newPanels[i].getDisplayName(); 298 int mnemonic = newPanels[i].getMnemonic(); 299 centerWrapper.add(newPanels[i]); 300 tabbedPane.addTab(name, centerWrapper); 301 if (mnemonic > 0) { 302 tabbedPane.setMnemonicAt(i, mnemonic); 303 int index = newPanels[i].getDisplayedMnemonicIndex(); 304 if (index >= 0) { 305 tabbedPane.setDisplayedMnemonicIndexAt(i, index); 306 } 307 } 308 } 309 } 310 chooser.applyComponentOrientation(chooser.getComponentOrientation()); 311 for (int i = 0; i < newPanels.length; i++) { 312 newPanels[i].installChooserPanel(chooser); 313 } 314 } 315 else if (prop == JColorChooser.PREVIEW_PANEL_PROPERTY) { 316 uninstallPreviewPanel(); 317 installPreviewPanel(); 318 } 319 else if (prop == JColorChooser.SELECTION_MODEL_PROPERTY) { 320 ColorSelectionModel oldModel = (ColorSelectionModel) evt.getOldValue(); 321 oldModel.removeChangeListener(previewListener); 322 ColorSelectionModel newModel = (ColorSelectionModel) evt.getNewValue(); 323 newModel.addChangeListener(previewListener); 324 selectionChanged(newModel); 325 } 326 else if (prop == "componentOrientation") { 327 ComponentOrientation o = 328 (ComponentOrientation)evt.getNewValue(); 329 JColorChooser cc = (JColorChooser)evt.getSource(); 330 if (o != (ComponentOrientation)evt.getOldValue()) { 331 cc.applyComponentOrientation(o); 332 cc.updateUI(); 333 } 334 } 335 } 336 } 337 338 /** 339 * This class should be treated as a "protected" inner class. 340 * Instantiate it only within subclasses of {@code BasicColorChooserUI}. 341 */ 342 public class PropertyHandler implements PropertyChangeListener { 343 public void propertyChange(PropertyChangeEvent e) { 344 getHandler().propertyChange(e); 345 } 346 } 347 348 static class ColorTransferHandler extends TransferHandler implements UIResource { 349 350 ColorTransferHandler() { 351 super("color"); 352 } 353 } 354 }