/**
* Copyright (C) 2001-2017 by RapidMiner and the contributors
*
* Complete list of developers available at our web site:
*
* http://rapidminer.com
*
* This program is free software: you can redistribute it and/or modify it under the terms of the
* GNU Affero General Public License as published by the Free Software Foundation, either version 3
* of the License, or (at your option) any later version.
*
* This program 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
* Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License along with this program.
* If not, see http://www.gnu.org/licenses/.
*/
package com.rapidminer.gui.new_plotter.configuration;
import com.rapidminer.gui.new_plotter.listener.events.LineFormatChangeEvent;
import com.rapidminer.gui.new_plotter.utility.DataStructureUtils;
import com.rapidminer.tools.I18N;
import java.awt.BasicStroke;
import java.awt.Color;
import java.lang.ref.WeakReference;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
/**
* @author Marius Helf
*/
public class LineFormat implements Cloneable {
private static class StrokeFactory {
static public BasicStroke getSolidStroke() {
return new BasicStroke(1, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
}
static public BasicStroke getDottedStroke() {
return new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 10.0f, new float[] { 1f, 1f }, 0.0f);
}
static public BasicStroke getShortDashedStroke() {
return new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 10.0f, new float[] { 4f, 2f }, 0.0f);
}
static public BasicStroke getLongDashedStroke() {
return new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 10.0f, new float[] { 7f, 3f }, 0.0f);
}
static public BasicStroke getDashDotStroke() {
return new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 10.0f, new float[] { 6f, 2f, 1f, 2f },
0.0f);
}
static public BasicStroke getStripedStroke() {
return new BasicStroke(1, BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 10.0f, new float[] { 0.2f, 0.2f }, 0.0f);
}
}
public enum LineStyle {
NONE(null, I18N.getGUILabel("plotter.linestyle.NONE.label")), SOLID(StrokeFactory.getSolidStroke(), I18N
.getGUILabel("plotter.linestyle.SOLID.label")), DOTS(StrokeFactory.getDottedStroke(), I18N
.getGUILabel("plotter.linestyle.DOTS.label")), SHORT_DASHES(StrokeFactory.getShortDashedStroke(), I18N
.getGUILabel("plotter.linestyle.SHORT_DASHES.label")), LONG_DASHES(StrokeFactory.getLongDashedStroke(), I18N
.getGUILabel("plotter.linestyle.LONG_DASHES.label")), DASH_DOT(StrokeFactory.getDashDotStroke(), I18N
.getGUILabel("plotter.linestyle.DASH_DOT.label")), STRIPES(StrokeFactory.getStripedStroke(), I18N
.getGUILabel("plotter.linestyle.STRIPES.label"));
private final BasicStroke stroke;
private final String name;
public BasicStroke getStroke() {
return stroke;
}
public String getName() {
return name;
}
private LineStyle(BasicStroke stroke, String name) {
this.stroke = stroke;
this.name = name;
}
}
private List<WeakReference<LineFormatListener>> listeners = new LinkedList<WeakReference<LineFormatListener>>();
private LineStyle style = LineStyle.NONE; // dashed, solid...
private Color color = Color.GRAY;
private float width = 1.0f;
public LineStyle getStyle() {
return style;
}
public void setStyle(LineStyle style) {
if (style != this.style) {
this.style = style;
fireStyleChanged();
}
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
if (color == null ? this.color != null : !color.equals(this.color)) {
this.color = color;
fireColorChanged();
}
}
public float getWidth() {
return width;
}
public void setWidth(float width) {
if (width != this.width) {
this.width = width;
fireWidthChanged();
}
}
private void fireWidthChanged() {
fireLineFormatChanged(new LineFormatChangeEvent(this, width));
}
private void fireColorChanged() {
fireLineFormatChanged(new LineFormatChangeEvent(this, color));
}
private void fireStyleChanged() {
fireLineFormatChanged(new LineFormatChangeEvent(this, style));
}
private void fireLineFormatChanged(LineFormatChangeEvent e) {
Iterator<WeakReference<LineFormatListener>> it = listeners.iterator();
while (it.hasNext()) {
LineFormatListener l = it.next().get();
if (l != null) {
l.lineFormatChanged(e);
} else {
it.remove();
}
}
}
@Override
public LineFormat clone() {
LineFormat clone = new LineFormat();
clone.color = new Color(color.getRGB(), true);
clone.style = style;
clone.width = width;
return clone;
}
public BasicStroke getStroke() {
BasicStroke stroke = style.getStroke();
if (stroke != null) {
float[] scaledDashArray = getScaledDashArray();
BasicStroke scaledStroke = new BasicStroke(this.getWidth(), stroke.getEndCap(), stroke.getLineJoin(),
stroke.getMiterLimit(), scaledDashArray, stroke.getDashPhase());
return scaledStroke;
} else {
return null;
}
}
float[] getScaledDashArray() {
BasicStroke stroke = getStyle().getStroke();
if (stroke == null) {
return null;
}
float[] dashArray = stroke.getDashArray();
float[] scaledDashArray;
if (dashArray != null) {
float scalingFactor = getWidth();
if (scalingFactor <= 0) {
scalingFactor = 1;
}
if (scalingFactor != 1) {
scaledDashArray = DataStructureUtils.cloneAndMultiplyArray(dashArray, scalingFactor);
} else {
scaledDashArray = dashArray;
}
} else {
scaledDashArray = dashArray;
}
return scaledDashArray;
}
public void addLineFormatListener(LineFormatListener l) {
listeners.add(new WeakReference<LineFormatListener>(l));
}
public void removeLineFormatListener(LineFormatListener l) {
Iterator<WeakReference<LineFormatListener>> it = listeners.iterator();
while (it.hasNext()) {
LineFormatListener listener = it.next().get();
if (l != null) {
if (listener != null && listener.equals(l)) {
it.remove();
}
} else {
it.remove();
}
}
}
}