0001: /*
0002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003: *
0004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005: *
0006: * The contents of this file are subject to the terms of either the GNU
0007: * General Public License Version 2 only ("GPL") or the Common
0008: * Development and Distribution License("CDDL") (collectively, the
0009: * "License"). You may not use this file except in compliance with the
0010: * License. You can obtain a copy of the License at
0011: * http://www.netbeans.org/cddl-gplv2.html
0012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013: * specific language governing permissions and limitations under the
0014: * License. When distributing the software, include this License Header
0015: * Notice in each file and include the License file at
0016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
0017: * particular file as subject to the "Classpath" exception as provided
0018: * by Sun in the GPL Version 2 section of the License file that
0019: * accompanied this code. If applicable, add the following below the
0020: * License Header, with the fields enclosed by brackets [] replaced by
0021: * your own identifying information:
0022: * "Portions Copyrighted [year] [name of copyright owner]"
0023: *
0024: * Contributor(s):
0025: *
0026: * The Original Software is NetBeans. The Initial Developer of the Original
0027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028: * Microsystems, Inc. All Rights Reserved.
0029: *
0030: * If you wish your version of this file to be governed by only the CDDL
0031: * or only the GPL Version 2, indicate your decision by adding
0032: * "[Contributor] elects to include this software in this distribution
0033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034: * single choice of license, a recipient has the option to distribute
0035: * your version of this file under either the CDDL, the GPL Version 2 or
0036: * to extend the choice of license to its licensees as provided above.
0037: * However, if you add GPL Version 2 code and therefore, elected the GPL
0038: * Version 2 license, then the option applies only if the new code is
0039: * made subject to such option by the copyright holder.
0040: */
0041:
0042: package org.netbeans.beaninfo.editors;
0043:
0044: import java.awt.BorderLayout;
0045: import java.awt.Color;
0046: import java.awt.Component;
0047: import java.awt.Dimension;
0048: import java.awt.Graphics;
0049: import java.awt.FontMetrics;
0050: import java.awt.Graphics2D;
0051: import java.awt.Rectangle;
0052: import java.awt.RenderingHints;
0053: import java.awt.SystemColor;
0054: import java.awt.Toolkit;
0055: import java.beans.PropertyChangeEvent;
0056: import java.beans.PropertyChangeListener;
0057: import java.beans.PropertyChangeSupport;
0058: import java.beans.PropertyEditor;
0059: import java.text.MessageFormat;
0060: import java.util.Enumeration;
0061: import java.util.HashMap;
0062: import java.util.Map;
0063: import javax.swing.border.EmptyBorder;
0064: import javax.swing.colorchooser.AbstractColorChooserPanel;
0065: import javax.swing.colorchooser.ColorSelectionModel;
0066: import javax.swing.colorchooser.DefaultColorSelectionModel;
0067: import javax.swing.event.*;
0068: import javax.swing.Icon;
0069: import javax.swing.JColorChooser;
0070: import javax.swing.JList;
0071: import javax.swing.JPanel;
0072: import javax.swing.JScrollPane;
0073: import javax.swing.ListCellRenderer;
0074: import javax.swing.UIDefaults;
0075: import javax.swing.UIManager;
0076: import org.netbeans.core.UIExceptions;
0077: import org.openide.explorer.propertysheet.editors.XMLPropertyEditor;
0078: import org.openide.util.NbBundle;
0079:
0080: /** A property editor for Color class.
0081: * (Final only for performance, can be unfinaled if desired).
0082: *
0083: * @author Jan Jancura, Ian Formanek
0084: */
0085: public final class ColorEditor implements PropertyEditor,
0086: XMLPropertyEditor {
0087:
0088: // static .....................................................................................
0089:
0090: /** AWT Palette mode. */
0091: public static final int AWT_PALETTE = 1;
0092: /** System Palette mode. */
0093: public static final int SYSTEM_PALETTE = 2;
0094: /** Swing Palette mode. */
0095: public static final int SWING_PALETTE = 3;
0096:
0097: /** Localized names of AWT colors. */
0098: /* package */static String awtColorNames[]; // for testing
0099:
0100: /** AWT colors used in AWT Palette. */
0101: private static final Color awtColors[] = { Color.white,
0102: Color.lightGray, Color.gray, Color.darkGray, Color.black,
0103: Color.red, Color.pink, Color.orange, Color.yellow,
0104: Color.green, Color.magenta, Color.cyan, Color.blue };
0105:
0106: /** Names of system colors. <em>Note:</em> not localizable,
0107: * those names corresponds to programatical names. */
0108: private static final String awtGenerate[] = { "white", "lightGray",
0109: "gray", "darkGray", // NOI18N
0110: "black", "red", "pink", "orange", "yellow", // NOI18N
0111: "green", "magenta", "cyan", "blue" }; // NOI18N
0112:
0113: /** Localized names of system colors. */
0114: private static String systemColorNames[];
0115:
0116: /** Names of system colors. <em>Note:</em> not localizable,
0117: * those names corresponds to programatical names. */
0118: private static final String systemGenerate[] = { "activeCaption",
0119: "activeCaptionBorder", // NOI18N
0120: "activeCaptionText", "control", "controlDkShadow", // NOI18N
0121: "controlHighlight", "controlLtHighlight", // NOI18N
0122: "controlShadow", "controlText", "desktop", // NOI18N
0123: "inactiveCaption", "inactiveCaptionBorder", // NOI18N
0124: "inactiveCaptionText", "info", "infoText", "menu", // NOI18N
0125: "menuText", "scrollbar", "text", "textHighlight", // NOI18N
0126: "textHighlightText", "textInactiveText", "textText", // NOI18N
0127: "window", "windowBorder", "windowText" }; // NOI18N
0128:
0129: /** System colors used in System Palette. */
0130: private static final Color systemColors[] = {
0131: SystemColor.activeCaption, SystemColor.activeCaptionBorder,
0132: SystemColor.activeCaptionText, SystemColor.control,
0133: SystemColor.controlDkShadow, SystemColor.controlHighlight,
0134: SystemColor.controlLtHighlight, SystemColor.controlShadow,
0135: SystemColor.controlText, SystemColor.desktop,
0136: SystemColor.inactiveCaption,
0137: SystemColor.inactiveCaptionBorder,
0138: SystemColor.inactiveCaptionText, SystemColor.info,
0139: SystemColor.infoText, SystemColor.menu,
0140: SystemColor.menuText, SystemColor.scrollbar,
0141: SystemColor.text, SystemColor.textHighlight,
0142: SystemColor.textHighlightText,
0143: SystemColor.textInactiveText, SystemColor.textText,
0144: SystemColor.window, SystemColor.windowBorder,
0145: SystemColor.windowText };
0146:
0147: /** Swing colors names and values are static and lazy initialized.
0148: * They are also cleared when l&f changes. */
0149: private static String swingColorNames[];
0150:
0151: /** Swing colors used in Swing Palette. */
0152: private static Color swingColors[];
0153:
0154: static final boolean GTK = "GTK".equals(UIManager.getLookAndFeel()
0155: .getID());//NOI18N
0156: static final boolean AQUA = "Aqua".equals(UIManager
0157: .getLookAndFeel().getID());//NOI18N
0158:
0159: private static final boolean antialias = Boolean
0160: .getBoolean("nb.cellrenderer.antialiasing") // NOI18N
0161: || Boolean.getBoolean("swing.aatext") // NOI18N
0162: || (GTK && gtkShouldAntialias()) // NOI18N
0163: || AQUA;
0164:
0165: private static Boolean gtkAA;
0166: private static Map hintsMap;
0167:
0168: // static initializer .........................................
0169:
0170: static {
0171: UIManager
0172: .addPropertyChangeListener(new PropertyChangeListener() {
0173: public void propertyChange(PropertyChangeEvent evt) {
0174: swingColorNames = null;
0175: swingColors = null;
0176: }
0177: });
0178:
0179: swingColorNames = null;
0180: swingColors = null;
0181: }
0182:
0183: // variables ..................................................................................
0184:
0185: /** Selected color. */
0186: private SuperColor super Color;
0187: /** Property change support. Helper field. */
0188: private PropertyChangeSupport support;
0189:
0190: /** Gets <code>staticChooser</code> instance. */
0191: public static JColorChooser getStaticChooser(ColorEditor ce) {
0192: JColorChooser staticChooser = new JColorChooser(
0193: new DefaultColorSelectionModel(Color.white) {
0194: public void setSelectedColor(Color color) {
0195: if (color instanceof SuperColor) {
0196: super .setSelectedColor((SuperColor) color);
0197: } else if (color instanceof Color) {
0198: super
0199: .setSelectedColor(new SuperColor(
0200: color));
0201: }
0202: }
0203: }) {
0204: public void setColor(Color c) {
0205: if (c == null)
0206: return;
0207: super .setColor(c);
0208: }
0209: };
0210: staticChooser.addChooserPanel(new NbColorChooserPanel(
0211: AWT_PALETTE, getAWTColorNames(), awtColors,
0212: getString("CTL_AWTPalette"), ce));
0213: initSwingConstants();
0214: staticChooser.addChooserPanel(new NbColorChooserPanel(
0215: SWING_PALETTE, swingColorNames, swingColors,
0216: getString("CTL_SwingPalette"), ce));
0217: staticChooser.addChooserPanel(new NbColorChooserPanel(
0218: SYSTEM_PALETTE, getSystemColorNames(), systemColors,
0219: getString("CTL_SystemPalette"), ce));
0220: return staticChooser;
0221: }
0222:
0223: // init .......................................................................................
0224:
0225: /** Creates color editor. */
0226: public ColorEditor() {
0227: support = new PropertyChangeSupport(this );
0228: }
0229:
0230: // main methods .......................................................................................
0231:
0232: /** Gets value. Implements <code>PropertyEditor</code> interface.
0233: * @return <code>Color</code> value or <code>null</code> */
0234: public Object getValue() {
0235: if (super Color != null) {
0236: if (super Color.getID() != null) {
0237: return super Color;
0238: } else {
0239: return super Color.getColor();
0240: }
0241:
0242: } else {
0243: return null;
0244: }
0245: }
0246:
0247: /** Sets value. Implements <code>PropertyEditor</code> interface.
0248: * @param object object to set, accepts <code>Color</code>
0249: * or <code>SuperColor<code> types */
0250: public void setValue(Object object) {
0251: if (object != null) {
0252: if (object instanceof SuperColor) {
0253: super Color = (SuperColor) object;
0254: } else if (object instanceof Color) {
0255: super Color = new SuperColor((Color) object);
0256: }
0257: } else {
0258: super Color = null;
0259: }
0260:
0261: support.firePropertyChange("", null, null); // NOI18N
0262: }
0263:
0264: /** Gets value as text. Implements <code>PropertyEditor</code> interface. */
0265: public String getAsText() {
0266: if (super Color == null)
0267: return "null"; // NOI18N
0268: return super Color.getAsText();
0269: }
0270:
0271: /** Sets value ad text. Implements <code>PropertyEditor</code> interface. */
0272: public void setAsText(String text) throws IllegalArgumentException {
0273: if (text == null) {
0274: throw new IllegalArgumentException("null parameter"); // NOI18N
0275: }
0276:
0277: text = text.trim();
0278:
0279: if ("null".equals(text)) { // NOI18N
0280: setValue(null);
0281: return;
0282: }
0283:
0284: try { // try to extract RGB values - represented as [r,g,b] or r,g,b
0285: int len = text.length();
0286: if (len > 0) {
0287: int start = -1;
0288: int end = -1;
0289:
0290: char c1 = text.charAt(0);
0291: char c2 = text.charAt(len - 1);
0292: if (c1 == '[' && c2 == ']') {
0293: start = 1;
0294: end = len - 1;
0295: } else if (c1 >= '0' && c1 <= '9' && c2 >= '0'
0296: && c2 <= '9') {
0297: start = 0;
0298: end = len;
0299: }
0300:
0301: if (start >= 0) {
0302: int index1 = text.indexOf(',');
0303: int index2 = index1 < 0 ? -1 : text.indexOf(',',
0304: index1 + 1);
0305:
0306: if (index1 >= 0 && index2 >= 0) {
0307: int red = Integer.parseInt(text.substring(
0308: start, index1).trim());
0309: int green = Integer.parseInt(text.substring(
0310: index1 + 1, index2).trim());
0311: int blue = Integer.parseInt(text.substring(
0312: index2 + 1, end).trim());
0313:
0314: try {
0315: setValue(new SuperColor(null, 0, new Color(
0316: red, green, blue)));
0317: return;
0318: } catch (IllegalArgumentException iaE) {
0319: UIExceptions.annotateUser(iaE, null, iaE
0320: .getLocalizedMessage(), null, null);
0321: throw iaE;
0322: }
0323: }
0324: }
0325: }
0326: } catch (NumberFormatException nfe) {
0327: // Ignore it and try out from palette's next.
0328: }
0329:
0330: int index;
0331: int palette = 0;
0332: Color color = null;
0333:
0334: if ((index = getIndex(getAWTColorNames(), text)) >= 0) {
0335: palette = AWT_PALETTE;
0336: color = awtColors[index];
0337: }
0338:
0339: if (index < 0
0340: && ((index = getIndex(getSystemColorNames(), text)) >= 0)) {
0341: palette = SYSTEM_PALETTE;
0342: color = systemColors[index];
0343: }
0344:
0345: if (index < 0) {
0346: initSwingConstants();
0347: if ((index = getIndex(swingColorNames, text)) >= 0) {
0348: palette = SWING_PALETTE;
0349: color = swingColors[index];
0350: }
0351: }
0352:
0353: if (index < 0) {
0354: String msg = MessageFormat.format(NbBundle.getMessage(
0355: ColorEditor.class, "FMT_IllegalEntry"),
0356: new Object[] { text });
0357: IllegalArgumentException iae = new IllegalArgumentException(
0358: text);
0359: UIExceptions.annotateUser(iae, text, msg, null, null);
0360: throw iae;
0361: }
0362:
0363: setValue(new SuperColor(text, palette, color));
0364: }
0365:
0366: /** Gets java inititalization string. Implements <code>PropertyEditor</code> interface. */
0367: public String getJavaInitializationString() {
0368: if (super Color == null)
0369: return "null"; // NOI18N
0370: if (super Color.getID() == null)
0371: return "new java.awt.Color(" + super Color.getRed() + ", "
0372: + super Color.getGreen() + // NOI18N
0373: ", " + super Color.getBlue() + ")"; // NOI18N
0374:
0375: switch (super Color.getPalette()) {
0376: default:
0377: case AWT_PALETTE:
0378: return "java.awt.Color."
0379: + awtGenerate[getIndex(getAWTColorNames(),
0380: super Color.getID())]; // NOI18N
0381: case SYSTEM_PALETTE:
0382: return "java.awt.SystemColor."
0383: + systemGenerate[getIndex(getSystemColorNames(),
0384: super Color.getID())]; // NOI18N
0385: case SWING_PALETTE:
0386: if (super Color.getID() == null)
0387: return "new java.awt.Color(" + super Color.getRed()
0388: + ", " + super Color.getGreen() + // NOI18N
0389: ", " + super Color.getBlue() + ")"; // NOI18N
0390: return "javax.swing.UIManager.getDefaults().getColor(\"" + // NOI18N
0391: super Color.getID() + "\")"; // NOI18N
0392: }
0393: }
0394:
0395: /** Get tags possible for choosing value. Implements <code>PropertyEditor</code> interface. */
0396: public String[] getTags() {
0397: if (super Color == null) {
0398: return getAWTColorNames();
0399: }
0400: switch (super Color.getPalette()) {
0401: case AWT_PALETTE:
0402: return getAWTColorNames();
0403: case SYSTEM_PALETTE:
0404: return getSystemColorNames();
0405: case SWING_PALETTE:
0406: initSwingConstants();
0407: return swingColorNames;
0408: default:
0409: return null;
0410: }
0411: }
0412:
0413: /** Insicates whether this editor is paintable. Implements <code>PropertyEditor</code> interface.
0414: * @return <code>true</code> */
0415: public boolean isPaintable() {
0416: return true;
0417: }
0418:
0419: /** Paints the current value. Implements <code>ProepertyEditor</code> interface. */
0420: public void paintValue(Graphics g, Rectangle rectangle) {
0421: int px;
0422:
0423: ((Graphics2D) g).setRenderingHints(getHints());
0424:
0425: if (this .super Color != null) {
0426: Color color = g.getColor();
0427: g.drawRect(rectangle.x, rectangle.y + rectangle.height / 2
0428: - 5, 10, 10);
0429: g.setColor(this .super Color);
0430: g.fillRect(rectangle.x + 1, rectangle.y + rectangle.height
0431: / 2 - 4, 9, 9);
0432: g.setColor(color);
0433: px = 18;
0434: } else
0435: px = 0;
0436:
0437: FontMetrics fm = g.getFontMetrics();
0438: g.drawString(getAsText(), rectangle.x + px, rectangle.y
0439: + (rectangle.height - fm.getHeight()) / 2
0440: + fm.getAscent());
0441: }
0442:
0443: /** Indicates whether this editor supports custom editing.
0444: * Implements <code>PropertyEditor</code> interface.
0445: * @return <code>true</code> */
0446: public boolean supportsCustomEditor() {
0447: return true;
0448: }
0449:
0450: /** Gets custom editor. Implements <code>PropertyEditor</code> interface.
0451: * *return <code>NbColorChooser</code> instance */
0452: public Component getCustomEditor() {
0453: return new NbColorChooser(this , getStaticChooser(this ));
0454: }
0455:
0456: /** Adds property change listener. */
0457: public void addPropertyChangeListener(
0458: PropertyChangeListener propertyChangeListener) {
0459: support.addPropertyChangeListener(propertyChangeListener);
0460: }
0461:
0462: /** Removes property change listner. */
0463: public void removePropertyChangeListener(
0464: PropertyChangeListener propertyChangeListener) {
0465: support.removePropertyChangeListener(propertyChangeListener);
0466: }
0467:
0468: // helper methods .......................................................................................
0469: /** Gets array of localized AWT color names. */
0470: private static synchronized String[] getAWTColorNames() {
0471: if (awtColorNames == null) {
0472: awtColorNames = new String[] { getString("LAB_White"),
0473: getString("LAB_LightGray"), getString("LAB_Gray"),
0474: getString("LAB_DarkGray"), getString("LAB_Black"),
0475: getString("LAB_Red"), getString("LAB_Pink"),
0476: getString("LAB_Orange"), getString("LAB_Yellow"),
0477: getString("LAB_Green"), getString("LAB_Magenta"),
0478: getString("LAB_Cyan"), getString("LAB_Blue") };
0479: }
0480:
0481: return awtColorNames;
0482: }
0483:
0484: /** Gets array of localize system color names. */
0485: private static synchronized String[] getSystemColorNames() {
0486: if (systemColorNames == null) {
0487: systemColorNames = new String[] {
0488: getString("LAB_ActiveCaption"),
0489: getString("LAB_ActiveCaptionBorder"),
0490: getString("LAB_ActiveCaptionText"),
0491: getString("LAB_Control"),
0492: getString("LAB_ControlDkShadow"),
0493: getString("LAB_ControlHighlight"),
0494: getString("LAB_ControlLtHighlight"),
0495: getString("LAB_ControlShadow"),
0496: getString("LAB_ControlText"),
0497: getString("LAB_Desktop"),
0498: getString("LAB_InactiveCaption"),
0499: getString("LAB_InactiveCaptionBorder"),
0500: getString("LAB_InactiveCaptionText"),
0501: getString("LAB_Info"), getString("LAB_InfoText"),
0502: getString("LAB_Menu"), getString("LAB_MenuText"),
0503: getString("LAB_Scrollbar"), getString("LAB_Text"),
0504: getString("LAB_TextHighlight"),
0505: getString("LAB_TextHighlightText"),
0506: getString("LAB_TextInactiveText"),
0507: getString("LAB_TextText"), getString("LAB_Window"),
0508: getString("LAB_WindowBorder"),
0509: getString("LAB_WindowText") };
0510: }
0511:
0512: return systemColorNames;
0513: }
0514:
0515: /** Gets localized string.
0516: * @param key key from bundle from the package like this source */
0517: private static String getString(String key) {
0518: return NbBundle.getBundle(ColorEditor.class).getString(key);
0519: }
0520:
0521: /** Gets index of name from array. */
0522: private static int getIndex(Object[] names, Object name) {
0523: for (int i = 0; i < names.length; i++) {
0524: if (name.equals(names[i])) {
0525: return i;
0526: }
0527: }
0528:
0529: return -1;
0530: }
0531:
0532: /** Initialized fields used in Swing Palette. */
0533: private static void initSwingConstants() {
0534: if (swingColorNames != null)
0535: return;
0536:
0537: UIDefaults def = UIManager.getDefaults();
0538: Enumeration e = def.keys();
0539:
0540: java.util.TreeSet<String> names = new java.util.TreeSet<String>();
0541:
0542: while (e.hasMoreElements()) {
0543: Object k = e.nextElement();
0544: if (!(k instanceof String))
0545: continue;
0546: Object v = def.get(k);
0547: if (!(v instanceof Color))
0548: continue;
0549: names.add((String) k);
0550: }
0551:
0552: swingColorNames = new String[names.size()];
0553: names.toArray(swingColorNames);
0554: swingColors = new Color[swingColorNames.length];
0555:
0556: int i, k = swingColorNames.length;
0557: for (i = 0; i < k; i++)
0558: swingColors[i] = (Color) def.get(swingColorNames[i]);
0559: }
0560:
0561: private SuperColor getSuperColor() {
0562: return super Color;
0563: }
0564:
0565: // innerclasses ............................................................................................
0566: /** Panel used as custom property editor. */
0567: private static class NbColorChooser extends JPanel implements
0568: ChangeListener {
0569: /** Color property editor */
0570: private final ColorEditor editor;
0571: /** Reference to model which holds the color selected in the color chooser */
0572: private final ColorSelectionModel selectionModel;
0573:
0574: static final long serialVersionUID = -6230228701104365037L;
0575:
0576: /** Creates new <code>NbColorChooser</code>. */
0577: public NbColorChooser(final ColorEditor editor,
0578: final JColorChooser chooser) {
0579: this .editor = editor;
0580: selectionModel = chooser.getSelectionModel();
0581: setLayout(new BorderLayout());
0582: add(chooser, BorderLayout.CENTER);
0583: chooser.setColor((Color) editor.getValue());
0584: selectionModel.addChangeListener(this );
0585:
0586: getAccessibleContext().setAccessibleDescription(
0587: getString("ACSD_CustomColorEditor"));
0588: }
0589:
0590: /** Overrides superclass method. Adds removing of change listener. */
0591: public void removeNotify() {
0592: super .removeNotify();
0593: selectionModel.removeChangeListener(this );
0594: }
0595:
0596: /** Overrides superclass method. Adds 50 pixels to each side. */
0597: public Dimension getPreferredSize() {
0598: Dimension s = super .getPreferredSize();
0599: return new Dimension(s.width + 50, s.height + 10);
0600: }
0601:
0602: /** Implementats <code>ChangeListener</code> interface */
0603: public void stateChanged(ChangeEvent evt) {
0604: editor.setValue(selectionModel.getSelectedColor());
0605: }
0606:
0607: } // End of class NbColorChooser.
0608:
0609: /** Color belonging to palette and keeping its ID. */
0610: static class SuperColor extends Color {
0611: /** generated Serialized Version UID */
0612: static final long serialVersionUID = 6147637669184334151L;
0613:
0614: /** ID of this color. */
0615: private String id = null;
0616: /** Palette where it belongs. */
0617: private int palette = 0;
0618:
0619: private Color color;
0620:
0621: SuperColor(Color color) {
0622: super (color.getRed(), color.getGreen(), color.getBlue());
0623: this .color = color;
0624:
0625: //jkozak: When user sets color by RGB values, maybe we shouldn't
0626: // change the color to AWT-Palette constant.
0627: /*
0628: int i = getIndex (ColorEditor.awtColors, color);
0629: if (i < 0) return;
0630: id = getAWTColorNames()[i];
0631: */
0632: }
0633:
0634: SuperColor(String id, int palette, Color color) {
0635: super (color.getRed(), color.getGreen(), color.getBlue());
0636: this .color = color;
0637: this .id = id;
0638: this .palette = palette;
0639: }
0640:
0641: /** Overrides the equals(Object obj) method of java.awt.Color */
0642: public boolean equals(Object obj) {
0643: boolean super Equals = super .equals(obj);
0644: String objID = null;
0645: int objPalette = -1;
0646:
0647: if (obj instanceof SuperColor) {
0648: objID = ((SuperColor) obj).getID();
0649: objPalette = ((SuperColor) obj).getPalette();
0650: } else
0651: return super Equals;
0652:
0653: if (objID != null) {
0654: return super Equals && objID.equals(getID())
0655: && (objPalette == getPalette());
0656: } else {
0657: return super Equals && (null == getID())
0658: && (objPalette == getPalette());
0659: }
0660: }
0661:
0662: /** Gets ID of this color. */
0663: private String getID() {
0664: return id;
0665: }
0666:
0667: /** Gets palette of this color. */
0668: private int getPalette() {
0669: return palette;
0670: }
0671:
0672: /** Returns original color object */
0673: private Color getColor() {
0674: return this .color;
0675: }
0676:
0677: /** Gets as text this color value. */
0678: private String getAsText() {
0679: if (id != null)
0680: return id;
0681: return "[" + getRed() + "," + getGreen() + "," + getBlue()
0682: + "]"; // NOI18N
0683: }
0684: } // End of class SuperColor.
0685:
0686: /** Color chooser panel which can be added into JColorChooser */
0687: private static final class NbColorChooserPanel extends
0688: AbstractColorChooserPanel implements ListSelectionListener {
0689: /** Generated Serialized Version UID */
0690: static final long serialVersionUID = -2792992315444428631L;
0691: /** List holding palette colors */
0692: private JList list;
0693:
0694: /** Arraay of names of colors. */
0695: String[] names;
0696: /** Arraay of colors. */
0697: Color[] colors;
0698: /** Palette type. */
0699: int palette;
0700: /** Current ColorEditor. */
0701: ColorEditor ce;
0702:
0703: /** Name for display of this chooser panel. */
0704: private String displayName;
0705:
0706: /** Constructs our chooser panel with specified
0707: * palette, names and colors to be shown in the list */
0708: NbColorChooserPanel(final int palette, final String[] names,
0709: final Color[] colors, final String displayName,
0710: final ColorEditor ce) {
0711: this .names = names;
0712: this .colors = colors;
0713: this .palette = palette;
0714: this .displayName = displayName;
0715: this .ce = ce;
0716: }
0717:
0718: /** Builds - creates a chooser */
0719: protected void buildChooser() {
0720: setLayout(new BorderLayout());
0721: add(BorderLayout.CENTER, new JScrollPane(list = new JList(
0722: names)));
0723: list.setCellRenderer(new MyListCellRenderer());
0724: list.addListSelectionListener(this );
0725:
0726: list.getAccessibleContext().setAccessibleName(displayName);
0727: }
0728:
0729: /** Get called when state of selected color changes */
0730: public void updateChooser() {
0731: SuperColor sc = ce.getSuperColor();
0732:
0733: if (sc != null && palette == sc.getPalette()) {
0734: int i = getIndex(names, sc.getID());
0735: list.setSelectedIndex(i);
0736: } else
0737: list.clearSelection();
0738: }
0739:
0740: /** @return display name of the chooser */
0741: public String getDisplayName() {
0742: return displayName;
0743: }
0744:
0745: /** No icon */
0746: public Icon getSmallDisplayIcon() {
0747: return null;
0748: }
0749:
0750: /** No icon */
0751: public Icon getLargeDisplayIcon() {
0752: return null;
0753: }
0754:
0755: /** ListSelectionListener interface implementation */
0756: public void valueChanged(ListSelectionEvent e) {
0757: if (!list.isSelectionEmpty()) {
0758: int i = list.getSelectedIndex();
0759: getColorSelectionModel().setSelectedColor(
0760: new SuperColor(names[i], palette, colors[i]));
0761: }
0762: }
0763:
0764: /** Setter for <code>color</code> property. */
0765: public void setColor(final Color newColor) {
0766: getColorSelectionModel().setSelectedColor(newColor);
0767: }
0768:
0769: /** Getter for <code>color</code> property. */
0770: public Color getColor() {
0771: return getColorFromModel();
0772: }
0773:
0774: /** Renderer for cell of the list showing palette colors */
0775: private final class MyListCellRenderer extends JPanel implements
0776: ListCellRenderer {
0777:
0778: /** Selected flag. */
0779: private boolean selected;
0780: /** Focus flag. */
0781: private boolean hasFocus;
0782: /** Selected index. */
0783: private int index;
0784:
0785: /** Generated serial version UID. */
0786: static final long serialVersionUID = -8877709520578055594L;
0787:
0788: /** Creates a new MyListCellRenderer */
0789: public MyListCellRenderer() {
0790: this .setOpaque(true);
0791: this .setBorder(new EmptyBorder(1, 1, 1, 1));
0792: }
0793:
0794: /** Overrides default preferredSize impl.
0795: * @return Standard method returned preferredSize
0796: * (depends on font size only).
0797: */
0798: @Override
0799: public Dimension getPreferredSize() {
0800: try {
0801: FontMetrics fontMetrics = this .getFontMetrics(this
0802: .getFont());
0803: return new Dimension(fontMetrics
0804: .stringWidth(names[index]) + 30,
0805: fontMetrics.getHeight() + 4);
0806: } catch (NullPointerException e) {
0807: return new Dimension(10, 10);
0808: }
0809: }
0810:
0811: /** Paints this component. */
0812: @Override
0813: public void paint(Graphics g) {
0814: ((Graphics2D) g).setRenderingHints(getHints());
0815:
0816: Dimension rectangle = this .getSize();
0817: Color color = g.getColor();
0818:
0819: if (selected) {
0820: g.setColor(UIManager
0821: .getColor("List.selectionBackground")); // NOI18N
0822: } else {
0823: g.setColor(UIManager.getColor("List.background")); // NOI18N
0824: }
0825:
0826: g.fillRect(0, 0, rectangle.width - 1,
0827: rectangle.height - 1);
0828:
0829: if (hasFocus) {
0830: g.setColor(Color.black);
0831: g.drawRect(0, 0, rectangle.width - 1,
0832: rectangle.height - 1);
0833: }
0834:
0835: g.setColor(Color.black);
0836: g.drawRect(6, rectangle.height / 2 - 5, 10, 10);
0837: g.setColor(colors[index]);
0838: g.fillRect(7, rectangle.height / 2 - 4, 9, 9);
0839:
0840: if (selected) {
0841: g.setColor(UIManager
0842: .getColor("List.selectionForeground")); // NOI18N
0843: } else {
0844: g.setColor(UIManager.getColor("List.foreground")); // NOI18N
0845: }
0846:
0847: FontMetrics fm = g.getFontMetrics();
0848: g.drawString(names[index], 22, (rectangle.height - fm
0849: .getHeight())
0850: / 2 + fm.getAscent());
0851: g.setColor(color);
0852: }
0853:
0854: /** This is the only method defined by ListCellRenderer. We just
0855: * reconfigure the Jlabel each time we're called.
0856: */
0857: public Component getListCellRendererComponent(JList list,
0858: Object value, // value to display
0859: int index, // cell index
0860: boolean isSelected, // is the cell selected
0861: boolean cellHasFocus // the list and the cell have the focus
0862: ) {
0863: this .index = index;
0864: selected = isSelected;
0865: hasFocus = cellHasFocus;
0866: getAccessibleContext().setAccessibleName(names[index]);
0867: return this ;
0868: }
0869: } // End of class MyListCellRenderer.
0870: } // End of class NbColorChooserPanel.
0871:
0872: //--------------------------------------------------------------------------
0873: // XMLPropertyEditor implementation
0874:
0875: /** Name of color element. */
0876: public static final String XML_COLOR = "Color"; // NOI18N
0877:
0878: /** Name of type attribute. */
0879: public static final String ATTR_TYPE = "type"; // NOI18N
0880: /** Name of red attribute. */
0881: public static final String ATTR_RED = "red"; // NOI18N
0882: /** Name of green attribute. */
0883: public static final String ATTR_GREEN = "green"; // NOI18N
0884: /** Name of blue attribute. */
0885: public static final String ATTR_BLUE = "blue"; // NOI18N
0886: /** Name of id attribute. */
0887: public static final String ATTR_ID = "id"; // NOI18N
0888: /** Name of palette attribute. */
0889: public static final String ATTR_PALETTE = "palette"; // NOI18N
0890:
0891: /** Value of palette. */
0892: public static final String VALUE_PALETTE = "palette"; // NOI18N
0893: /** Value of rgb. */
0894: public static final String VALUE_RGB = "rgb"; // NOI18N
0895: /** Null value. */
0896: public static final String VALUE_NULL = "null"; // NOI18N
0897:
0898: /** Called to load property value from specified XML subtree. If succesfully loaded,
0899: * Implements <code>XMLPropertyEditor</code> interface.
0900: * the value should be available via the getValue method.
0901: * An IOException should be thrown when the value cannot be restored from the specified XML element
0902: * @param element the XML DOM element representing a subtree of XML from which the value should be loaded
0903: * @exception IOException thrown when the value cannot be restored from the specified XML element
0904: */
0905: public void readFromXML(org.w3c.dom.Node element)
0906: throws java.io.IOException {
0907: if (!XML_COLOR.equals(element.getNodeName())) {
0908: throw new java.io.IOException();
0909: }
0910: org.w3c.dom.NamedNodeMap attributes = element.getAttributes();
0911: try {
0912: String type = attributes.getNamedItem(ATTR_TYPE)
0913: .getNodeValue();
0914: if (VALUE_NULL.equals(type)) {
0915: setValue(null);
0916: } else {
0917: String red = attributes.getNamedItem(ATTR_RED)
0918: .getNodeValue();
0919: String green = attributes.getNamedItem(ATTR_GREEN)
0920: .getNodeValue();
0921: String blue = attributes.getNamedItem(ATTR_BLUE)
0922: .getNodeValue();
0923: if (VALUE_PALETTE.equals(type)) {
0924: int palette = Integer.parseInt(attributes
0925: .getNamedItem(ATTR_PALETTE).getNodeValue());
0926: String id = attributes.getNamedItem(ATTR_ID)
0927: .getNodeValue();
0928: if (palette == AWT_PALETTE) { // old colors stored localized name of color, newer has original 'en' name
0929: int idx = getIndex(awtGenerate, id);
0930: id = idx >= 0 ? getAWTColorNames()[idx]
0931: : (getIndex(getAWTColorNames(), id) >= 0 ? id
0932: : null);
0933: }
0934: setValue(new SuperColor(id, palette, new Color(
0935: Integer.parseInt(red, 16), Integer
0936: .parseInt(green, 16), Integer
0937: .parseInt(blue, 16))));
0938: } else {
0939: setValue(new SuperColor(new Color(Integer.parseInt(
0940: red, 16), Integer.parseInt(green, 16),
0941: Integer.parseInt(blue, 16))));
0942: }
0943: }
0944: } catch (NullPointerException e) {
0945: throw new java.io.IOException();
0946: }
0947: }
0948:
0949: /** Called to store current property value into XML subtree. The property value should be set using the
0950: * Implemtns <code>XMLPropertyEdtitor</code> interface.
0951: * setValue method prior to calling this method.
0952: * @param doc The XML document to store the XML in - should be used for creating nodes only
0953: * @return the XML DOM element representing a subtree of XML from which the value should be loaded
0954: */
0955: public org.w3c.dom.Node storeToXML(org.w3c.dom.Document doc) {
0956: org.w3c.dom.Element el = doc.createElement(XML_COLOR);
0957: el.setAttribute(ATTR_TYPE, (super Color == null) ? VALUE_NULL
0958: : ((super Color.getID() == null) ? VALUE_RGB
0959: : VALUE_PALETTE));
0960: if (super Color != null) {
0961: el.setAttribute(ATTR_RED, Integer.toHexString(super Color
0962: .getRed()));
0963: el.setAttribute(ATTR_GREEN, Integer.toHexString(super Color
0964: .getGreen()));
0965: el.setAttribute(ATTR_BLUE, Integer.toHexString(super Color
0966: .getBlue()));
0967: if (super Color.getID() != null) {
0968: if (super Color.getPalette() == AWT_PALETTE) {
0969: el.setAttribute(ATTR_ID, awtGenerate[getIndex(
0970: getAWTColorNames(), super Color.getID())]);
0971: } else {
0972: el.setAttribute(ATTR_ID, super Color.getID());
0973: }
0974: el.setAttribute(ATTR_PALETTE, Integer
0975: .toString(super Color.getPalette()));
0976: }
0977: }
0978: return el;
0979: }
0980:
0981: public static final boolean gtkShouldAntialias() {
0982: if (gtkAA == null) {
0983: Object o = Toolkit.getDefaultToolkit().getDesktopProperty(
0984: "gnome.Xft/Antialias"); //NOI18N
0985: gtkAA = Boolean.valueOf(Integer.valueOf(1).equals(o));
0986: }
0987:
0988: return gtkAA.booleanValue();
0989: }
0990:
0991: // copied from openide/awt/HtmlLabelUI
0992: private static Map getHints() {
0993: if (hintsMap == null) {
0994: hintsMap = (Map) (Toolkit.getDefaultToolkit()
0995: .getDesktopProperty("awt.font.desktophints")); //NOI18N
0996: if (hintsMap == null) {
0997: hintsMap = new HashMap();
0998: if (antialias) {
0999: hintsMap.put(RenderingHints.KEY_TEXT_ANTIALIASING,
1000: RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
1001: }
1002: }
1003: }
1004: return hintsMap;
1005: }
1006: }
|