/*
* ColorIterator.java, something that walks over the Hue-Saturation-Brightness
* color space.
* Copyright (C) 2004 - 2011 Achim Westermann.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* If you modify or optimize the code in a useful way please let me know.
* Achim.Westermann@gmx.de
*
*/
package info.monitorenter.gui.util;
import java.awt.Color;
import java.util.Iterator;
import java.util.NoSuchElementException;
/**
* Iterator of the color space.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.10 $
*/
public class ColorIterator implements Iterator<Color> {
/**
* Just for protected internal float stepping.
* <p>
*
*
*/
public abstract static class ADefaultStepping implements ColorIterator.ISteppingModel {
/** The internal step width. */
protected double m_stepping;
/**
* Creates a stepper with 100 steps in the color space.
* <p>
*/
public ADefaultStepping() {
this(100);
}
/**
* Creates a stepper with the given step length.
* <p>
*
* @param steps
* the amount of steps to do in the color space.
*
*/
public ADefaultStepping(final int steps) {
this.setSteps(steps);
}
/**
* Too lazy to implement for each subclass. An overhead for newInstance()
* (return dynamic sub type) is paid here.
* <p>
*
* @return a clone of the stepper.
*/
@Override
public Object clone() {
ADefaultStepping result = null;
try {
result = (ADefaultStepping) super.clone();
result.m_stepping = this.m_stepping;
} catch (final Throwable f) {
f.printStackTrace();
}
return result;
}
/**
* @see info.monitorenter.gui.util.ColorIterator.ISteppingModel#setSteps(int)
*/
public void setSteps(final int steps) {
this.m_stepping = 1.0 / steps;
}
}
/**
* A stepping model that steps on the alpha channel of the HSB color space.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.10 $
*/
public static class AlphaStepper extends ColorIterator.ADefaultStepping {
/**
* Creates an instance with 100 alpha steps.
* <p>
*/
public AlphaStepper() {
super();
}
/**
* Creates an instance with the given stepping to go on the alpha channel of
* the color space.
* <p>
*
* @param steps
* the amount of steps to take on the saturation line.
*
*/
public AlphaStepper(final int steps) {
super(steps);
}
/**
* Performs a alpha step on the given ColorIterator's HSBColor.
* <p>
* The bounds are watched: if a step would cross 255, it will be continued
* beginning from 0. if a step would cross the alpha value of the
* ColorIterator's start alpha, the step will only go as far as this value.
* Else there would be problems with finding the end of the iteration.
* <p>
*
* @param tostep
* the color iterator to perform the step on.
*/
public void doStep(final ColorIterator tostep) {
double increment = tostep.m_iterate.m_alpha;
final double bound = tostep.m_startColor.m_alpha;
// + operations:
if (tostep.isAscendingDirection()) {
// naive step without watching bounds:
increment += this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_alpha < bound) && (increment > bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment > 255) {
// 2.b) if so, shift by the value range (overflow)
increment -= 255;
// 2.c) check if we crossed the bound now:
if (increment > bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
} else {
// - operations:
// naive step without watching bounds:
increment -= this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_alpha > bound) && (increment < bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment < 0) {
// 2.b) if so, shift by the value range (overflow)
increment += 255;
// 2.c) check if we crossed the bound now:
if (increment < bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
}
tostep.m_iterate.m_alpha = increment;
}
/**
* @see info.monitorenter.gui.util.ColorIterator.ADefaultStepping#setSteps(int)
*/
@Override
public void setSteps(final int steps) {
this.m_stepping = 255.0 / steps;
}
}
/**
* Base class for stepping models that may step in each direction of the Hue
* Saturation Luminance color space.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
*
* @version $Revision: 1.10 $
*/
public abstract static class APiggyBackStepper implements ColorIterator.ISteppingModel {
/** The hue stepper to use. */
protected HueStepper m_huestep;
/** The luminance stepper to use. */
protected LuminanceStepper m_lumstep;
/** The saturation stepper to use. */
protected SaturationStepper m_satstep;
/**
* Creates an instance with an amount of steps of 100 for hue, saturation
* and luminance.
* <p>
*/
public APiggyBackStepper() {
this(100, 100, 100);
}
/**
* Creates an instance that uses the given amount of steps for hue,
* luminance and saturation.
* <p>
*
* @param hueSteps
* the amount of steps on the hue line of the HSB color space.
*
* @param satSteps
* the amount of steps on the saturation line of the HSB color
* space.
*
* @param lumSteps
* the amount of steps on the luminance line of the HSB color
* space.
*
*/
public APiggyBackStepper(final int hueSteps, final int satSteps, final int lumSteps) {
this.m_huestep = new HueStepper(hueSteps);
this.m_satstep = new SaturationStepper(satSteps);
this.m_lumstep = new LuminanceStepper(lumSteps);
}
/**
* @see java.lang.Object#clone()
*/
@Override
public Object clone() {
try {
final APiggyBackStepper ret = (APiggyBackStepper) super.clone();
ret.m_huestep = (HueStepper) this.m_huestep.clone();
ret.m_satstep = (SaturationStepper) this.m_satstep.clone();
ret.m_lumstep = (LuminanceStepper) this.m_lumstep.clone();
return ret;
} catch (final CloneNotSupportedException cne) {
cne.printStackTrace(System.err);
// this should never happen!
throw new RuntimeException(cne);
}
}
/**
* @see info.monitorenter.gui.util.ColorIterator.ISteppingModel#setSteps(int)
*/
public void setSteps(final int steps) {
this.m_huestep.setSteps(steps);
this.m_lumstep.setSteps(steps);
this.m_satstep.setSteps(steps);
}
}
/**
* Performs hue steps until it has walked the whole hue line, then performs a
* saturation step to start with hue steps again. If the saturation steps have
* walked the whole saturation line, a luminance step is done before starting
* with hue steps again.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.10 $
*/
public static class HSBStepper extends ColorIterator.APiggyBackStepper {
/**
* Creates an instance that will perform 100 steps on the hue line then
* perform 100 steps on the saturation line and then 100 steps on the
* luminance line.
* <p>
*/
public HSBStepper() {
super();
}
/**
* @see info.monitorenter.gui.util.ColorIterator.ISteppingModel#doStep(info.monitorenter.gui.util.ColorIterator)
*/
public void doStep(final ColorIterator tostep) {
// technique: without testing the step is done
// this allows to restart with hue step even if start.hue==iterate.hue
// after having performed a step of different kind
this.m_huestep.doStep(tostep);
if (tostep.m_iterate.m_hue == tostep.m_startColor.m_hue) {
this.m_satstep.doStep(tostep);
if (tostep.m_iterate.m_sat == tostep.m_startColor.m_sat) {
this.m_lumstep.doStep(tostep);
}
}
}
}
/**
* Performs hue steps until it has walked the whole hue line, then performs a
* saturation step to start with hue steps again.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.10 $
*/
public static class HSStepper extends ColorIterator.APiggyBackStepper {
/**
* Creates an instance that will perform 100 steps on the hue line and then
* 100 steps on the saturation line.
* <p>
*/
public HSStepper() {
// nop
}
/**
* @see info.monitorenter.gui.util.ColorIterator.ISteppingModel#doStep(info.monitorenter.gui.util.ColorIterator)
*/
public void doStep(final ColorIterator tostep) {
// technique: without testing the step is done
// this allows to restart with huestep even if start.hue==iterate.hue
// after having performed a step of different kind
this.m_huestep.doStep(tostep);
if (tostep.m_iterate.m_hue == tostep.m_startColor.m_hue) {
this.m_satstep.doStep(tostep);
}
}
}
/**
* A stepper that walks along the hue line of the color space.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.10 $
*/
public static class HueStepper extends ColorIterator.ADefaultStepping {
/**
* Creates an instance with 100 steps left.
* <p>
*/
public HueStepper() {
super();
}
/**
* Creates a stepper with the given step length.
* <p>
*
* @param steps
* the amount of steps to take in the hue direction.
*
*/
public HueStepper(final int steps) {
super(steps);
}
/**
* Performs a hue step on the given ColorIterator's HSBColor.
* <p>
*
* The bounds are watched: if a hue step would cross 1.0 it will be
* continued beginning from 0. if a hue step would cross the hue value of
* the ColorIterator's start hue value, the step will only go as far as this
* value. Else there would be problems with finding the end of the
* iteration.
* <p>
*
* @param tostep
* the iterator to perform the step on.
*/
public void doStep(final ColorIterator tostep) {
double increment = tostep.m_iterate.m_hue;
final double bound = tostep.m_startColor.m_hue;
// + operations:
if (tostep.isAscendingDirection()) {
// naive step without watching bounds:
increment += this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_hue < bound) && (increment > bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment > 1.0) {
// 2.b) if so, shift by the value range (overflow)
increment -= 1.0;
// 2.c) check if we crossed the bound now:
if (increment > bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
} else {
// - operations:
// naive step without watching bounds:
increment -= this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_hue > bound) && (increment < bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment < 0) {
// 2.b) if so, shift by the value range (overflow)
increment += 1.0;
// 2.c) check if we crossed the bound now:
if (increment < bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
}
tostep.m_iterate.m_hue = increment;
}
}
/**
* Defines the strategy of walking through the HSB color space.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
*
* @version $Revision: 1.10 $
*/
public static interface ISteppingModel extends Cloneable {
/**
* Creates a clone of this stepper.
* <p>
*
* @return a clone of this stepper.
*/
public Object clone();
/**
* Performs a step on the given color iterator.
* <p>
*
* @param tostep
* the color iterator to perform a step on.
*/
public void doStep(final ColorIterator tostep);
/**
* Sets the amount of steps in the color space.
* <p>
*
* @param steps
* the amount of steps in the color space.
*/
public void setSteps(final int steps);
}
/**
* A stepping model that steps on the luminance line of the HSB color space.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.10 $
*/
public static class LuminanceStepper extends ColorIterator.ADefaultStepping {
/**
* Creates an instance with 100 luminance steps.
* <p>
*/
public LuminanceStepper() {
super();
}
/**
* Creates an instance with the given stepping to go on the luminance line
* of the color space.
* <p>
*
* @param steps
* the amount of steps to take in the luminance space.
*
*/
public LuminanceStepper(final int steps) {
super(steps);
}
/**
* Performs a luminance step on the given ColorIterator's HSBColor.
* <p>
*
* The bounds are watched: if a step would cross 1.0, it will be continued
* beginning from 0. if a step would cross the luminance value of the
* ColorIterator's start luminance, the step will only go as far as this
* value. Else there would be problems with finding the end of the
* iteration.
* <p>
*
* @param tostep
* the color iterator to perform the step on.
*/
public void doStep(final ColorIterator tostep) {
double increment = tostep.m_iterate.m_lum;
final double bound = tostep.m_startColor.m_lum;
// + operations:
if (tostep.isAscendingDirection()) {
// naive step without watching bounds:
increment += this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_lum < bound) && (increment > bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment > 1.0) {
// 2.b) if so, shift by the value range (overflow)
increment -= 1.0;
// 2.c) check if we crossed the bound now:
if (increment > bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
} else {
// - operations:
// naive step without watching bounds:
increment -= this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_lum > bound) && (increment < bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment < 0) {
// 2.b) if so, shift by the value range (overflow)
increment += 1.0;
// 2.c) check if we crossed the bound now:
if (increment < bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
}
tostep.m_iterate.m_lum = increment;
}
}
/**
* A stepping model that steps on the saturation line of the HSB color space.
* <p>
*
* @author <a href="mailto:Achim.Westermann@gmx.de">Achim Westermann </a>
*
* @version $Revision: 1.10 $
*/
public static class SaturationStepper extends ColorIterator.ADefaultStepping {
/**
* Creates an instance with 100 saturation steps.
* <p>
*/
public SaturationStepper() {
super();
}
/**
* Creates an instance with the given stepping to go on the saturation line
* of the color space.
* <p>
*
* @param steps
* the amount of steps to take on the saturation line.
*
*/
public SaturationStepper(final int steps) {
super(steps);
}
/**
* Performs a saturation step on the given ColorIterator's HSBColor.
* <p>
* The bounds are watched: if a step would cross 1.0, it will be continued
* beginning from 0. if a step would cross the saturation value of the
* ColorIterator's start saturation, the step will only go as far as this
* value. Else there would be problems with finding the end of the
* iteration.
* <p>
*
* @param tostep
* the color iterator to perform the step on.
*/
public void doStep(final ColorIterator tostep) {
double increment = tostep.m_iterate.m_sat;
final double bound = tostep.m_startColor.m_sat;
if (tostep.isAscendingDirection()) {
// + operations
// naive step without watching bounds:
increment += this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_sat < bound) && (increment > bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment > 1.0) {
// 2.b) if so, shift by the value range (overflow)
increment -= 1.0;
// 2.c) check if we crossed the bound now:
if (increment > bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
} else {
// - operations
// naive step without watching bounds:
increment -= this.m_stepping;
// 1) check if we crossed the bound:;
if ((tostep.m_iterate.m_sat > bound) && (increment < bound)) {
increment = bound;
} else {
// 2.a) check if we crossed the value range:
if (increment < 0.0) {
// 2.b) if so, shift by the value range (overflow)
increment += 1.0;
// 2.c) check if we crossed the bound now:
if (increment < bound) {
// this test is sufficient as we know that we
// started from lowest value due to the overflow
// and still are higher than bound.
increment = bound;
}
} else {
// Nothing because we were bigger than bound before
// the step and still did not hit the overflow!
}
}
}
tostep.m_iterate.m_sat = increment;
}
}
/**
* Main entry for a test application.
* <p>
*
* @param args
* ignored.
*/
public static void main(final String[] args) {
final javax.swing.JFrame frame = new javax.swing.JFrame(Messages.getString("ColorIterator.0")); //$NON-NLS-1$
final javax.swing.JPanel panel = new javax.swing.JPanel() {
/**
* Generated <code>serialVersionUID</code>.
*/
private static final long serialVersionUID = 3258408422146715703L;
private final ColorIterator m_color = new ColorIterator();
{
// System.out.println("start: " + color.start.toString());
// System.out.println("iterate: " + color.iterate.toString());
int wdt = 0;
while (this.m_color.hasNext()) {
wdt++;
this.m_color.next();
}
System.out
.println(Messages.getString("ColorIterator.1") + wdt + Messages.getString("ColorIterator.2")); //$NON-NLS-1$ //$NON-NLS-2$
System.out.println(Messages.getString("ColorIterator.3") + wdt); //$NON-NLS-1$
this.setSize(wdt, 100);
this.setPreferredSize(new java.awt.Dimension(wdt, 100));
this.setMinimumSize(new java.awt.Dimension(wdt, 100));
}
/**
* @see java.awt.Component#paint(java.awt.Graphics)
*/
@Override
public void paint(final java.awt.Graphics g) {
super.paint(g);
// refresh iterator
this.m_color.reset();
final int width = this.getWidth();
final int height = this.getHeight();
int pxdrawn = 0;
while (this.m_color.hasNext()) {
if (pxdrawn == width) {
break;
}
g.setColor(this.m_color.next());
g.drawLine(pxdrawn, 0, pxdrawn, height);
pxdrawn++;
}
}
};
final javax.swing.JScrollPane scroll = new javax.swing.JScrollPane(panel);
final java.awt.Container contentPane = frame.getContentPane();
contentPane.setLayout(new java.awt.BorderLayout());
contentPane.add(scroll, java.awt.BorderLayout.CENTER);
frame.setLocation(200, 200);
frame.setSize(new java.awt.Dimension(400, 100));
frame.addWindowListener(new java.awt.event.WindowAdapter() {
/**
* @see java.awt.event.WindowAdapter#windowClosing(java.awt.event.WindowEvent)
*/
@Override
public void windowClosing(final java.awt.event.WindowEvent e) {
System.exit(0);
}
});
frame.setResizable(true);
frame.setVisible(true);
}
/** Flag to control the direction of iteration. */
private boolean m_ascendingDirection = true;
/** Flag to show if more colors are iterateable. */
private boolean m_hasnext = true;
/**
* Flag to allow return the start color for the first step instead of stepping
* forward.
* <p>
*/
private boolean m_firstTime = true;
/** Reference to the currently iterated color. */
protected HSBColor m_iterate;
/**
* To allow clean reset of ColorIterator, also the SteppingModel has to be
* reset. This is done by a deep copy at construction time.
*/
private final ColorIterator.ISteppingModel m_resetModel;
/**
* The starting color which is also used to detect if a whole iteration has
* been performed.
*/
protected HSBColor m_startColor;
/** The stepping model that defines the path through the color space. */
private ColorIterator.ISteppingModel m_stepModel;
/**
* Creates an instance that starts with a red color and walks the hue line
* with a {@link ColorIterator.HueStepper}.
* <p>
*/
public ColorIterator() {
this(Color.RED, new HueStepper(1000));
}
/**
* Creates an instance that starts with the given color and uses the given
* stepper for iteration.
* <p>
*
* @param startColor
* the color to start the iteration with.
*
* @param stepper
* the stepping model to use.
*/
public ColorIterator(final Color startColor, final ColorIterator.ISteppingModel stepper) {
this.setStartColor(startColor);
this.m_stepModel = stepper;
this.m_resetModel = (ColorIterator.ISteppingModel) this.m_stepModel.clone();
this.m_firstTime = true;
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
final ColorIterator other = (ColorIterator) obj;
if (this.m_ascendingDirection != other.m_ascendingDirection) {
return false;
}
if (this.m_firstTime != other.m_firstTime) {
return false;
}
if (this.m_hasnext != other.m_hasnext) {
return false;
}
if (this.m_iterate == null) {
if (other.m_iterate != null) {
return false;
}
} else if (!this.m_iterate.equals(other.m_iterate)) {
return false;
}
if (this.m_resetModel == null) {
if (other.m_resetModel != null) {
return false;
}
} else if (!this.m_resetModel.equals(other.m_resetModel)) {
return false;
}
if (this.m_startColor == null) {
if (other.m_startColor != null) {
return false;
}
} else if (!this.m_startColor.equals(other.m_startColor)) {
return false;
}
if (this.m_stepModel == null) {
if (other.m_stepModel != null) {
return false;
}
} else if (!this.m_stepModel.equals(other.m_stepModel)) {
return false;
}
return true;
}
/**
* Returns the starting color which is also used to detect if a whole
* iteration has been performed.
* <p>
*
* @return the starting color which is also used to detect if a whole
* iteration has been performed.
*/
public final Color getStartColor() {
return this.m_startColor.getRGBColor();
}
/**
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (this.m_ascendingDirection ? 1231 : 1237);
result = prime * result + (this.m_firstTime ? 1231 : 1237);
result = prime * result + (this.m_hasnext ? 1231 : 1237);
result = prime * result + ((this.m_iterate == null) ? 0 : this.m_iterate.hashCode());
result = prime * result + ((this.m_resetModel == null) ? 0 : this.m_resetModel.hashCode());
result = prime * result + ((this.m_startColor == null) ? 0 : this.m_startColor.hashCode());
result = prime * result + ((this.m_stepModel == null) ? 0 : this.m_stepModel.hashCode());
return result;
}
/**
* Returns true if more colors are available.
* <p>
*
* @return true if more colors are available.
*
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext() {
return this.m_hasnext;
}
/**
* Returns the ascendingDirection.
* <p>
*
* @see #setAscendingDirection(boolean)
*
* @return the ascendingDirection
*/
public final boolean isAscendingDirection() {
return this.m_ascendingDirection;
}
/**
* Returns instances of java.awt.Color or throws a NoSuchElementException, if
* iterator has finished.
* <p>
*
* @return the next available Color.
*
* @throws NoSuchElementException
* if {@link #hasNext()} returns false.
*/
public Color next() throws NoSuchElementException {
if (!this.m_hasnext) {
throw new java.util.NoSuchElementException(Messages.getString("ColorIterator.4")); //$NON-NLS-1$
}
if (!this.m_firstTime) {
this.m_stepModel.doStep(this);
if (this.m_iterate.equals(this.m_startColor)) {
this.m_hasnext = false;
}
} else {
this.m_firstTime = false;
}
return this.m_iterate.getRGBColor();
}
/**
* Nothing is done here. Do you really want to remove a color from the color
* circle model?
* <p>
*/
public void remove() {
// nop
}
/**
* Resets the ColorIterator. It will be able to start a new iteration over the
* color space.
* <p>
*/
public void reset() {
this.m_iterate = (HSBColor) this.m_startColor.clone();
// also reset the SteppingModel!!!!
this.m_stepModel = (ColorIterator.ISteppingModel) this.m_resetModel.clone();
this.m_hasnext = true;
this.m_firstTime = true;
}
/**
* Sets whether the color space should be iterated in ascending direction (+
* operations) or descending direction(- operations).
* <p>
*
* @param ascendingDirection
* if true the color space will be iterated in ascending direction.
*/
public final void setAscendingDirection(final boolean ascendingDirection) {
this.m_ascendingDirection = ascendingDirection;
}
/**
* Sets the starting color which is also used to detect if a whole iteration
* has been performed.
* <p>
*
* @param startColor
* the starting color which is also used to detect if a whole
* iteration has been performed.
*/
public final void setStartColor(final Color startColor) {
this.m_startColor = HSBColor.rgbToHSB(startColor);
this.m_iterate = (HSBColor) this.m_startColor.clone();
}
/**
* Sets the amount of colors to iterate over.
* <p>
*
* @param steps
* the amount of steps to take in the color space.
*/
public void setSteps(final int steps) {
this.m_resetModel.setSteps(steps);
this.m_stepModel.setSteps(steps);
}
}