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