/*
* Created on 26.04.2005 for PIROL
*
* CVS header information:
* $RCSfile: ColorGenerator.java,v $
* $Revision: 1.19 $
* $Date: 2005/11/24 14:26:16 $
* $Source: D:/CVS/cvsrepo/pirolPlugIns/utilities/colors/ColorGenerator.java,v $
*/
package org.openjump.core.ui.color;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.openjump.core.apitools.CollectionsTools;
/**
* Class to generate a given number of color steps to
* cross fade from color A to color C (and optionally
* pass color B)
*
* @author Ole Rahn, Stefan Ostermann
* <br>
* <br>FH Osnabrück - University of Applied Sciences Osnabrück,
* <br>Project: PIROL (2005),
* <br>Subproject: Daten- und Wissensmanagement
*
* @version $Revision: 1.19 $
*
*/
public class ColorGenerator {
protected List inputColors = new ArrayList();
protected Color[] colorArray = null;
protected int steps = 0;
//protected PersonalLogger logger = new PersonalLogger(DebugUserIds.USER_Ole);
public static ColorGenerator getTrafficLightColors(int steps){
if (steps >= 3)
return new ColorGenerator(steps, Color.GREEN.darker(), Color.YELLOW.brighter(), Color.RED.darker());
return ColorGenerator.getGreenToRedColors(steps);
}
public static ColorGenerator getGreenToRedColors(int steps){
return new ColorGenerator(steps, Color.GREEN.darker(), Color.RED.darker());
}
public static ColorGenerator getRedToGreenColors(int steps){
return new ColorGenerator(steps, Color.RED.darker(), Color.GREEN.darker());
}
public static ColorGenerator getReverseTrafficLightColors(int steps){
if (steps >= 3)
return new ColorGenerator(steps, Color.RED.darker(), Color.YELLOW.brighter(), Color.GREEN.darker());
return ColorGenerator.getRedToGreenColors(steps);
}
public static ColorGenerator getBlueToRedColors(int steps){
return new ColorGenerator(steps, Color.BLUE, Color.RED);
}
/**
* For java2xml which needs an empty constructor.
*
*/
public ColorGenerator() {
}
/**
* this constructor is untested, yet
* (but there is no predictable reason, why it should not work...)
* @param steps number of colors wanted
* @param colors List containing java.awt.Color objects
*/
public ColorGenerator(int steps, List colors) {
super();
this.steps = steps - 1;
this.inputColors.addAll(colors);
this.fillColorArray();
}
/**
* this constructor is untested, yet
* (but there is no predictable reason, why it should not work...)
* @param steps number of colors wanted
* @param colors array containing java.awt.Color objects
*/
public ColorGenerator(int steps, Color[] colors) {
super();
this.steps = steps - 1;
CollectionsTools.addArrayToList( this.inputColors, colors );
this.fillColorArray();
}
public ColorGenerator(int steps, Color A, Color C) {
super();
this.steps = steps - 1;
this.inputColors.add( A );
this.inputColors.add( C );
this.fillColorArray();
}
public ColorGenerator(int steps, Color A, Color B, Color C) {
super();
this.steps = steps -1;
this.inputColors.add( A );
this.inputColors.add( B );
this.inputColors.add( C );
this.fillColorArray();
}
/**
*@return All generated colors in an object-array
*/
public Color[] getColorArray() {
return colorArray;
}
/**
*@return the given number of color steps
*/
public int getSteps() {
return steps + 1;
}
/**
*@param steps the number of color steps
*/
public void setSteps(int steps) {
this.steps = steps - 1;
this.fillColorArray();
}
/**
* Returns the nr-th color, generated by this class
*@param nr zero-based index of the color wanted
*@return Color or null if the given index is out-of-bounds
*/
public Color getColor(int nr){
if (nr < 0 || nr >= this.colorArray.length )
return null;
//logger.printDebug("color " + nr + ": " + this.colorArray[nr]);
return this.colorArray[nr];
}
/**
* Sets the nr-th color, originally generated by this class
*@param nr zero-based index of the color wanted
*/
protected void setColor(int nr, Color color){
if (nr < 0 || nr >= this.colorArray.length )
return ;
//logger.printDebug("color " + nr + ": " + this.colorArray[nr]);
this.colorArray[nr] = color;
}
/**
* method to actually generate the colors
*/
protected void fillColorArray(){
ArrayList colors = new ArrayList();
if (this.getSteps() > this.inputColors.size()){
int r = 0, g = 0, b = 0;
int rTarget = 0, gTarget = 0, bTarget = 0;
double rStep = 0, gStep = 0, bStep = 0;
double stepsToSwitch = (double)this.steps / (this.inputColors.size()-1);
int currentBaseColor = 0;
Color baseColor = (Color)this.inputColors.get(0);
Color nextColor = (Color)this.inputColors.get(1);
boolean switchR, switchG, switchB;
switchR = false;
switchG = false;
switchB = false;
r = baseColor.getRed();
g = baseColor.getGreen();
b = baseColor.getBlue();
rStep = Math.ceil((double)(nextColor.getRed()-baseColor.getRed()) / Math.round(stepsToSwitch));
gStep = Math.ceil((double)(nextColor.getGreen()-baseColor.getGreen()) / Math.round(stepsToSwitch));
bStep = Math.ceil((double)(nextColor.getBlue()-baseColor.getBlue()) / Math.round(stepsToSwitch));
rTarget = nextColor.getRed();
gTarget = nextColor.getGreen();
bTarget = nextColor.getBlue();
colors.add(baseColor);
for (int i=0; i<this.steps; i++){
if ( (r + rStep >= rTarget && rStep >= 0) || (r + rStep <= rTarget && rStep < 0)){
if (nextColor!=null){
switchR = true;
}
}
if ( (g + gStep >= gTarget && gStep >= 0) || (g + gStep <= gTarget && gStep < 0)){
if (nextColor!=null){
switchG = true;
}
}
if ( (b + bStep >= bTarget && bStep >= 0) || (b + bStep <= bTarget && bStep < 0)){
if (nextColor!=null){
switchB = true;
}
}
if (switchR && switchG && switchB){
// (this.inputColors.size() -1) - (currentBaseColor + 1) --> this.inputColors.size() - currentBaseColor
stepsToSwitch = (double)(this.steps - currentBaseColor) / Math.max(this.inputColors.size() - currentBaseColor, 1);
switchR = false;
switchG = false;
switchB = false;
rStep = (nextColor.getRed()-baseColor.getRed()) / Math.round(stepsToSwitch);
rTarget = nextColor.getRed();
gStep = (nextColor.getGreen()-baseColor.getGreen()) / Math.round(stepsToSwitch);
gTarget = nextColor.getGreen();
bStep = (nextColor.getBlue()-baseColor.getBlue()) / Math.round(stepsToSwitch);
bTarget = nextColor.getBlue();
currentBaseColor ++;
if (currentBaseColor < this.inputColors.size()){
baseColor = (Color)this.inputColors.get(currentBaseColor);
}
if (currentBaseColor < this.inputColors.size()-1){
nextColor = (Color)this.inputColors.get(currentBaseColor+1);
} else {
nextColor = null;
}
}
r += (int)Math.round(rStep);
r = Math.max(Math.min(r, 255), 0);
g += (int)Math.round(gStep);
g = Math.max(Math.min(g, 255), 0);
b += (int)Math.round(bStep);
b = Math.max(Math.min(b, 255), 0);
colors.add(new Color(r,g,b));
}
} else {
for (int i=0; i<this.getSteps(); i++){
colors.add(this.inputColors.get(i));
}
}
this.colorArray = (Color[])colors.toArray(new Color[0]);
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
public String toString() {
return "ColorGenerator";
}
public Color[] getInputColorsAsArray(){
return (Color[])this.inputColors.toArray(new Color[0]);
}
/**For java2xml
* @return Returns the inputColors.
*/
public Collection getXMLInputColors() {
return inputColors;
}
/**For java2xml
*
* @param color
*/
public void addXMLInputColor(Color color) {
this.inputColors.add(color);
}
/**
* For java2xml
*
* @return the number of steps to cross fade from color A to color C
*/
public int getStepsXML() {
return steps;
}
/**For java2xml
*
* @param steps
*/
public void setStepsXML(int steps) {
this.steps = steps;
this.fillColorArray();
}
}