/*
* Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package javax.swing;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.colorchooser.*;
import javax.swing.plaf.ColorChooserUI;
import javax.accessibility.*;
import sun.swing.SwingUtilities2;
/**
* JColorChooser
provides a pane of controls designed to allow
* a user to manipulate and select a color.
* For information about using color choosers, see
* How to Use Color Choosers,
* a section in The Java Tutorial.
*
*
* * This class provides three levels of API: *
ActionListeners
can be specified to be invoked when
* the user presses one of the dialog buttons.
* JColorChooser
panes
* directly (within any container). PropertyChange
listeners
* can be added to detect when the current "color" property changes.
* * Warning: Swing is not thread safe. For more * information see Swing's Threading * Policy. *
* Warning:
* Serialized objects of this class will not be compatible with
* future Swing releases. The current serialization support is
* appropriate for short term storage or RMI between applications running
* the same version of Swing. As of 1.4, support for long term storage
* of all JavaBeans™
* has been added to the java.beans
package.
* Please see {@link java.beans.XMLEncoder}.
*
*
* @beaninfo
* attribute: isContainer false
* description: A component that supports selecting a Color.
*
*
* @author James Gosling
* @author Amy Fowler
* @author Steve Wilson
*/
public class JColorChooser extends JComponent implements Accessible {
/**
* @see #getUIClassID
* @see #readObject
*/
private static final String uiClassID = "ColorChooserUI";
private ColorSelectionModel selectionModel;
private JComponent previewPanel = ColorChooserComponentFactory.getPreviewPanel();
private AbstractColorChooserPanel[] chooserPanels = new AbstractColorChooserPanel[0];
private boolean dragEnabled;
/**
* The selection model property name.
*/
public static final String SELECTION_MODEL_PROPERTY = "selectionModel";
/**
* The preview panel property name.
*/
public static final String PREVIEW_PANEL_PROPERTY = "previewPanel";
/**
* The chooserPanel array property name.
*/
public static final String CHOOSER_PANELS_PROPERTY = "chooserPanels";
/**
* Shows a modal color-chooser dialog and blocks until the
* dialog is hidden. If the user presses the "OK" button, then
* this method hides/disposes the dialog and returns the selected color.
* If the user presses the "Cancel" button or closes the dialog without
* pressing "OK", then this method hides/disposes the dialog and returns
* null
.
*
* @param component the parent Component
for the dialog
* @param title the String containing the dialog's title
* @param initialColor the initial Color set when the color-chooser is shown
* @return the selected color or null
if the user opted out
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static Color showDialog(Component component,
String title, Color initialColor) throws HeadlessException {
final JColorChooser pane = new JColorChooser(initialColor != null?
initialColor : Color.white);
ColorTracker ok = new ColorTracker(pane);
JDialog dialog = createDialog(component, title, true, pane, ok, null);
dialog.addComponentListener(new ColorChooserDialog.DisposeOnClose());
dialog.show(); // blocks until user brings dialog down...
return ok.getColor();
}
/**
* Creates and returns a new dialog containing the specified
* ColorChooser
pane along with "OK", "Cancel", and "Reset"
* buttons. If the "OK" or "Cancel" buttons are pressed, the dialog is
* automatically hidden (but not disposed). If the "Reset"
* button is pressed, the color-chooser's color will be reset to the
* color which was set the last time show
was invoked on the
* dialog and the dialog will remain showing.
*
* @param c the parent component for the dialog
* @param title the title for the dialog
* @param modal a boolean. When true, the remainder of the program
* is inactive until the dialog is closed.
* @param chooserPane the color-chooser to be placed inside the dialog
* @param okListener the ActionListener invoked when "OK" is pressed
* @param cancelListener the ActionListener invoked when "Cancel" is pressed
* @return a new dialog containing the color-chooser pane
* @exception HeadlessException if GraphicsEnvironment.isHeadless()
* returns true.
* @see java.awt.GraphicsEnvironment#isHeadless
*/
public static JDialog createDialog(Component c, String title, boolean modal,
JColorChooser chooserPane, ActionListener okListener,
ActionListener cancelListener) throws HeadlessException {
Window window = JOptionPane.getWindowForComponent(c);
ColorChooserDialog dialog;
if (window instanceof Frame) {
dialog = new ColorChooserDialog((Frame)window, title, modal, c, chooserPane,
okListener, cancelListener);
} else {
dialog = new ColorChooserDialog((Dialog)window, title, modal, c, chooserPane,
okListener, cancelListener);
}
dialog.getAccessibleContext().setAccessibleDescription(title);
return dialog;
}
/**
* Creates a color chooser pane with an initial color of white.
*/
public JColorChooser() {
this(Color.white);
}
/**
* Creates a color chooser pane with the specified initial color.
*
* @param initialColor the initial color set in the chooser
*/
public JColorChooser(Color initialColor) {
this( new DefaultColorSelectionModel(initialColor) );
}
/**
* Creates a color chooser pane with the specified
* ColorSelectionModel
.
*
* @param model the ColorSelectionModel
to be used
*/
public JColorChooser(ColorSelectionModel model) {
selectionModel = model;
updateUI();
dragEnabled = false;
}
/**
* Returns the L&F object that renders this component.
*
* @return the ColorChooserUI
object that renders
* this component
*/
public ColorChooserUI getUI() {
return (ColorChooserUI)ui;
}
/**
* Sets the L&F object that renders this component.
*
* @param ui the ColorChooserUI
L&F object
* @see UIDefaults#getUI
*
* @beaninfo
* bound: true
* hidden: true
* description: The UI object that implements the color chooser's LookAndFeel.
*/
public void setUI(ColorChooserUI ui) {
super.setUI(ui);
}
/**
* Notification from the UIManager
that the L&F has changed.
* Replaces the current UI object with the latest version from the
* UIManager
.
*
* @see JComponent#updateUI
*/
public void updateUI() {
setUI((ColorChooserUI)UIManager.getUI(this));
}
/**
* Returns the name of the L&F class that renders this component.
*
* @return the string "ColorChooserUI"
* @see JComponent#getUIClassID
* @see UIDefaults#getUI
*/
public String getUIClassID() {
return uiClassID;
}
/**
* Gets the current color value from the color chooser.
* By default, this delegates to the model.
*
* @return the current color value of the color chooser
*/
public Color getColor() {
return selectionModel.getSelectedColor();
}
/**
* Sets the current color of the color chooser to the specified color.
* The ColorSelectionModel
will fire a ChangeEvent
* @param color the color to be set in the color chooser
* @see JComponent#addPropertyChangeListener
*
* @beaninfo
* bound: false
* hidden: false
* description: The current color the chooser is to display.
*/
public void setColor(Color color) {
selectionModel.setSelectedColor(color);
}
/**
* Sets the current color of the color chooser to the
* specified RGB color. Note that the values of red, green,
* and blue should be between the numbers 0 and 255, inclusive.
*
* @param r an int specifying the amount of Red
* @param g an int specifying the amount of Green
* @param b an int specifying the amount of Blue
* @exception IllegalArgumentException if r,g,b values are out of range
* @see java.awt.Color
*/
public void setColor(int r, int g, int b) {
setColor(new Color(r,g,b));
}
/**
* Sets the current color of the color chooser to the
* specified color.
*
* @param c an integer value that sets the current color in the chooser
* where the low-order 8 bits specify the Blue value,
* the next 8 bits specify the Green value, and the 8 bits
* above that specify the Red value.
*/
public void setColor(int c) {
setColor((c >> 16) & 0xFF, (c >> 8) & 0xFF, c & 0xFF);
}
/**
* Sets the dragEnabled
property,
* which must be true
to enable
* automatic drag handling (the first part of drag and drop)
* on this component.
* The transferHandler
property needs to be set
* to a non-null
value for the drag to do
* anything. The default value of the dragEnabled
* property
* is false
.
*
*
*
* When automatic drag handling is enabled,
* most look and feels begin a drag-and-drop operation
* when the user presses the mouse button over the preview panel.
* Some look and feels might not support automatic drag and drop;
* they will ignore this property. You can work around such
* look and feels by modifying the component
* to directly call the exportAsDrag
method of a
* TransferHandler
.
*
* @param b the value to set the dragEnabled
property to
* @exception HeadlessException if
* b
is true
and
* GraphicsEnvironment.isHeadless()
* returns true
*
* @since 1.4
*
* @see java.awt.GraphicsEnvironment#isHeadless
* @see #getDragEnabled
* @see #setTransferHandler
* @see TransferHandler
*
* @beaninfo
* description: Determines whether automatic drag handling is enabled.
* bound: false
*/
public void setDragEnabled(boolean b) {
if (b && GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
dragEnabled = b;
}
/**
* Gets the value of the dragEnabled
property.
*
* @return the value of the dragEnabled
property
* @see #setDragEnabled
* @since 1.4
*/
public boolean getDragEnabled() {
return dragEnabled;
}
/**
* Sets the current preview panel.
* This will fire a PropertyChangeEvent
for the property
* named "previewPanel".
*
* @param preview the JComponent
which displays the current color
* @see JComponent#addPropertyChangeListener
*
* @beaninfo
* bound: true
* hidden: true
* description: The UI component which displays the current color.
*/
public void setPreviewPanel(JComponent preview) {
if (previewPanel != preview) {
JComponent oldPreview = previewPanel;
previewPanel = preview;
firePropertyChange(JColorChooser.PREVIEW_PANEL_PROPERTY, oldPreview, preview);
}
}
/**
* Returns the preview panel that shows a chosen color.
*
* @return a JComponent
object -- the preview panel
*/
public JComponent getPreviewPanel() {
return previewPanel;
}
/**
* Adds a color chooser panel to the color chooser.
*
* @param panel the AbstractColorChooserPanel
to be added
*/
public void addChooserPanel( AbstractColorChooserPanel panel ) {
AbstractColorChooserPanel[] oldPanels = getChooserPanels();
AbstractColorChooserPanel[] newPanels = new AbstractColorChooserPanel[oldPanels.length+1];
System.arraycopy(oldPanels, 0, newPanels, 0, oldPanels.length);
newPanels[newPanels.length-1] = panel;
setChooserPanels(newPanels);
}
/**
* Removes the Color Panel specified.
*
* @param panel a string that specifies the panel to be removed
* @return the color panel
* @exception IllegalArgumentException if panel is not in list of
* known chooser panels
*/
public AbstractColorChooserPanel removeChooserPanel( AbstractColorChooserPanel panel ) {
int containedAt = -1;
for (int i = 0; i < chooserPanels.length; i++) {
if (chooserPanels[i] == panel) {
containedAt = i;
break;
}
}
if (containedAt == -1) {
throw new IllegalArgumentException("chooser panel not in this chooser");
}
AbstractColorChooserPanel[] newArray = new AbstractColorChooserPanel[chooserPanels.length-1];
if (containedAt == chooserPanels.length-1) { // at end
System.arraycopy(chooserPanels, 0, newArray, 0, newArray.length);
}
else if (containedAt == 0) { // at start
System.arraycopy(chooserPanels, 1, newArray, 0, newArray.length);
}
else { // in middle
System.arraycopy(chooserPanels, 0, newArray, 0, containedAt);
System.arraycopy(chooserPanels, containedAt+1,
newArray, containedAt, (chooserPanels.length - containedAt - 1));
}
setChooserPanels(newArray);
return panel;
}
/**
* Specifies the Color Panels used to choose a color value.
*
* @param panels an array of AbstractColorChooserPanel
* objects
*
* @beaninfo
* bound: true
* hidden: true
* description: An array of different chooser types.
*/
public void setChooserPanels( AbstractColorChooserPanel[] panels) {
AbstractColorChooserPanel[] oldValue = chooserPanels;
chooserPanels = panels;
firePropertyChange(CHOOSER_PANELS_PROPERTY, oldValue, panels);
}
/**
* Returns the specified color panels.
*
* @return an array of AbstractColorChooserPanel
objects
*/
public AbstractColorChooserPanel[] getChooserPanels() {
return chooserPanels;
}
/**
* Returns the data model that handles color selections.
*
* @return a ColorSelectionModel
object
*/
public ColorSelectionModel getSelectionModel() {
return selectionModel;
}
/**
* Sets the model containing the selected color.
*
* @param newModel the new ColorSelectionModel
object
*
* @beaninfo
* bound: true
* hidden: true
* description: The model which contains the currently selected color.
*/
public void setSelectionModel(ColorSelectionModel newModel ) {
ColorSelectionModel oldModel = selectionModel;
selectionModel = newModel;
firePropertyChange(JColorChooser.SELECTION_MODEL_PROPERTY, oldModel, newModel);
}
/**
* See readObject
and writeObject
in
* JComponent
for more
* information about serialization in Swing.
*/
private void writeObject(ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
if (getUIClassID().equals(uiClassID)) {
byte count = JComponent.getWriteObjCounter(this);
JComponent.setWriteObjCounter(this, --count);
if (count == 0 && ui != null) {
ui.installUI(this);
}
}
}
/**
* Returns a string representation of this JColorChooser
.
* This method
* is intended to be used only for debugging purposes, and the
* content and format of the returned string may vary between
* implementations. The returned string may be empty but may not
* be null
.
*
* @return a string representation of this JColorChooser
*/
protected String paramString() {
StringBuffer chooserPanelsString = new StringBuffer("");
for (int i=0; i