All Downloads are FREE. Search and download functionalities are using the official Maven repository.

echopointng.util.ColorKit Maven / Gradle / Ivy

Go to download

Echo2 bundled with Echo2_Extras, Echo2_FileTransfer and echopointing and various improvements/bugfixes

There is a newer version: 2.0.4
Show newest version
package echopointng.util;
/* 
 * This file is part of the Echo Point Project.  This project is a collection
 * of Components that have extended the Echo Web Application Framework.
 *
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 */
import echopointng.util.collections.ConcurrentReaderHashMap;

import java.util.Map;

import nextapp.echo2.app.Color;
import nextapp.echo2.app.Component;

/**
 * A utility to class to help with Color manipulation
 *
 * @author Brad Baker 
 */
public class ColorKit {

	/** Array for acceptable Color Constant strings*/
	public static String ColorConstantStrings[] = {
			"Color.BLACK",		"BLACK",
			"Color.BLUE",		"BLUE",
			"Color.CYAN",		"CYAN",
			"Color.DARKGRAY",	"DARKGRAY",
			"Color.GREEN",		"GREEN",
			"Color.LIGHTGRAY",	"LIGHTGRAY",
			"Color.MAGENTA",	"MAGENTA",
			"Color.ORANGE",		"ORANGE",
			"Color.PINK",		"PINK",
			"Color.RED",		"RED",
			"Color.WHITE",		"WHITE",
			"Color.YELLOW",		"YELLOW",
			};

	/** An array for Color values matching ColorConstantStrings*/
	public static Color ColorConstantValues[] =
		{
			Color.BLACK,		Color.BLACK,
			Color.BLUE,			Color.BLUE,
			Color.CYAN,			Color.CYAN,
			Color.DARKGRAY,		Color.DARKGRAY,
			Color.GREEN,		Color.GREEN,
			Color.LIGHTGRAY,	Color.LIGHTGRAY,
			Color.MAGENTA,		Color.MAGENTA,
			Color.ORANGE,		Color.ORANGE,
			Color.PINK,			Color.PINK,
			Color.RED,			Color.RED,
			Color.WHITE,		Color.WHITE,
			Color.YELLOW,		Color.YELLOW,
			};
	
	/** 
	 * The default scale factor applied to the brighter and darker functions
	 */
	public static final double COLOR_FACTOR = 0.7;

	private static Map colorMap = new ConcurrentReaderHashMap();

	/** not instantiable */
	private ColorKit() {
	}
	
	/*
	 * POarse a string in the form #99999
	 */
	private static Color _parseHashHexString(String hasHexString) {
		StringBuffer sb = new StringBuffer(hasHexString.substring(1));
		while (sb.length() < 6) {
			sb.append("0");
		}
		String hex = sb.substring(0,6);
		int rgb = Integer.parseInt(hex,16);
		return new Color(rgb);
	}
	

	/*
	 * Create a zero fronted hex string
	 */
	private static String _toHexString(int i) {
		String hex = Integer.toHexString(i);
		if (hex.length() < 2)
			hex = "0" + hex;
		return hex.toUpperCase();
	}
	
	/*
	 * Returns true if the propertyValue is a valid representation of a base 10 Integer
	 * value.
	 */
	private static boolean _isInteger(String propertyValue) {
		try {
			Integer.parseInt(propertyValue.trim());
		} catch (NumberFormatException nfe) {
			return false;
		}
		return true;
	}
	
	/*
	 * Returns true if the propertyValue is a valid representation of a base 16 Integer
	 * value.
	 */
	private static boolean _isHexInteger(String propertyValue) {
		propertyValue = propertyValue.trim().toLowerCase();
		if (propertyValue.indexOf("0x") == 0)
			propertyValue = propertyValue.substring(2);

		try {
			Integer.parseInt(propertyValue, 16);
		} catch (NumberFormatException nfe) {
			return false;
		}
		return true;
	}
	
