1 /*
   2  * Copyright (c) 1998, 2015, 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.colorchooser;
  27 
  28 import java.awt.*;
  29 import java.beans.BeanProperty;
  30 import java.beans.PropertyChangeEvent;
  31 import java.beans.PropertyChangeListener;
  32 import javax.swing.*;
  33 
  34 /**
  35  * This is the abstract superclass for color choosers.  If you want to add
  36  * a new color chooser panel into a <code>JColorChooser</code>, subclass
  37  * this class.
  38  * <p>
  39  * <strong>Warning:</strong>
  40  * Serialized objects of this class will not be compatible with
  41  * future Swing releases. The current serialization support is
  42  * appropriate for short term storage or RMI between applications running
  43  * the same version of Swing.  As of 1.4, support for long term storage
  44  * of all JavaBeans&trade;
  45  * has been added to the <code>java.beans</code> package.
  46  * Please see {@link java.beans.XMLEncoder}.
  47  *
  48  * @author Tom Santos
  49  * @author Steve Wilson
  50  */
  51 @SuppressWarnings("serial") // Same-version serialization only
  52 public abstract class AbstractColorChooserPanel extends JPanel {
  53 
  54 
  55     /**
  56      * Identifies that the transparency of the color (alpha value) can be
  57      * selected
  58      */
  59     public static final String TRANSPARENCY_ENABLED_PROPERTY
  60             = "TransparencyEnabled";
  61 
  62     private final PropertyChangeListener enabledListener = new PropertyChangeListener() {
  63         public void propertyChange(PropertyChangeEvent event) {
  64             Object value = event.getNewValue();
  65             if (value instanceof Boolean) {
  66                 setEnabled((Boolean) value);
  67             }
  68         }
  69     };
  70 
  71     /**
  72      *
  73      */
  74     private JColorChooser chooser;
  75 
  76     /**
  77       * Invoked automatically when the model's state changes.
  78       * It is also called by <code>installChooserPanel</code> to allow
  79       * you to set up the initial state of your chooser.
  80       * Override this method to update your <code>ChooserPanel</code>.
  81       */
  82     public abstract void updateChooser();
  83 
  84     /**
  85      * Builds a new chooser panel.
  86      */
  87     protected abstract void buildChooser();
  88 
  89     /**
  90      * Returns a string containing the display name of the panel.
  91      * @return the name of the display panel
  92      */
  93     public abstract String getDisplayName();
  94 
  95     /**
  96      * Provides a hint to the look and feel as to the
  97      * <code>KeyEvent.VK</code> constant that can be used as a mnemonic to
  98      * access the panel. A return value &lt;= 0 indicates there is no mnemonic.
  99      * <p>
 100      * The return value here is a hint, it is ultimately up to the look
 101      * and feel to honor the return value in some meaningful way.
 102      * <p>
 103      * This implementation returns 0, indicating the
 104      * <code>AbstractColorChooserPanel</code> does not support a mnemonic,
 105      * subclasses wishing a mnemonic will need to override this.
 106      *
 107      * @return KeyEvent.VK constant identifying the mnemonic; &lt;= 0 for no
 108      *         mnemonic
 109      * @see #getDisplayedMnemonicIndex
 110      * @since 1.4
 111      */
 112     public int getMnemonic() {
 113         return 0;
 114     }
 115 
 116     /**
 117      * Provides a hint to the look and feel as to the index of the character in
 118      * <code>getDisplayName</code> that should be visually identified as the
 119      * mnemonic. The look and feel should only use this if
 120      * <code>getMnemonic</code> returns a value &gt; 0.
 121      * <p>
 122      * The return value here is a hint, it is ultimately up to the look
 123      * and feel to honor the return value in some meaningful way. For example,
 124      * a look and feel may wish to render each
 125      * <code>AbstractColorChooserPanel</code> in a <code>JTabbedPane</code>,
 126      * and further use this return value to underline a character in
 127      * the <code>getDisplayName</code>.
 128      * <p>
 129      * This implementation returns -1, indicating the
 130      * <code>AbstractColorChooserPanel</code> does not support a mnemonic,
 131      * subclasses wishing a mnemonic will need to override this.
 132      *
 133      * @return Character index to render mnemonic for; -1 to provide no
 134      *                   visual identifier for this panel.
 135      * @see #getMnemonic
 136      * @since 1.4
 137      */
 138     public int getDisplayedMnemonicIndex() {
 139         return -1;
 140     }
 141 
 142     /**
 143      * Returns the small display icon for the panel.
 144      * @return the small display icon
 145      */
 146     public abstract Icon getSmallDisplayIcon();
 147 
 148     /**
 149      * Returns the large display icon for the panel.
 150      * @return the large display icon
 151      */
 152     public abstract Icon getLargeDisplayIcon();
 153 
 154     /**
 155      * Invoked when the panel is added to the chooser.
 156      * If you override this, be sure to call <code>super</code>.
 157      *
 158      * @param enclosingChooser the chooser to which the panel is to be added
 159      * @exception RuntimeException  if the chooser panel has already been
 160      *                          installed
 161      */
 162     public void installChooserPanel(JColorChooser enclosingChooser) {
 163         if (chooser != null) {
 164             throw new RuntimeException ("This chooser panel is already installed");
 165         }
 166         chooser = enclosingChooser;
 167         chooser.addPropertyChangeListener("enabled", enabledListener);
 168         setEnabled(chooser.isEnabled());
 169         buildChooser();
 170         updateChooser();
 171     }
 172 
 173     /**
 174      * Invoked when the panel is removed from the chooser.
 175      * If override this, be sure to call <code>super</code>.
 176      *
 177      * @param enclosingChooser the chooser from which the panel is to be removed
 178      */
 179   public void uninstallChooserPanel(JColorChooser enclosingChooser) {
 180         chooser.removePropertyChangeListener("enabled", enabledListener);
 181         chooser = null;
 182     }
 183 
 184     /**
 185       * Returns the model that the chooser panel is editing.
 186       * @return the <code>ColorSelectionModel</code> model this panel
 187       *         is editing
 188       */
 189     public ColorSelectionModel getColorSelectionModel() {
 190         return (this.chooser != null)
 191                 ? this.chooser.getSelectionModel()
 192                 : null;
 193     }
 194 
 195     /**
 196      * Returns the color that is currently selected.
 197      * @return the <code>Color</code> that is selected
 198      */
 199     protected Color getColorFromModel() {
 200         ColorSelectionModel model = getColorSelectionModel();
 201         return (model != null)
 202                 ? model.getSelectedColor()
 203                 : null;
 204     }
 205 
 206     void setSelectedColor(Color color) {
 207         ColorSelectionModel model = getColorSelectionModel();
 208         if (model != null) {
 209             model.setSelectedColor(color);
 210         }
 211     }
 212 
 213     /**
 214      * Sets whether color chooser panel allows to select the transparency
 215      * (alpha value) of a color.
 216      * This method fires a property-changed event, using the string value of
 217      * {@code TRANSPARENCY_ENABLED_PROPERTY} as the name
 218      * of the property.
 219      *
 220      * <p>The value is a hint and may not be applicable to all types of chooser
 221      * panel.
 222      *
 223      * <p>The default value is {@code true}.
 224      *
 225      * @param b true if the transparency of a color can be selected
 226      * @see #isColorTransparencySelectionEnabled()
 227      */
 228     @BeanProperty(description
 229             = "Sets the transparency of a color selection on or off.")
 230     public void setColorTransparencySelectionEnabled(boolean b){
 231     }
 232 
 233     /**
 234      * Gets whether color chooser panel allows to select the transparency
 235      * (alpha value) of a color.
 236      *
 237      * @return true if the transparency of a color can be selected
 238      * @see #setColorTransparencySelectionEnabled(boolean)
 239      */
 240     public boolean isColorTransparencySelectionEnabled(){
 241         return true;
 242     }
 243 
 244     /**
 245      * Draws the panel.
 246      * @param g  the <code>Graphics</code> object
 247      */
 248     public void paint(Graphics g) {
 249         super.paint(g);
 250     }
 251 
 252     /**
 253      * Returns an integer from the defaults table. If <code>key</code> does
 254      * not map to a valid <code>Integer</code>, <code>default</code> is
 255      * returned.
 256      *
 257      * @param key  an <code>Object</code> specifying the int
 258      * @param defaultValue Returned value if <code>key</code> is not available,
 259      *                     or is not an Integer
 260      * @return the int
 261      */
 262     int getInt(Object key, int defaultValue) {
 263         Object value = UIManager.get(key, getLocale());
 264 
 265         if (value instanceof Integer) {
 266             return ((Integer)value).intValue();
 267         }
 268         if (value instanceof String) {
 269             try {
 270                 return Integer.parseInt((String)value);
 271             } catch (NumberFormatException nfe) {}
 272         }
 273         return defaultValue;
 274     }
 275 }