Frames | No Frames |
1: /* JColorChooser.java -- 2: Copyright (C) 2002, 2004 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.AWTError; 42: import java.awt.BorderLayout; 43: import java.awt.Color; 44: import java.awt.Component; 45: import java.awt.Dialog; 46: import java.awt.FlowLayout; 47: import java.awt.Frame; 48: import java.awt.event.ActionEvent; 49: import java.awt.event.ActionListener; 50: 51: import javax.accessibility.Accessible; 52: import javax.accessibility.AccessibleContext; 53: import javax.accessibility.AccessibleRole; 54: import javax.swing.colorchooser.AbstractColorChooserPanel; 55: import javax.swing.colorchooser.ColorSelectionModel; 56: import javax.swing.colorchooser.DefaultColorSelectionModel; 57: import javax.swing.plaf.ColorChooserUI; 58: 59: 60: /** 61: * A Swing widget that offers users different ways to 62: * select a color. By default, three different panels are presented to the 63: * user that are capable of changing the selected color. There are three ways 64: * to utilize JColorChooser. The first is to build a JColorChooser and add it 65: * to the content pane. The second is to use the createDialog method to 66: * create a JDialog that holds a JColorChooser. The third is to show a 67: * JColorChooser in a JDialog directly using the showDialog method. 68: * 69: * @author original author unknown 70: */ 71: public class JColorChooser extends JComponent implements Accessible 72: { 73: /** DOCUMENT ME! */ 74: private static final long serialVersionUID = 9168066781620640889L; 75: 76: /** 77: * Accessibility support for <code>JColorChooser</code>. 78: */ 79: protected class AccessibleJColorChooser 80: extends JComponent.AccessibleJComponent 81: { 82: /** DOCUMENT ME! */ 83: private static final long serialVersionUID = -2038297864782299082L; 84: 85: /** 86: * Constructor AccessibleJColorChooser 87: */ 88: protected AccessibleJColorChooser() 89: { 90: // Nothing to do here. 91: } 92: 93: /** 94: * getAccessibleRole 95: * 96: * @return AccessibleRole 97: */ 98: public AccessibleRole getAccessibleRole() 99: { 100: return AccessibleRole.COLOR_CHOOSER; 101: } // getAccessibleRole() 102: } // AccessibleJColorChooser 103: 104: /** The model used with the JColorChooser. */ 105: private ColorSelectionModel selectionModel; 106: 107: /** The preview panel associated with the JColorChooser. */ 108: private JComponent previewPanel; 109: 110: /** 111: * The set of AbstractColorChooserPanels associated with the JColorChooser. 112: */ 113: private AbstractColorChooserPanel[] chooserPanels; 114: 115: /** A Drag and Drop property. */ 116: private boolean dragEnabled; 117: 118: /** 119: * The property fired by the JColorChooser when the selectionModel property 120: * changes. 121: */ 122: public static final String SELECTION_MODEL_PROPERTY = "selectionModel"; 123: 124: /** 125: * The property fired by the JColorChooser when the previewPanel property 126: * changes. 127: */ 128: public static final String PREVIEW_PANEL_PROPERTY = "previewPanel"; 129: 130: /** 131: * The property fired by the JColorChooser when the chooserPanels property 132: * changes. 133: */ 134: public static final String CHOOSER_PANELS_PROPERTY = "chooserPanels"; 135: 136: /** accessibleContext */ 137: protected AccessibleContext accessibleContext; 138: 139: /** 140: * This method creates a new JColorChooser with the default initial color. 141: */ 142: public JColorChooser() 143: { 144: this(new DefaultColorSelectionModel()); 145: } // JColorChooser() 146: 147: /** 148: * This method creates a new JColorChooser with the given initial color. 149: * 150: * @param initial The initial color. 151: */ 152: public JColorChooser(Color initial) 153: { 154: this(new DefaultColorSelectionModel(initial)); 155: } // JColorChooser() 156: 157: /** 158: * This method creates a new JColorChooser with the given model. The model 159: * will dictate what the initial color for the JColorChooser is. 160: * 161: * @param model The Model to use with the JColorChooser. 162: */ 163: public JColorChooser(ColorSelectionModel model) 164: { 165: if (model == null) 166: model = new DefaultColorSelectionModel(); 167: selectionModel = model; 168: updateUI(); 169: } // JColorChooser() 170: 171: /** 172: * This method sets the current color for the JColorChooser. 173: * 174: * @param color The new color for the JColorChooser. 175: */ 176: public void setColor(Color color) 177: { 178: if (color != null) 179: selectionModel.setSelectedColor(color); 180: } // setColor() 181: 182: /** 183: * This method sets the current color for the JColorChooser using RGB 184: * values. 185: * 186: * @param r The red value. 187: * @param g The green value. 188: * @param b The blue value. 189: */ 190: public void setColor(int r, int g, int b) 191: { 192: selectionModel.setSelectedColor(new Color(r, g, b)); 193: } // setColor() 194: 195: /** 196: * This method sets the current color for the JColorChooser using the 197: * integer value. Bits 0-7 represent the blue value. Bits 8-15 represent 198: * the green value. Bits 16-23 represent the red value. 199: * 200: * @param color The new current color of the JColorChooser. 201: */ 202: public void setColor(int color) 203: { 204: setColor(new Color(color, false)); 205: } // setColor() 206: 207: /** 208: * This method shows a JColorChooser inside a JDialog. The JDialog will 209: * block until it is hidden. The JDialog comes with three buttons: OK, 210: * Cancel, and Reset. Pressing OK or Cancel hide the JDialog. Pressing 211: * Reset will reset the JColorChooser to its initial value. 212: * 213: * @param component The Component that parents the JDialog. 214: * @param title The title displayed in the JDialog. 215: * @param initial The initial color. 216: * 217: * @return The selected color. 218: */ 219: public static Color showDialog(Component component, String title, 220: Color initial) 221: { 222: JColorChooser choose = new JColorChooser(initial); 223: 224: JDialog dialog = createDialog(component, title, true, choose, null, null); 225: 226: dialog.getContentPane().add(choose); 227: dialog.pack(); 228: dialog.show(); 229: 230: return choose.getColor(); 231: } // showDialog() 232: 233: /** 234: * This is a helper method to make the given JDialog block until it is 235: * hidden. This is package-private to avoid an accessor method. 236: * 237: * @param dialog The JDialog to block. 238: */ 239: static void makeModal(JDialog dialog) 240: { 241: try 242: { 243: synchronized (dialog) 244: { 245: while (dialog.isVisible()) 246: dialog.wait(); 247: } 248: } 249: catch (InterruptedException e) 250: { 251: // TODO: Should this be handled? 252: } 253: } 254: 255: /** 256: * This is a helper method to find the first Frame or Dialog ancestor of the 257: * given Component. 258: * 259: * @param c The Component to find ancestors for. 260: * 261: * @return A Frame or Dialog ancestor. Null if none are found. 262: */ 263: private static Component findParent(Component c) 264: { 265: Component parent = SwingUtilities.getAncestorOfClass(Frame.class, c); 266: if (parent != null) 267: return parent; 268: parent = SwingUtilities.getAncestorOfClass(Dialog.class, c); 269: return parent; 270: } 271: 272: /** 273: * This method will take the given JColorChooser and place it in a JDialog 274: * with the given modal property. Three buttons are displayed in the 275: * JDialog: OK, Cancel and Reset. If OK or Cancel are pressed, the JDialog 276: * is hidden. If Reset is pressed, then the JColorChooser will take on its 277: * default color value. The given okListener will be registered to the OK 278: * button and the cancelListener will be registered to the Cancel button. 279: * If the modal property is set, then the JDialog will block until it is 280: * hidden. 281: * 282: * @param component The Component that will parent the JDialog. 283: * @param title The title displayed in the JDialog. 284: * @param modal The modal property. 285: * @param chooserPane The JColorChooser to place in the JDialog. 286: * @param okListener The ActionListener to register to the OK button. 287: * @param cancelListener The ActionListener to register to the Cancel 288: * button. 289: * 290: * @return A JDialog with the JColorChooser inside of it. 291: * 292: * @throws AWTError If the component is not a suitable parent. 293: */ 294: public static JDialog createDialog(Component component, String title, 295: boolean modal, JColorChooser chooserPane, 296: ActionListener okListener, 297: ActionListener cancelListener) 298: { 299: Component parent = findParent(component); 300: if (parent == null) 301: throw new AWTError("No suitable parent found for Component."); 302: JDialog dialog; 303: if (parent instanceof Frame) 304: dialog = new JDialog((Frame) parent, title, true); 305: else 306: dialog = new JDialog((Dialog) parent, title, true); 307: 308: dialog.getContentPane().setLayout(new BorderLayout()); 309: 310: JPanel panel = new JPanel(); 311: panel.setLayout(new FlowLayout()); 312: 313: ActionListener al = new DefaultOKCancelListener(dialog); 314: 315: JButton ok = new JButton("OK"); 316: ok.addActionListener(okListener); 317: ok.addActionListener(al); 318: 319: JButton cancel = new JButton("Cancel"); 320: cancel.addActionListener(cancelListener); 321: cancel.addActionListener(al); 322: 323: JButton reset = new JButton("Reset"); 324: reset.addActionListener(new DefaultResetListener(chooserPane)); 325: 326: dialog.getContentPane().add(chooserPane, BorderLayout.NORTH); 327: 328: panel.add(ok); 329: panel.add(cancel); 330: panel.add(reset); 331: 332: dialog.getContentPane().add(panel, BorderLayout.SOUTH); 333: 334: return dialog; 335: } // createDialog() 336: 337: /** 338: * This method returns the UI Component used for this JColorChooser. 339: * 340: * @return The UI Component for this JColorChooser. 341: */ 342: public ColorChooserUI getUI() 343: { 344: return (ColorChooserUI) ui; 345: } // getUI() 346: 347: /** 348: * This method sets the UI Component used for this JColorChooser. 349: * 350: * @param ui The UI Component to use with this JColorChooser. 351: */ 352: public void setUI(ColorChooserUI ui) 353: { 354: super.setUI(ui); 355: } // setUI() 356: 357: /** 358: * This method resets the UI Component property to the Look and Feel 359: * default. 360: */ 361: public void updateUI() 362: { 363: setUI((ColorChooserUI) UIManager.getUI(this)); 364: } 365: 366: /** 367: * This method returns a String identifier for the UI Class to be used with 368: * the JColorChooser. 369: * 370: * @return The String identifier for the UI Class. 371: */ 372: public String getUIClassID() 373: { 374: return "ColorChooserUI"; 375: } // getUIClassID() 376: 377: /** 378: * This method returns the current color for the JColorChooser. 379: * 380: * @return The current color for the JColorChooser. 381: */ 382: public Color getColor() 383: { 384: return selectionModel.getSelectedColor(); // TODO 385: } // getColor() 386: 387: /** 388: * This method changes the previewPanel property for the JTabbedPane. The 389: * previewPanel is responsible for indicating the current color of the 390: * JColorChooser. 391: * 392: * @param component The Component that will act as the previewPanel. 393: */ 394: public void setPreviewPanel(JComponent component) 395: { 396: if (component != previewPanel) 397: { 398: JComponent old = previewPanel; 399: previewPanel = component; 400: firePropertyChange(PREVIEW_PANEL_PROPERTY, old, previewPanel); 401: } 402: } // setPreviewPanel() 403: 404: /** 405: * This method returns the current previewPanel used with this 406: * JColorChooser. 407: * 408: * @return The current previewPanel. 409: */ 410: public JComponent getPreviewPanel() 411: { 412: return previewPanel; // TODO 413: } // getPreviewPanel() 414: 415: /** 416: * This method adds the given AbstractColorChooserPanel to the list of the 417: * JColorChooser's chooserPanels. 418: * 419: * @param panel The AbstractColorChooserPanel to add. 420: */ 421: public void addChooserPanel(AbstractColorChooserPanel panel) 422: { 423: if (panel == null) 424: return; 425: AbstractColorChooserPanel[] old = chooserPanels; 426: AbstractColorChooserPanel[] newPanels = 427: new AbstractColorChooserPanel[(old == null) ? 1 : old.length + 1]; 428: if (old != null) 429: System.arraycopy(old, 0, newPanels, 0, old.length); 430: newPanels[newPanels.length - 1] = panel; 431: chooserPanels = newPanels; 432: panel.installChooserPanel(this); 433: firePropertyChange(CHOOSER_PANELS_PROPERTY, old, newPanels); 434: } // addChooserPanel() 435: 436: /** 437: * This method removes the given AbstractColorChooserPanel from the 438: * JColorChooser's list of chooserPanels. 439: * 440: * @param panel The AbstractColorChooserPanel to remove. 441: * 442: * @return The AbstractColorChooserPanel that was removed. 443: */ 444: public AbstractColorChooserPanel removeChooserPanel(AbstractColorChooserPanel panel) 445: { 446: int index = -1; 447: for (int i = 0; i < chooserPanels.length; i++) 448: if (panel == chooserPanels[i]) 449: { 450: index = i; 451: break; 452: } 453: 454: if (index == -1) 455: return null; 456: 457: AbstractColorChooserPanel[] old = chooserPanels; 458: if (chooserPanels.length == 1) 459: chooserPanels = null; 460: else 461: { 462: AbstractColorChooserPanel[] newPanels = 463: new AbstractColorChooserPanel[chooserPanels.length - 1]; 464: System.arraycopy(chooserPanels, 0, newPanels, 0, index); 465: System.arraycopy(chooserPanels, index, newPanels, index - 1, 466: chooserPanels.length - index); 467: chooserPanels = newPanels; 468: } 469: panel.uninstallChooserPanel(this); 470: firePropertyChange(CHOOSER_PANELS_PROPERTY, old, chooserPanels); 471: return panel; 472: } 473: 474: /** 475: * This method sets the chooserPanels property for this JColorChooser. 476: * 477: * @param panels The new set of AbstractColorChooserPanels to use. 478: */ 479: public void setChooserPanels(AbstractColorChooserPanel[] panels) 480: { 481: if (panels != chooserPanels) 482: { 483: if (chooserPanels != null) 484: for (int i = 0; i < chooserPanels.length; i++) 485: if (chooserPanels[i] != null) 486: chooserPanels[i].uninstallChooserPanel(this); 487: 488: AbstractColorChooserPanel[] old = chooserPanels; 489: chooserPanels = panels; 490: 491: if (panels != null) 492: for (int i = 0; i < panels.length; i++) 493: if (panels[i] != null) 494: panels[i].installChooserPanel(this); 495: 496: firePropertyChange(CHOOSER_PANELS_PROPERTY, old, chooserPanels); 497: } 498: } // setChooserPanels() 499: 500: /** 501: * This method returns the AbstractColorChooserPanels used with this 502: * JColorChooser. 503: * 504: * @return The AbstractColorChooserPanels used with this JColorChooser. 505: */ 506: public AbstractColorChooserPanel[] getChooserPanels() 507: { 508: return chooserPanels; 509: } // getChooserPanels() 510: 511: /** 512: * This method returns the ColorSelectionModel used with this JColorChooser. 513: * 514: * @return The ColorSelectionModel. 515: */ 516: public ColorSelectionModel getSelectionModel() 517: { 518: return selectionModel; 519: } // getSelectionModel() 520: 521: /** 522: * This method sets the ColorSelectionModel to be used with this 523: * JColorChooser. 524: * 525: * @param model The ColorSelectionModel to be used with this JColorChooser. 526: * 527: * @throws AWTError If the given model is null. 528: */ 529: public void setSelectionModel(ColorSelectionModel model) 530: { 531: if (model == null) 532: throw new AWTError("ColorSelectionModel is not allowed to be null."); 533: selectionModel = model; 534: } // setSelectionModel() 535: 536: /** 537: * DOCUMENT ME! 538: * 539: * @return DOCUMENT ME! 540: */ 541: public boolean getDragEnabled() 542: { 543: return dragEnabled; 544: } 545: 546: /** 547: * DOCUMENT ME! 548: * 549: * @param b DOCUMENT ME! 550: */ 551: public void setDragEnabled(boolean b) 552: { 553: dragEnabled = b; 554: } 555: 556: /** 557: * This method returns a String describing the JColorChooser. 558: * 559: * @return A String describing the JColorChooser. 560: */ 561: protected String paramString() 562: { 563: return "JColorChooser"; 564: } // paramString() 565: 566: /** 567: * getAccessibleContext 568: * 569: * @return AccessibleContext 570: */ 571: public AccessibleContext getAccessibleContext() 572: { 573: if (accessibleContext == null) 574: accessibleContext = new AccessibleJColorChooser(); 575: 576: return accessibleContext; 577: } 578: 579: /** 580: * A helper class that hides a JDialog when the action is performed. 581: */ 582: static class DefaultOKCancelListener implements ActionListener 583: { 584: /** The JDialog to hide. */ 585: private JDialog dialog; 586: 587: /** 588: * Creates a new DefaultOKCancelListener with the given JDialog to hide. 589: * 590: * @param dialog The JDialog to hide. 591: */ 592: public DefaultOKCancelListener(JDialog dialog) 593: { 594: super(); 595: this.dialog = dialog; 596: } 597: 598: /** 599: * This method hides the JDialog when called. 600: * 601: * @param e The ActionEvent. 602: */ 603: public void actionPerformed(ActionEvent e) 604: { 605: dialog.hide(); 606: } 607: } 608: 609: /** 610: * This method resets the JColorChooser color to the initial color when the 611: * action is performed. 612: */ 613: static class DefaultResetListener implements ActionListener 614: { 615: /** The JColorChooser to reset. */ 616: private JColorChooser chooser; 617: 618: /** The initial color. */ 619: private Color init; 620: 621: /** 622: * Creates a new DefaultResetListener with the given JColorChooser. 623: * 624: * @param chooser The JColorChooser to reset. 625: */ 626: public DefaultResetListener(JColorChooser chooser) 627: { 628: super(); 629: this.chooser = chooser; 630: init = chooser.getColor(); 631: } 632: 633: /** 634: * This method resets the JColorChooser to its initial color. 635: * 636: * @param e The ActionEvent. 637: */ 638: public void actionPerformed(ActionEvent e) 639: { 640: chooser.setColor(init); 641: } 642: } 643: 644: }