package com.positive.charts.plot;
import java.awt.Paint;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import com.positive.charts.block.RectangleInsets;
import com.positive.charts.data.util.RectangleAnchor;
import com.positive.charts.event.MarkerChangeEvent;
import com.positive.charts.event.MarkerChangeListener;
import com.positive.charts.util.LengthAdjustmentType;
import com.positive.charts.util.Stroke;
import com.positive.charts.util.TextAnchor;
/**
* The base class for markers that can be added to plots to highlight a value or
* range of values.
*/
// TODO : Create initializers
public class Marker {
/** Storage for registered change listeners. */
private transient final ListenerList listenerList;
private int alpha;
private Stroke stroke;
private Color paint;
private String label;
private RectangleAnchor labelAnchor;
private Font labelFont;
private Color labelPaint;
private RectangleInsets labelOffset;
private LengthAdjustmentType labelOffsetType;
private TextAnchor labelTextAnchor;
private Color outlinePaint;
private Stroke outlineStroke;
/**
* Constructs a new marker.
*
* @param paint
* the paint (<code>null</code> not permitted).
* @param stroke
* the stroke (<code>null</code> not permitted).
* @param outlinePaint
* the outline paint (<code>null</code> permitted).
* @param outlineStroke
* the outline stroke (<code>null</code> permitted).
* @param alpha
* the alpha transparency (must be in the range 0.0f to 1.0f).
*
* @throws IllegalArgumentException
* if <code>paint</code> or <code>stroke</code> is
* <code>null</code>, or <code>alpha</code> is not in the
* specified range.
*/
protected Marker(final Color paint, final Stroke stroke,
final Color outlinePaint, final Stroke outlineStroke,
final int alpha) {
if (paint == null) {
throw new IllegalArgumentException("Null 'paint' argument.");
}
if (stroke == null) {
throw new IllegalArgumentException("Null 'stroke' argument.");
}
if ((alpha < 0.0f) || (alpha > 1.0f)) {
throw new IllegalArgumentException(
"The 'alpha' value must be in the range 0.0f to 1.0f");
}
this.paint = paint;
this.stroke = stroke;
this.outlinePaint = outlinePaint;
this.outlineStroke = outlineStroke;
this.alpha = alpha;
this.labelAnchor = RectangleAnchor.TOP_LEFT;
this.labelOffset = new RectangleInsets(3, 3, 3, 3);
this.labelOffsetType = LengthAdjustmentType.CONTRACT;
this.labelTextAnchor = TextAnchor.CENTER;
this.listenerList = new ListenerList();
}
/**
* Registers an object for notification of changes to the marker.
*
* @param listener
* the object to be registered.
*/
public void addChangeListener(final MarkerChangeListener listener) {
this.listenerList.add(listener);
}
/**
* Returns the alpha transparency.
*
* @return The alpha transparency.
*
* @see #setAlpha(int)
*/
public int getAlpha() {
return this.alpha;
}
/**
* Returns the label (if <code>null</code> no label is displayed).
*
* @return The label (possibly <code>null</code>).
*
* @see #setLabel(String)
*/
public String getLabel() {
return this.label;
}
/**
* Returns the label anchor. This defines the position of the label anchor,
* relative to the bounds of the marker.
*
* @return The label anchor (never <code>null</code>).
*
* @see #setLabelAnchor(RectangleAnchor)
*/
public RectangleAnchor getLabelAnchor() {
return this.labelAnchor;
}
/**
* Returns the label font.
*
* @return The label font (never <code>null</code>).
*
* @see #setLabelFont(Font)
*/
public Font getLabelFont() {
return this.labelFont;
}
/**
* Returns the label offset.
*
* @return The label offset (never <code>null</code>).
*
* @see #setLabelOffset(RectangleInsets)
*/
public RectangleInsets getLabelOffset() {
return this.labelOffset;
}
/**
* Returns the label offset type.
*
* @return The type (never <code>null</code>).
*
* @see #setLabelOffsetType(LengthAdjustmentType)
*/
public LengthAdjustmentType getLabelOffsetType() {
return this.labelOffsetType;
}
/**
* Returns the label paint.
*
* @return The label paint (never </code>null</code>).
*
* @see #setLabelPaint(Color)
*/
public Color getLabelPaint() {
return this.labelPaint;
}
/**
* Returns the label text anchor.
*
* @return The label text anchor (never <code>null</code>).
*
* @see #setLabelTextAnchor(TextAnchor)
*/
public TextAnchor getLabelTextAnchor() {
return this.labelTextAnchor;
}
/**
* Returns the outline paint.
*
* @return The outline paint (possibly <code>null</code>).
*
* @see #setOutlinePaint(Paint)
*/
public Color getOutlinePaint() {
return this.outlinePaint;
}
/**
* Returns the outline stroke.
*
* @return The outline stroke (possibly <code>null</code>).
*
* @see #setOutlineStroke(Stroke)
*/
public Stroke getOutlineStroke() {
return this.outlineStroke;
}
/**
* Returns the paint.
*
* @return The paint (never <code>null</code>).
*
* @see #setPaint(Color)
*/
public Color getPaint() {
return this.paint;
}
/**
* Returns the stroke.
*
* @return The stroke (never <code>null</code>).
*
* @see #setStroke(Stroke)
*/
public Stroke getStroke() {
return this.stroke;
}
/**
* Notifies all registered listeners that the marker has been modified.
*
* @param event
* information about the change event.
*/
public void notifyListeners(final MarkerChangeEvent event) {
final Object[] listeners = this.listenerList.getListeners();
for (int i = 0; i < listeners.length; i++) {
final MarkerChangeListener listener = (MarkerChangeListener) listeners[i];
listener.markerChanged(event);
}
}
/**
* Unregisters an object for notification of changes to the marker.
*
* @param listener
* the object to be unregistered.
*/
public void removeChangeListener(final MarkerChangeListener listener) {
this.listenerList.remove(listener);
}
/**
* Sets the alpha transparency that should be used when drawing the marker,
* and sends a {@link MarkerChangeEvent} to all registered listeners. The
* alpha transparency is a value in the range 0.0f (completely transparent)
* to 1.0f (completely opaque).
*
* @param alpha
* the alpha transparency (must be in the range 0.0f to 1.0f).
*
* @throws IllegalArgumentException
* if <code>alpha</code> is not in the specified range.
*
* @see #getAlpha()
*/
public void setAlpha(final int alpha) {
this.alpha = alpha;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the label (if <code>null</code> no label is displayed) and sends a
* {@link MarkerChangeEvent} to all registered listeners.
*
* @param label
* the label (<code>null</code> permitted).
*
* @see #getLabel()
*/
public void setLabel(final String label) {
this.label = label;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the label anchor and sends a {@link MarkerChangeEvent} to all
* registered listeners. The anchor defines the position of the label
* anchor, relative to the bounds of the marker.
*
* @param anchor
* the anchor (<code>null</code> not permitted).
*
* @see #getLabelAnchor()
*/
public void setLabelAnchor(final RectangleAnchor anchor) {
if (anchor == null) {
throw new IllegalArgumentException("Null 'anchor' argument.");
}
this.labelAnchor = anchor;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the label font and sends a {@link MarkerChangeEvent} to all
* registered listeners.
*
* @param font
* the font (<code>null</code> not permitted).
*
* @see #getLabelFont()
*/
public void setLabelFont(final Font font) {
if (font == null) {
throw new IllegalArgumentException("Null 'font' argument.");
}
this.labelFont = font;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the label offset and sends a {@link MarkerChangeEvent} to all
* registered listeners.
*
* @param offset
* the label offset (<code>null</code> not permitted).
*
* @see #getLabelOffset()
*/
public void setLabelOffset(final RectangleInsets offset) {
if (offset == null) {
throw new IllegalArgumentException("Null 'offset' argument.");
}
this.labelOffset = offset;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the label offset type and sends a {@link MarkerChangeEvent} to all
* registered listeners.
*
* @param adj
* the type (<code>null</code> not permitted).
*
* @see #getLabelOffsetType()
*/
public void setLabelOffsetType(final LengthAdjustmentType adj) {
if (adj == null) {
throw new IllegalArgumentException("Null 'adj' argument.");
}
this.labelOffsetType = adj;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the label paint and sends a {@link MarkerChangeEvent} to all
* registered listeners.
*
* @param paint
* the paint (<code>null</code> not permitted).
*
* @see #getLabelPaint()
*/
public void setLabelPaint(final Color paint) {
if (paint == null) {
throw new IllegalArgumentException("Null 'paint' argument.");
}
this.labelPaint = paint;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the label text anchor and sends a {@link MarkerChangeEvent} to all
* registered listeners.
*
* @param anchor
* the label text anchor (<code>null</code> not permitted).
*
* @see #getLabelTextAnchor()
*/
public void setLabelTextAnchor(final TextAnchor anchor) {
if (anchor == null) {
throw new IllegalArgumentException("Null 'anchor' argument.");
}
this.labelTextAnchor = anchor;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the outline paint and sends a {@link MarkerChangeEvent} to all
* registered listeners.
*
* @param paint
* the paint (<code>null</code> permitted).
*
* @see #getOutlinePaint()
*/
public void setOutlinePaint(final Color paint) {
this.outlinePaint = paint;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the outline stroke and sends a {@link MarkerChangeEvent} to all
* registered listeners.
*
* @param stroke
* the stroke (<code>null</code> permitted).
*
* @see #getOutlineStroke()
*/
public void setOutlineStroke(final Stroke stroke) {
this.outlineStroke = stroke;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the paint and sends a {@link MarkerChangeEvent} to all registered
* listeners.
*
* @param paint
* the paint (<code>null</code> not permitted).
*
* @see #getPaint()
*/
public void setPaint(final Color paint) {
if (paint == null) {
throw new IllegalArgumentException("Null 'paint' argument.");
}
this.paint = paint;
this.notifyListeners(new MarkerChangeEvent(this));
}
/**
* Sets the stroke and sends a {@link MarkerChangeEvent} to all registered
* listeners.
*
* @param stroke
* the stroke (<code>null</code> not permitted).
*
* @see #getStroke()
*/
public void setStroke(final Stroke stroke) {
if (stroke == null) {
throw new IllegalArgumentException("Null 'stroke' argument.");
}
this.stroke = stroke;
this.notifyListeners(new MarkerChangeEvent(this));
}
}