	/*
	 * Returns the index of the string in an array of strings, case insensitive
	 * or -1 if its not found
	 */
	private static int _arrayIndexOf(String s, String[] array) {
		if (array == null)
			return -1;
		for (int i = 0; i < array.length; i++) {
			if (s.equalsIgnoreCase(array[i]))
				return i;
		}
		return -1;
	}

	/**
	 * Creates a brighter version of this color.
	 * 

* This method applies a 0.7 scale factor to each of the three RGB * components of the color to create a brighter version of the same * color. Although brighter and darker are * inverse operations, the results of a series of invocations of * these two methods may be inconsistent because of rounding errors. * * @param color - the color to make brighter * @return a new Color object, a brighter version of the color. * */ public static Color brighter(Color color) { return brighter(color,COLOR_FACTOR); } /** * Creates a brighter version of this color, according to the provided * factor. *

* This method applies an the scale factor to each of the three RGB * components of the color to create a brighter version of the same * color. Although brighter and darker are * inverse operations, the results of a series of invocations of * these two methods may be inconsistent because of rounding errors. * * @param color - the color to make brighter * @param factor - the factor by which to make it brighter. * * @return a new Color object, a brighter version of the color. * */ public static Color brighter(Color color, double factor) { int r = color.getRed(); int g = color.getGreen(); int b = color.getBlue(); /* * 1. black.brighter() should return grey * 2. applying brighter to blue will always return blue, brighter * 3. non pure color (non zero rgb) will eventually return white */ int i = (int) (1.0 / (1.0 - factor)); if (r == 0 && g == 0 && b == 0) { return new Color(i, i, i); } if (r > 0 && r < i) r = i; if (g > 0 && g < i) g = i; if (b > 0 && b < i) b = i; return makeColor(Math.min((int) (r / factor), 255), Math.min((int) (g / factor), 255), Math.min((int) (b / factor), 255)); } /** * Creates a darker version of this color. *

* This method applies an arbitrary 0.7 scale factor to each of the three RGB * components of the color to create a darker version of the same * color. Although brighter and darker are * inverse operations, the results of a series of invocations of * these two methods may be inconsistent because of rounding errors. * * @param color - the color to make darker * @return a new Color object,a darker version of this color. * */ public static Color darker(Color color) { return darker(color,COLOR_FACTOR); } /** * Creates a darker version of this color, according to the provided * factor. *

* This method applies an the scale factor to each of the three RGB * components of the color to create a darker version of the same * color. Although brighter and darker are * inverse operations, the results of a series of invocations of * these two methods may be inconsistent because of rounding errors. * * @param color - the color to make darker * @param factor - the factor by whcih to make it darker. * @return a new Color object,a darker version of the color. * */ public static Color darker(Color color, double factor) { return makeColor(Math.max((int) (color.getRed() * factor), 0), Math.max((int) (color.getGreen() * factor), 0), Math.max((int) (color.getBlue() * factor), 0)); } /** * Searchs the heirarchy tree of the component and finds the first * non null background Color object. It will return * Color.WHITE if no ancestor components have * a background set, but in practice this is unlikely to be the case. * * @param comp - the component to start searching at * @return - the background color of the component or its parents * */ public static Color findBackground(Component comp) { while (comp != null) { Color clr = comp.getBackground(); if (clr != null) return clr; comp = comp.getParent(); } return Color.WHITE; } /** * Searchs the heirarchy tree of the component and finds the first * non null foreground Color object. It will return * Color.BLACK. if no ancestor components have * a background set, but in practice this is unlikely to be the case. * * @param comp - the component to start searching at * @return - the foreground color of the component or its parents */ public static Color findForeground(Component comp) { while (comp != null) { Color clr = comp.getForeground(); if (clr != null) return clr; comp = comp.getParent(); } return Color.BLACK; } /** * Returns the inversion of a color. * * @param color - the color to invert * @return the inverted color */ public static Color invertColor(Color color) { int r = Math.abs(255 - color.getRed()); int g = Math.abs(255 - color.getGreen()); int b = Math.abs(255 - color.getBlue()); return makeColor(r, g, b); } /** * Creates an java.awt.Color object from a nextapp.echo.Color object, or * uses the default AWT if the echoColor object is null * * @param echoColor - the nextapp.echo2.app.Color object to convert * @param defaultAwtColor - the AWT color to use if the echoColor is null * @return a new AWT color object * */ public static java.awt.Color makeAwtColor(Color echoColor, java.awt.Color defaultAwtColor) { if (echoColor == null) return defaultAwtColor; else return new java.awt.Color(echoColor.getRgb(), false); } /** * Returns the Hex W3C CSS color string for a given color * ie #rrggbb * * @param color - the color to convert to a W3C hex CSS string value * @return the W3C hex CSS string value */ public static String makeCSSColor(Color color) { StringBuffer b = new StringBuffer(); b.append("#"); b.append(makeHexColor(color)); return b.toString().toUpperCase(); } /** * Returns the Color in the form : color(r,g,b); * * @param color - the color to convert to a color string representation * @return the color string representation */ public static String makeColorString(Color color) { StringBuffer b = new StringBuffer(); b.append("color("); b.append(color.getRed()); b.append(","); b.append(color.getGreen()); b.append(","); b.append(color.getBlue()); b.append(")"); return b.toString(); } /** * Returns the Hex string for a given color for example 'rrggbb' * * Note it does NOT have the # character at the front * * @param color the color in question * @return the string in the form rrggbb */ public static String makeHexColor(Color color) { StringBuffer b = new StringBuffer(); b.append(_toHexString(color.getRed())); b.append(_toHexString(color.getGreen())); b.append(_toHexString(color.getBlue())); return b.toString().toLowerCase(); } /** * Returns a Color object from the string representation *

* The color string must be in the format :
* - #rrggbb where rr, gg, bb are hexidecimal integer values
* - rgb( r, g, b) where r,g,b are integer values
* - color( r, g, b) where r,g,b are integer values
* - null will return a null color *

* otherwise an IllegalArgumentException is thrown. *

* The results of these operations are cached in a static * cache, so that Color objects can be re-used. This is okay * since Color objects are immutable. * * @param colorString - the color string representation * @return a new Color object * * @throws IllegalArgumentException - if the string cannot be converted * to a color */ public static Color makeColor(String colorString) { if (colorString == null) throw new IllegalArgumentException("Illegal null color string"); colorString = colorString.trim().toLowerCase(); Color color = (Color) colorMap.get(colorString); if (color != null) return color; if (! isColor(colorString)) throw new IllegalArgumentException("Illegal color string" + colorString); String tokens[] = TokenizerKit.tokenize(colorString, "(,)"); if (tokens.length == 1) { int index = _arrayIndexOf(colorString, ColorConstantStrings); if (index != -1) color = ColorConstantValues[index]; } if (color == null) { if (colorString.indexOf('#') == 0) { color = _parseHashHexString(colorString); } else { int r = Integer.parseInt(tokens[1].trim()); int g = Integer.parseInt(tokens[2].trim()); int b = Integer.parseInt(tokens[3].trim()); color = new Color(r,g,b); } } colorMap.put(colorString, color); return color; } /** * Returns true if the propertyValue is a valid representation of a Color * value. *

* The allowable forms are :

* - colorconstant where colorconstant in (red,blue,green...) * - #rrggbb where rr, gg, bb are hexidecimal integer values
* - rgb( r, g, b) where r,g,b are integer values
* - color( r, g, b) where r,g,b are integer values
*/ public static boolean isColor(String colorString) { if (colorString == null) return false; colorString = colorString.trim(); String tokens[] = TokenizerKit.tokenize(colorString, "(,)"); if (tokens.length == 1) { if (_arrayIndexOf(colorString, ColorConstantStrings) != -1) return true; } if (colorString.indexOf('#') == 0) { return _isHexInteger(colorString.substring(1).trim()); } else if (colorString.indexOf("rgb(") == 0 || colorString.indexOf("color(") == 0) { if (tokens.length != 4) return false; String r = tokens[1].trim(); String g = tokens[2].trim(); String b = tokens[3].trim(); return _isInteger(r) && _isInteger(g) && _isInteger(b); } return false; } /** * Shortcut synonym for makeColor(colorString); *

* @see ColorKit#makeColor(String) */ public static Color clr(String colorString) { return makeColor(colorString); } /** * Shortcut synonym for makeColor(r,g,b); *

* @see ColorKit#makeColor(int, int, int) */ public static Color clr(int r, int g, int b) { return makeColor(r,g,b); } /** * Shortcut synonym for makeColor(rgb); *

* @see ColorKit#makeColor(int) */ public static Color clr(int rgb) { return makeColor(rgb); } /** * Returns a Color object from the red, green and blue integer values. *

* The results of these operations are cached in a static * cache, so that Color objects can be re-used. This is okay * since Color objects are immutable. * * @param r - the red color component * @param g - the green color component * @param b - the blue color component * @return a new Color object */ public static Color makeColor(int r, int g, int b) { StringBuffer buf = new StringBuffer(); buf.append('#'); buf.append(_toHexString(r)); buf.append(_toHexString(g)); buf.append(_toHexString(b)); // // since we know we have produced a correct // color string we can go direct to the cache! // String colorString = buf.toString().toLowerCase(); Color color = (Color) colorMap.get(colorString); if (color == null) { color = new Color(r,g,b); colorMap.put(colorString,color); } return color; } /** * Returns a Color object from the red, green and blue integer values. *

* The results of these operations are cached in a static * cache, so that Color objects can be re-used. This is okay * since Color objects are immutable. * * @param rgb - the red/blue/green integer color value * @return a new Color object */ public static Color makeColor(int rgb) { StringBuffer buf = new StringBuffer(); buf.append('#'); buf.append(_toHexString(rgb)); // // since we know we have produced a correct // color string we can go direct to the cache! // String colorString = buf.toString().toLowerCase(); Color color = (Color) colorMap.get(colorString); if (color == null) { color = new Color(rgb); colorMap.put(colorString,color); } return color; } /** * Tints a given color by a factor given in red, blue and green. *

* The red, green and blue arguments should be around 1.0 */ public static Color tint(Color clr, double red, double green, double blue) { double newRed = clr.getRed() * red; double newGreen = clr.getGreen() * green; double newBlue = clr.getBlue() * blue; double normFactor = Math.max(newRed, Math.max(newGreen, newBlue)) / 255; newRed /= normFactor; newGreen /= normFactor; newBlue /= normFactor; return makeColor((int)newRed, (int)newGreen, (int)newBlue); } /** swapRGB Operation - R = B, G = G, B = R */ public static final int SWAP_OP_BGR = 0; /** swapRGB Operation - R = B, G = R, B = G */ public static final int SWAP_OP_BRG = 1; /** swapRGB Operation - R = G, G = B, B = R */ public static final int SWAP_OP_GBR = 2; /** swapRGB Operation - R = G, G = R, B = B */ public static final int SWAP_OP_GRB = 3; /** swapRGB Operation - R = R, G = B, B = G */ public static final int SWAP_OP_RBG = 4; /** * This will swap the red/green/blue elements of a color * according to the swapOperation, which may be one of : *

    *
  • SWAP_OP_RBG
  • *
  • SWAP_OP_BGR
  • *
  • SWAP_OP_BRG
  • *
  • SWAP_OP_GRB
  • *
  • SWAP_OP_GBR
  • *
      * * @param swapColor - the color to swap the RGB elements * @param swapOperation - the operation to perform * @return - a new swapped Color or null if the swapColor was null. */ public static Color swapRGB(Color swapColor, int swapOperation) { if (swapColor == null) return swapColor; int r = swapColor.getRed(); int g = swapColor.getGreen(); int b = swapColor.getBlue(); switch (swapOperation) { case SWAP_OP_RBG: return makeColor(r,b,g); case SWAP_OP_BGR: return makeColor(b,g,r); case SWAP_OP_BRG: return makeColor(b,r,g); case SWAP_OP_GBR: return makeColor(g,b,r); case SWAP_OP_GRB: return makeColor(g,r,b); default : return swapColor; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy