001/* =========================================================== 002 * JFreeChart : a free chart library for the Java(tm) platform 003 * =========================================================== 004 * 005 * (C) Copyright 2000-present, by David Gilbert and Contributors. 006 * 007 * Project Info: http://www.jfree.org/jfreechart/index.html 008 * 009 * This library is free software; you can redistribute it and/or modify it 010 * under the terms of the GNU Lesser General Public License as published by 011 * the Free Software Foundation; either version 2.1 of the License, or 012 * (at your option) any later version. 013 * 014 * This library is distributed in the hope that it will be useful, but 015 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 016 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 017 * License for more details. 018 * 019 * You should have received a copy of the GNU Lesser General Public 020 * License along with this library; if not, write to the Free Software 021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 022 * USA. 023 * 024 * [Oracle and Java are registered trademarks of Oracle and/or its affiliates. 025 * Other names may be trademarks of their respective owners.] 026 * 027 * --------------- 028 * PaintUtils.java 029 * --------------- 030 * (C) Copyright 2000-present, by David Gilbert and Contributors. 031 * 032 * Original Author: David Gilbert; 033 * Contributors: -; 034 */ 035 036package org.jfree.chart.util; 037 038import java.awt.Color; 039import java.awt.GradientPaint; 040import java.awt.LinearGradientPaint; 041import java.awt.Paint; 042import java.awt.RadialGradientPaint; 043import java.lang.reflect.Field; 044import java.lang.reflect.Modifier; 045import java.util.Arrays; 046 047/** 048 * Utility code that relates to {@code Paint} objects. 049 */ 050public class PaintUtils { 051 052 /** 053 * Private constructor prevents object creation. 054 */ 055 private PaintUtils() { 056 } 057 058 /** 059 * Returns {@code true} if the two {@code Paint} objects are equal 060 * OR both {@code null}. This method handles 061 * {@code GradientPaint}, {@code LinearGradientPaint} and 062 * {@code RadialGradientPaint} as a special cases, since those classes do 063 * not override the {@code equals()} method. 064 * 065 * @param p1 paint 1 ({@code null} permitted). 066 * @param p2 paint 2 ({@code null} permitted). 067 * 068 * @return A boolean. 069 */ 070 public static boolean equal(Paint p1, Paint p2) { 071 if (p1 == p2) { 072 return true; 073 } 074 075 // handle cases where either or both arguments are null 076 if (p1 == null) { 077 return (p2 == null); 078 } 079 if (p2 == null) { 080 return false; 081 } 082 083 // handle GradientPaint as a special case... 084 if (p1 instanceof GradientPaint && p2 instanceof GradientPaint) { 085 GradientPaint gp1 = (GradientPaint) p1; 086 GradientPaint gp2 = (GradientPaint) p2; 087 return gp1.getColor1().equals(gp2.getColor1()) 088 && gp1.getColor2().equals(gp2.getColor2()) 089 && gp1.getPoint1().equals(gp2.getPoint1()) 090 && gp1.getPoint2().equals(gp2.getPoint2()) 091 && gp1.isCyclic() == gp2.isCyclic() 092 && gp1.getTransparency() == gp1.getTransparency(); 093 } else if (p1 instanceof LinearGradientPaint 094 && p2 instanceof LinearGradientPaint) { 095 LinearGradientPaint lgp1 = (LinearGradientPaint) p1; 096 LinearGradientPaint lgp2 = (LinearGradientPaint) p2; 097 return lgp1.getStartPoint().equals(lgp2.getStartPoint()) 098 && lgp1.getEndPoint().equals(lgp2.getEndPoint()) 099 && Arrays.equals(lgp1.getFractions(), lgp2.getFractions()) 100 && Arrays.equals(lgp1.getColors(), lgp2.getColors()) 101 && lgp1.getCycleMethod() == lgp2.getCycleMethod() 102 && lgp1.getColorSpace() == lgp2.getColorSpace() 103 && lgp1.getTransform().equals(lgp2.getTransform()); 104 } else if (p1 instanceof RadialGradientPaint 105 && p2 instanceof RadialGradientPaint) { 106 RadialGradientPaint rgp1 = (RadialGradientPaint) p1; 107 RadialGradientPaint rgp2 = (RadialGradientPaint) p2; 108 return rgp1.getCenterPoint().equals(rgp2.getCenterPoint()) 109 && rgp1.getRadius() == rgp2.getRadius() 110 && rgp1.getFocusPoint().equals(rgp2.getFocusPoint()) 111 && Arrays.equals(rgp1.getFractions(), rgp2.getFractions()) 112 && Arrays.equals(rgp1.getColors(), rgp2.getColors()) 113 && rgp1.getCycleMethod() == rgp2.getCycleMethod() 114 && rgp1.getColorSpace() == rgp2.getColorSpace() 115 && rgp1.getTransform().equals(rgp2.getTransform()); 116 } else { 117 return p1.equals(p2); 118 } 119 } 120 121 /** 122 * Converts a color into a string. If the color is equal to one of the 123 * defined constant colors, that name is returned instead. Otherwise the 124 * color is returned as hex-string. 125 * 126 * @param c the color. 127 * @return the string for this color. 128 */ 129 public static String colorToString(Color c) { 130 try { 131 Field[] fields = Color.class.getFields(); 132 for (int i = 0; i < fields.length; i++) { 133 Field f = fields[i]; 134 if (Modifier.isPublic(f.getModifiers()) 135 && Modifier.isFinal(f.getModifiers()) 136 && Modifier.isStatic(f.getModifiers())) { 137 final String name = f.getName(); 138 final Object oColor = f.get(null); 139 if (oColor instanceof Color) { 140 if (c.equals(oColor)) { 141 return name; 142 } 143 } 144 } 145 } 146 } catch (Exception e) { 147 // 148 } 149 150 // no defined constant color, so this must be a user defined color 151 final String color = Integer.toHexString(c.getRGB() & 0x00ffffff); 152 final StringBuilder retval = new StringBuilder(7); 153 retval.append("#"); 154 155 final int fillUp = 6 - color.length(); 156 for (int i = 0; i < fillUp; i++) { 157 retval.append("0"); 158 } 159 160 retval.append(color); 161 return retval.toString(); 162 } 163 164 /** 165 * Converts a given string into a color. 166 * 167 * @param value the string, either a name or a hex-string. 168 * @return the color. 169 */ 170 public static Color stringToColor(String value) { 171 if (value == null) { 172 return Color.BLACK; 173 } 174 try { 175 // get color by hex or octal value 176 return Color.decode(value); 177 } catch (NumberFormatException nfe) { 178 // if we can't decode lets try to get it by name 179 try { 180 // try to get a color by name using reflection 181 final Field f = Color.class.getField(value); 182 return (Color) f.get(null); 183 } catch (Exception ce) { 184 // if we can't get any color return black 185 return Color.BLACK; 186 } 187 } 188 } 189} 190