1
0
mirror of https://github.com/octoleo/plantuml.git synced 2024-11-25 06:17:33 +00:00

version 1.2019.8

This commit is contained in:
Arnaud Roques 2019-07-14 22:09:26 +02:00
parent fb108ebb5a
commit 18b688210f
317 changed files with 8220 additions and 8763 deletions

View File

@ -61,6 +61,11 @@
<include name="**/*.repx" /> <include name="**/*.repx" />
</fileset> </fileset>
</copy> </copy>
<copy todir="build/skin">
<fileset dir="skin">
<include name="**/*.skin" />
</fileset>
</copy>
</target> </target>
<target name="dist" depends="compile"> <target name="dist" depends="compile">

View File

@ -35,7 +35,7 @@
<groupId>net.sourceforge.plantuml</groupId> <groupId>net.sourceforge.plantuml</groupId>
<artifactId>plantuml</artifactId> <artifactId>plantuml</artifactId>
<version>1.2019.8-SNAPSHOT</version> <version>1.2019.9-SNAPSHOT</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<name>PlantUML</name> <name>PlantUML</name>

169
skin/debug.skin Normal file
View File

@ -0,0 +1,169 @@
style root {
FontName SansSerif
HyperLinkColor red
FontColor green
FontSize 19
FontStyle plain
HorizontalAlignment left
RoundCorner 15
DiagonalCorner 0
LineColor #3600A8
LineThickness 1.0
BackGroundColor #AAA
Shadowing 0.0
}
style stereotype {
FontColor blue
FontSize 8
FontStyle bold
}
style title {
HorizontalAlignment right
FontSize 24
FontColor blue
}
style header {
HorizontalAlignment center
FontSize 26
FontColor purple
}
style footer {
HorizontalAlignment left
FontSize 28
FontColor red
}
style legend {
FontSize 30
BackGroundColor yellow
Margin 30
Padding 50
}
style caption {
FontSize 32
}
style element {
BackGroundColor #CEFEFE
}
style sequenceDiagram {
}
style classDiagram {
}
style activityDiagram {
}
style group {
LineThickness 3.5
BackGroundColor MistyRose
LineColor DarkOrange
FontSize 12
FontStyle italic
FontColor red
}
style groupHeader {
BackGroundColor tan
LineThickness 0.5
LineColor yellow
FontSize 18
FontStyle bold
FontColor blue
}
style lifeLine {
BackGroundColor gold
}
style destroy {
LineColor red
}
style reference {
LineColor red
FontSize 10
FontStyle bold
FontColor blue
BackGroundColor gold
HorizontalAlignment right
}
style box {
LineThickness 0.1
LineColor FireBrick
BackGroundColor PowderBlue
FontSize 12
FontStyle italic
FontColor Maroon
}
style separator {
LineColor red
BackGroundColor green
FontSize 16
FontStyle bold
FontColor white
}
style delay {
FontSize 22
FontStyle italic
}
style participant {
LineThickness 2.5
}
style actor {
LineThickness 0.5
}
style boundary {
LineThickness 1.5
}
style control {
LineThickness 1.5
}
style entity {
LineThickness 1.5
}
style queue {
LineThickness 1.5
}
style database {
LineThickness 1.5
}
style collections {
LineThickness 1.5
}
style message {
}
style note {
BackGroundColor GoldenRod
}
style swimlane {
}

164
skin/plantuml.skin Normal file
View File

@ -0,0 +1,164 @@
style root {
FontName SansSerif
HyperLinkColor red
FontColor black
FontSize 14
FontStyle plain
HorizontalAlignment left
RoundCorner 0
DiagonalCorner 0
LineThickness 1.0
LineColor #A80036
BackGroundColor #FEFECE
Shadowing 0.0
}
style stereotype {
FontStyle italic
}
style title {
HorizontalAlignment center
FontSize 14
FontStyle bold
Padding 0
Margin 4
LineColor none
BackGroundColor none
}
style header {
HorizontalAlignment center
FontSize 10
FontColor #888888
}
style footer {
HorizontalAlignment left
FontSize 10
FontColor #888888
}
style legend {
LineColor black
BackGroundColor #DDDDDD
FontSize 14
RoundCorner 15
Padding 6
Margin 8
}
style caption {
HorizontalAlignment center
FontSize 14
Padding 0
Margin 1
LineColor none
BackGroundColor none
}
style element {
Shadowing 4.0
}
style sequenceDiagram {
}
style classDiagram {
}
style activityDiagram {
}
style group {
BackGroundColor none
LineColor black
LineThickness 2.0
FontSize 11
FontStyle bold
}
style groupHeader {
BackGroundColor #EEEEEE
LineColor black
FontSize 13
FontStyle bold
}
style lifeLine {
BackGroundColor none
}
style destroy {
}
style reference {
LineColor red
FontSize 10
FontStyle bold
FontColor blue
BackGroundColor gold
HorizontalAlignment right
}
style box {
BackGroundColor #DDDDDD
FontSize 13
FontStyle bold
}
style separator {
LineColor black
LineThickness 2.0
BackGroundColor #EEEEEE
FontSize 13
FontStyle bold
}
style delay {
FontSize 22
FontStyle italic
}
style participant {
LineThickness 1.5
}
style actor {
LineThickness 2.0
}
style boundary {
}
style control {
}
style entity {
}
style queue {
}
style database {
}
style collections {
}
style swimlane {
}
style message {
FontSize 13
}
style note {
FontSize 13
BackGroundColor #FBFB77
}

116
skin/reddress.skin Normal file
View File

@ -0,0 +1,116 @@
!ifndef FONTNAME
!define FONTNAME "Verdana"
!endif
!ifndef FONTSIZE
!define FONTSIZE 11
!endif
!ifdef DARKBLUE
skinparam backgroundColor 777
!define ACCENT 1a66c2
!define ACCENTDARK 002642
skinparam stereotypeCBackgroundColor ACCENT
!define DARKSTYLE
!endif
!ifdef LIGHTBLUE
!define ACCENT 2a86e2
!define ACCENTDARK 1a66c2
skinparam stereotypeCBackgroundColor ACCENTDARK
!define LIGHTSTYLE
!endif
!ifdef DARKRED
!define ACCENT 880000
!define ACCENTDARK 330000
skinparam stereotypeCBackgroundColor ACCENT
!define DARKSTYLE
!endif
!ifdef LIGHTRED
!define ACCENT CC0033
!define ACCENTDARK AA0033
skinparam stereotypeCBackgroundColor ACCENTDARK
!define LIGHTSTYLE
!endif
!ifdef DARKGREEN
!define ACCENT 228811
!define ACCENTDARK 113300
skinparam stereotypeCBackgroundColor ACCENT
!define DARKSTYLE
!endif
!ifdef LIGHTGREEN
!define ACCENT 55BB33
!define ACCENTDARK 338822
skinparam stereotypeCBackgroundColor ACCENTDARK
!define LIGHTSTYLE
!endif
!ifdef DARKORANGE
!define ACCENT BB6600
!define ACCENTDARK 662200
skinparam stereotypeCBackgroundColor ACCENT
!define DARKSTYLE
!endif
!ifdef LIGHTORANGE
!define ACCENT FF8800
!define ACCENTDARK BB6600
skinparam stereotypeCBackgroundColor ACCENT
!define LIGHTSTYLE
!endif
!ifdef LIGHTSTYLE
!define PRIMARY 000
!define SECONDARY 333
!define ARROWCOLOR 000
!define ARROWFONTCOLOR 333
!define BORDERCOLOR aaa
!define BOXBG ccc
skinparam backgroundColor fff
!endif
!ifdef DARKSTYLE
!define PRIMARY fff
!define SECONDARY aaa
!define ARROWCOLOR fff
!define ARROWFONTCOLOR bbb
!define BORDERCOLOR 1b1b1b
!define BOXBG 2e2e2e
skinparam backgroundColor 777
!endif
skinparam circledCharacter {
radius 8
fontSize FONTSIZE
fontName FONTNAME
}
skinparam class {
backgroundColor BOXBG
borderColor BORDERCOLOR
fontColor PRIMARY
fontName FONTNAME
fontSize FONTSIZE
arrowColor ARROWCOLOR
arrowFontName FONTNAME
arrowFontColor ARROWFONTCOLOR
arrowFontSize FONTSIZE
attributeFontColor SECONDARY
attributeFontSize FONTSIZE
attributeIconSize FONTSIZE
stereotypeFontColor SECONDARY
stereotypeFontSize FONTSIZE
}
skinparam note {
backgroundColor ACCENT
borderColor ACCENTDARK
fontColor PRIMARY
fontName FONTNAME
fontSize FONTSIZE
}

37
skin/sonyxperiadev.skin Normal file
View File

@ -0,0 +1,37 @@
SkinParam BackgroundColor #white
SkinParam Shadowing false
SkinParam SequenceMessageAlign center
SkinParam DefaultFontName Arial
SkinParam DefaultFontStyle bold
SkinParam DefaultFontColor #333333
SkinParam NoteBackgroundColor #fbfb77
SkinParam NoteBorderColor #cbcb47
SkinParam NoteBackgroundColor #ffffcd
SkinParam NoteBorderColor #a9a980
SkinParam NoteFontColor #676735
SkinParam NoteFontStyle italic
SkinParam SequenceArrowColor #555555
SkinParam SequenceArrowFontColor #555555
SkinParam SequenceArrowFontStyle none
SkinParam SequenceBoxBackgroundColor #fafafa
SkinParam SequenceBoxBorderColor #eeeeee
SkinParam SequenceBoxFontColor #666666
SkinParam SequenceBoxFontSize 12
SkinParam SequenceBoxFontStyle italic
SkinParam ParticipantBackgroundColor #dde5ff
SkinParam ParticipantBorderColor #cccccc
SkinParam ParticipantFontColor #333333
SkinParam ParticipantFontStyle bold
SkinParam DatabaseBackgroundColor #df4646
SkinParam DatabaseFontColor #red
SkinParam DatabaseFontStyle bold
SkinParam EntityBackgroundColor #999999
SkinParam SequenceLifeLineBorderColor #bbbbbb

View File

@ -1,228 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.Renderer;
import jcckit.plot.Plot;
import jcckit.plot.PlotCanvas;
import jcckit.renderer.Graphics2DRenderer;
import jcckit.renderer.Transformation;
import jcckit.util.ConfigParameters;
import jcckit.util.Factory;
/**
* Class which handles plotting into a <tt>Graphics</tt> context based on the
* {@link jcckit.renderer.GraphicsRenderer}. This class is not a subclass of
* <tt>java.awt.Component</tt>. The actual AWT component presenting the plot
* is an innerclass. Its instance wrapped by <tt>GraphicsPlotCanvas</tt> can
* be obtained with {@link #getGraphicsCanvas}.
* <p>
* The plot is painted by using double-buffering and pre-rendered view of the
* coordinate system. That is, the coordinate system is drawn into an off-screen
* image. It will be redrawn only if the size of the embedding AWT component is
* changed.
*
* @author Franz-Josef Elmer
*/
public class GraphicsPlotCanvas extends PlotCanvas {
/** Key of a configuration parameter. */
public static final String BACKGROUND_KEY = "background";
public static final String FOREGROUND_KEY = "foreground";
public static final String DOUBLE_BUFFERING_KEY = "doubleBuffering";
/**
* Class which does the actual painting. Needs the <tt>Component</tt> into
* which the plot is painted for some resources like size, background color,
* etc.
*
* @author Franz-Josef Elmer
*/
private final BufferedImage img3;
private final Graphics2D g3;
private Transformation _transformation;
private String _renderer = "jcckit.renderer.GraphicsRenderer";
private GraphicalElement _marker;
/**
* Creates an instance from the specified configuration parameters. <table
* border=1 cellpadding=5>
* <tr>
* <th>Key &amp; Default Value</th>
* <th>Type</th>
* <th>Mandatory</th>
* <th>Description</th>
* </tr>
* <tr>
* <td><tt>background = </tt><i>default background color of the wrapped
* AWT component</i></td>
* <td><tt>Color</tt></td>
* <td>no</td>
* <td>Background color of the wrapped AWT component.</td>
* </tr>
* <tr>
* <td><tt>foreground = </tt><i>default foreground color of the wrapped
* AWT component</i></td>
* <td><tt>Color</tt></td>
* <td>no</td>
* <td>Foreground color of the wrapped AWT component.</td>
* </tr>
* <tr>
* <td><tt>doubleBuffering = true</td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> the plot will be painted by using
* double-buffering and pre-rendered view of the coordinate system.
* </td></tr>
* </table>
* In addition the configuration parameters of the
* <a href="plot/PlotCanvas.html#PlotCanvas(jcckit.util.ConfigParameters)">
* constructor</a> of the superclass {@link jcckit.plot.PlotCanvas} apply.
*/
public GraphicsPlotCanvas(ConfigParameters config, BufferedImage img3) {
super(config);
this.img3 = img3;
setRenderer("jcckit.renderer.Graphics2DRenderer");
g3 = img3.createGraphics();
g3.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// _doubleBuffering = config.getBoolean(DOUBLE_BUFFERING_KEY, true);
background = config.getColor(BACKGROUND_KEY, Color.WHITE);
foreground = config.getColor(FOREGROUND_KEY, Color.BLACK);
}
private final Color background;
private final Color foreground;
/**
* Paints the plot. If {@link GraphicsPlotCanvas#_doubleBuffering} is set
* double-buffering and pre-rendered view of the coordinate system is used.
*/
public void paint() {
Dimension size = new Dimension(img3.getWidth(), img3.getHeight());
g3.setColor(background);
g3.fillRect(0, 0, size.width + 1, size.height + 1);
init(size);
_transformation.apply(g3);
Plot plot = getPlot();
drawCoordinateSystem(size, plot);
drawPlot(plot);
if (_marker != null) {
_marker.renderWith(createRenderer());
}
}
private void drawPlot(Plot plot) {
prepare();
Renderer renderer = createRenderer();
GraphicalElement[] curves = plot.getCurves();
for (int i = 0; i < curves.length; i++) {
curves[i].renderWith(renderer);
}
GraphicalElement annotation = plot.getAnnotation();
if (annotation != null) {
annotation.renderWith(renderer);
}
if (plot.isLegendVisible()) {
plot.getLegend().renderWith(renderer);
}
}
private void init(Dimension size) {
calculateTransformation(size);
}
private void drawCoordinateSystem(Dimension size, Plot plot) {
g3.setColor(foreground);
plot.getCoordinateSystem().renderWith(createRenderer());
}
/**
* Prepare graphics context before drawing the pre-rendered view of the
* coordinate system. Does nothing but will be used in subclasses.
*/
protected void prepare() {
}
/**
* Calculate the transformation form device-independent coordinates into
* device-dependent coordinates according to the specified canvas size.
*/
protected void calculateTransformation(Dimension size) {
_transformation = new Transformation(size.width, size.height, getPaper(), getHorizontalAnchor(),
getVerticalAnchor());
}
/**
* Creates an appropriated {@link Renderer} for the specified
* <tt>Graphics</tt> context.
*/
protected Renderer createRenderer() {
return ((Graphics2DRenderer) Factory.create(_renderer)).init(g3);
// return ((GraphicsRenderer) Factory.create(_renderer)).init(g, null,
// _transformation);
}
/**
* Sets the renderer used to render the plot. The default value is
* {@link GraphicsRenderer}.
*
* @param className
* Fully qualified name of the renderer class.
*/
public void setRenderer(String className) {
_renderer = className;
}
// /**
// * Maps the cursor position onto a point in device-independent
// coordinates.
// *
// * @param x
// * X-coordinate of the cursor.
// * @param y
// * Y-coordinate of the cursor.
// */
// public GraphPoint mapCursorPosition(int x, int y) {
// return _transformation.transformBack(x, y);
// }
/**
* Defines a graphical marker which will be drawn on top of the plot. To
* remove the marker call this method with argument <tt>null</tt>.
*
* @param marker
* Marker element. Can be <tt>null</tt>.
*/
public void setMarker(GraphicalElement marker) {
_marker = marker;
}
}

View File

@ -1,182 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
import java.text.MessageFormat;
import java.util.Vector;
/**
* Abstract superclass of all data containers. A data container holds an
* ordered list of {@link DataElement DataElements} of the same type.
* <p>
* Data elements can be added, inserted, removed, or replaced.
* Such an action leads to a {@link DataEvent} which will be delivered to
* all {@link DataListener DataListeners} observing this
* <code>DataContainer</code>. If this data container also implements
* {@link DataEvent} (as {@link DataCurve} does) also the listeners
* registrated at the data container containg this container will be notified.
* As a consequence a <tt>DataListener</tt> must only be registered at the
* {@link DataPlot} instance and it will automatically also received events
* caused by manipulating one of its <tt>DataCurves</tt>.
* <p>
* Concrete subclasses have to implement {@link #isValid} which
* checks whether the added or inserted <tt>DataElement</tt> is of the right
* type. This is an application of the Template Method Design Pattern.
*
* @author Franz-Josef Elmer
*/
public abstract class DataContainer {
private final static String TEMPLATE
= "Invalid operation: {0}, Element: {1}, Container: {2}";
final static String ADD = "add",
REPLACE = "replace",
INSERT = "insert";
private final Vector _listeners = new Vector();
private final Vector _container = new Vector();
/** Adds a {@link DataListener}. Does nothing if already added. */
public void addDataListener(DataListener listener) {
if (!_listeners.contains(listener)) {
_listeners.addElement(listener);
}
}
/** Removes a {@link DataListener}. Does nothing if already removed. */
public void removeDataListener(DataListener listener) {
_listeners.removeElement(listener);
}
private void notifyListeners(DataEvent event) {
for (int i = 0, n = _listeners.size(); i < n; i++) {
((DataListener) _listeners.elementAt(i)).dataChanged(event);
}
// Notifies also parent container
if (this instanceof DataElement) {
DataContainer container = ((DataElement) this).getContainer();
if (container != null) {
container.notifyListeners(event);
}
}
}
/** Returns the number of elements of this container. */
public int getNumberOfElements() {
return _container.size();
}
/** Returns the element for the specified index. */
public DataElement getElement(int index) {
return (DataElement) _container.elementAt(index);
}
/**
* Returns the index of the specified element.
* @param element Element to be looked for.
* @return -1 if not found.
*/
public int getIndexOf(DataElement element) {
return _container.indexOf(element);
}
/**
* Adds a {@link DataElement}. After the element has been successfully
* added all {@link DataListener DataListeners} will be informed.
* @param element DataElement to be added.
* @throws IllegalArgumentException if <tt>element</tt> is not of the correct
* type which will be checked by the method {@link #isValid}.
*/
public void addElement(DataElement element) {
if (isValid(element)) {
_container.addElement(element);
element.setContainer(this);
notifyListeners(DataEvent.createAddEvent(this));
} else {
throwException(ADD, element);
}
}
/**
* Inserts a {@link DataElement} at the specified index.
* After the element has been successfully inserted
* all {@link DataListener DataListeners} will be informed.
* @param index Index at which <tt>element</tt> will be inserted.
* All elements with an index &gt;= <tt>index</tt> will be shifted.
* @param element DataElement to be added.
* @throws IllegalArgumentException if <tt>element</tt> is not of the correct
* type which will be checked by the method {@link #isValid}.
*/
public void insertElementAt(int index, DataElement element) {
if (isValid(element)) {
_container.insertElementAt(element, index);
element.setContainer(this);
notifyListeners(DataEvent.createInsertEvent(this, index));
} else {
throwException(INSERT, element);
}
}
/**
* Removes a {@link DataElement} at the specified index.
* After the element has been successfully removed
* all {@link DataListener DataListeners} will be informed.
* @param index Index of the element which will be removed.
* All elements with an index &gt; <tt>index</tt> will be shifted.
*/
public void removeElementAt(int index) {
DataElement element = (DataElement) _container.elementAt(index);
element.setContainer(null);
_container.removeElementAt(index);
notifyListeners(DataEvent.createRemoveEvent(this, index, element));
}
/**
* Replaces the {@link DataElement} at the specified index.
* After the element has been successfully replaced
* all {@link DataListener DataListeners} will be informed.
* @param index Index of the element which will be replaced by
* <tt>element</tt>.
* @param element The new <tt>DataElement</tt>.
* @throws IllegalArgumentException if <tt>element</tt> is not of the correct
* type which will be checked by the method {@link #isValid}.
*/
public void replaceElementAt(int index, DataElement element) {
if (isValid(element)) {
DataElement oldElement = (DataElement) _container.elementAt(index);
oldElement.setContainer(null);
_container.setElementAt(element, index);
element.setContainer(this);
notifyListeners(DataEvent.createReplaceEvent(this, index, oldElement));
} else {
throwException(REPLACE, element);
}
}
private void throwException(String operation, DataElement element) {
throw new IllegalArgumentException(MessageFormat.format(TEMPLATE,
new Object[] {operation, element, this.getClass().getName()}));
}
/**
* Returns <tt>true</tt> if the specified {@link DataElement} has the
* correct type. Concrete subclasses have to implement this method.
* @param element <tt>DataElement</tt> to be checked.
*/
protected abstract boolean isValid(DataElement element);
}

View File

@ -1,93 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
import jcckit.util.ConfigParameters;
/**
* A curve is a {@link DataContainer} of {@link DataPoint DataPoints}.
*
* @author Franz-Josef Elmer
*/
public class DataCurve extends DataContainer implements DataElement {
/** Config parameter key. */
public static final String X_KEY = "x",
Y_KEY = "y",
TITLE_KEY = "title";
private final String _title;
private DataContainer _container;
/** Creates an empty instance with the specified title. */
public DataCurve(String title) {
_title = title;
}
/**
* Creates an instance from the specified config parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>title = </tt><i>empty string</i></td>
* <td><tt>String</tt></td><td>no</td>
* <td>Curve title.</td></tr>
* <tr><td><tt>x</tt></td><td><tt>double[]</tt></td><td>yes</td>
* <td>x-coordinates of the curve points.</td></tr>
* <tr><td><tt>y</tt></td><td><tt>double[]</tt></td><td>yes</td>
* <td>y-coordinates of the curve points.</td></tr>
* </table>
*/
public DataCurve(ConfigParameters config) {
this(config.get(TITLE_KEY, ""));
double[] xPoints = config.getDoubleArray(X_KEY);
double[] yPoints = config.getDoubleArray(Y_KEY);
int n = Math.min(xPoints.length, yPoints.length);
for (int i = 0; i < n; i++) {
addElement(new DataPoint(xPoints[i], yPoints[i]));
}
}
/**
* Returns the {@link DataPlot} containing this curve.
*/
public DataContainer getContainer() {
return _container;
}
/**
* Sets the {@link DataPlot} where this is a curve of.
*/
public void setContainer(DataContainer container) {
_container = container;
}
/** Returns the title of this curve. */
public String getTitle() {
return _title;
}
/**
* Returns <tt>true</tt> if <tt>element</tt> is an instance of
* {@link DataPoint}.
*/
protected boolean isValid(DataElement element) {
return element instanceof DataPoint;
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
/**
* Interface for all kinds of data elements.
*
* @author Franz-Josef Elmer
*/
public interface DataElement {
/**
* Returns the container containing this element.
* @return <tt>null</tt> if this element is not an element of a container.
*/
public DataContainer getContainer();
/**
* Sets the container which should contain this element.
* This method should <b>not</b> used outside {@link DataContainer}..
* @param container Container which should contains this element. Cann be
* <tt>null</tt> if this element does not belong to a container.
*/
public void setContainer(DataContainer container);
}

View File

@ -1,128 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
/**
* Event to be sent to a {@link DataListener}.
*
* @author Franz-Josef Elmer
*/
public class DataEvent {
private final DataContainer _container;
private final DataEventType _type;
private final int _index;
private final DataElement _deletedElement;
/**
* Creates an instance for the specified parameters.
* @param container The container which has been changed.
* @param type Type of change.
* @param index Index of the element which has been added, inserted,
* replaced, or removed.
* @param deletedElement Element which has been replaced or removed.
*/
private DataEvent(DataContainer container, DataEventType type, int index,
DataElement deletedElement) {
_container = container;
_type = type;
_index = index;
_deletedElement = deletedElement;
}
/**
* Creates an event of type {@link DataEventType#ELEMENT_ADDED} for the
* specified container.
* @param container Container where an element has been added.
* @return <tt>ELEMENT_ADDED</tt> event.
*/
public static final DataEvent createAddEvent(DataContainer container) {
return new DataEvent(container, DataEventType.ELEMENT_ADDED,
container.getNumberOfElements() - 1, null);
}
/**
* Creates an event of type {@link DataEventType#ELEMENT_INSERTED} for the
* specified container.
* @param container Container where an element has been inserted.
* @param index Index at which an element has been inserted.
* @return <tt>ELEMENT_INSERTED</tt> event.
*/
public static final DataEvent createInsertEvent(DataContainer container,
int index) {
return new DataEvent(container, DataEventType.ELEMENT_INSERTED, index,
null);
}
/**
* Creates an event of type {@link DataEventType#ELEMENT_REPLACED} for the
* specified container.
* @param container Container where an element has been replaced.
* @param index Index of the replaced element.
* @param replacedElement The previous element at <tt>index</tt>.
* @return <tt>ELEMENT_REPLACED</tt> event.
*/
public static final DataEvent createReplaceEvent(DataContainer container,
int index, DataElement replacedElement) {
return new DataEvent(container, DataEventType.ELEMENT_REPLACED, index,
replacedElement);
}
/**
* Creates an event of type {@link DataEventType#ELEMENT_REMOVED} for the
* specified container.
* @param container Container where an element has been removed.
* @param index Index of the removed element.
* @param removedElement The previous element at <tt>index</tt>.
* @return <tt>ELEMENT_REMOVED</tt> event.
*/
public static final DataEvent createRemoveEvent(DataContainer container,
int index, DataElement removedElement) {
return new DataEvent(container, DataEventType.ELEMENT_REMOVED, index,
removedElement);
}
/** Returns the container. */
public DataContainer getContainer() {
return _container;
}
/**
* Returns the event type. Will be one of the constants
* {@link DataEventType#ELEMENT_ADDED},
* {@link DataEventType#ELEMENT_INSERTED},
* {@link DataEventType#ELEMENT_REMOVED}, or
* {@link DataEventType#ELEMENT_REPLACED}.
*/
public DataEventType getType() {
return _type;
}
/** Returns the index. */
public int getIndex() {
return _index;
}
/**
* Returns the deleted element.
* @return <tt>null</tt> if either an element has been added or inserted.
*/
public DataElement getDeletedElement() {
return _deletedElement;
}
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
/**
* Type of a {@link DataEvent}. Implements the typesafe enumeration pattern.
*
* @author Franz-Josef Elmer
*/
public class DataEventType {
private DataEventType() {}
/** Event type. */
public static final DataEventType ELEMENT_ADDED = new DataEventType(),
ELEMENT_INSERTED = new DataEventType(),
ELEMENT_REPLACED = new DataEventType(),
ELEMENT_REMOVED = new DataEventType();
}

View File

@ -1,33 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
/**
* An interface all observers of {@link DataEvent DataEvents}
* have to implement.
*
* @author Franz-Josef Elmer
*/
public interface DataListener {
/**
* Sends the specified data event to this object.
* @param event Data event informing where and what happened.
*/
public void dataChanged(DataEvent event);
}

View File

@ -1,74 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
import java.util.StringTokenizer;
import jcckit.util.ConfigParameters;
/**
* A plot is a {@link DataContainer} of {@link DataCurve DataCurves}.
*
* @author Franz-Josef Elmer
*/
public class DataPlot extends DataContainer {
/** Config parameter key. */
public static final String CURVES_KEY = "curves",
DATA_KEY = "data";
/** Creates an empty instance. */
public DataPlot() {}
/**
* Creates an instance from the specified config parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>curves</tt></td><td><tt>String[]</tt></td><td>yes</td>
* <td>List of keys denoting data curves. Each key refers to
* config parameters used in the
* <a href="DataCurve.html#DataCurve(jcckit.util.ConfigParameters)">
* constructor</a> of {@link DataCurve}.</td></tr>
* </table>
*/
public DataPlot(ConfigParameters config) {
StringTokenizer tokenizer = new StringTokenizer(config.get(CURVES_KEY));
while (tokenizer.hasMoreTokens()) {
addElement(new DataCurve(config.getNode(tokenizer.nextToken())));
}
}
/**
* Convenient method to create a <tt>DataPlot</tt> based on the specified
* config parameters. It is a short-cut of
* <tt>new DataPlot(config.getNode("data"))</tt>.
*/
public static DataPlot create(ConfigParameters config) {
return new DataPlot(config.getNode(DATA_KEY));
}
/**
* Returns <tt>true</tt> if <tt>element</tt> is an instance of
* {@link DataCurve}.
*/
protected boolean isValid(DataElement element) {
return element instanceof DataCurve;
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.data;
import jcckit.util.Point;
/**
* Immutable two-dimensional point in data coordinates.
*
* @author Franz-Josef Elmer
*/
public class DataPoint extends Point implements DataElement {
public DataPoint(double x, double y) {
super(x, y);
}
/** Returns always <tt>null</tt>. */
public DataContainer getContainer() {
return null;
}
/** Does nothing. */
public void setContainer(DataContainer container) {}
}

View File

@ -1,129 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import jcckit.util.ConfigParameters;
import jcckit.util.FactoryException;
/**
* Anchor of a graphical element. There exist only the three
* instances {@link #LEFT_BOTTOM}, {@link #CENTER}, and
* {@link #RIGHT_TOP}.
* <p>
* The anchor factor can be used in a position formular. Its value
* for the three instances reads:
* <p>
* <center>
* <table border=1 cellpadding=5>
* <tr><th>Instance</th><th>Factor</th></tr>
* <tr><td><tt>LEFT_BOTTOM</tt></td><td>0</td></tr>
* <tr><td><tt>CENTER</tt></td><td>1</td></tr>
* <tr><td><tt>RIGHT_TOP</tt></td><td>2</td></tr>
* </table>
* </center>
*
* @author Franz-Josef Elmer
*/
public class Anchor {
/** Anchor constant. */
public static final Anchor LEFT_BOTTOM = new Anchor(0),
CENTER = new Anchor(1),
RIGHT_TOP = new Anchor(2);
private static final String LEFT_VALUE = "left",
RIGHT_VALUE = "right",
CENTER_VALUE = "center",
TOP_VALUE = "top",
BOTTOM_VALUE = "bottom";
/**
* Returns form the specified configuration parameters the
* horizontal anchor defined by the specified key or the
* specified default value.
* @param config Configuration parameters.
* @param key The key of the anchor. <tt>null</tt> is not allowed.
* @param defaultValue The default value.
* @return one of the three instances of <tt>Anchor</tt>.
* @throws FactoryException if the value of <tt>key</tt> is
* neither <tt>left</tt>, <tt>center</tt>,
* nor <tt>right</tt>.
* Note, that {@link FactoryException#getClassName()}
* returns the invalid value.
*/
public static Anchor getHorizontalAnchor(ConfigParameters config, String key,
Anchor defaultValue) {
Anchor result = defaultValue;
String anchor = config.get(key, null);
if (anchor != null) {
if (anchor.equals(LEFT_VALUE)) {
result = Anchor.LEFT_BOTTOM;
} else if (anchor.equals(CENTER_VALUE)) {
result = Anchor.CENTER;
} else if (anchor.equals(RIGHT_VALUE)) {
result = Anchor.RIGHT_TOP;
} else {
throw new FactoryException(config, key, "Invalid horizontal anchor.");
}
}
return result;
}
/**
* Returns form the specified configuration parameters the
* vertical anchor defined by the specified key or the
* specified default value.
* @param config Configuration parameters.
* @param key The key of the anchor. <tt>null</tt> is not allowed.
* @param defaultValue The default value.
* @return one of the three instances of <tt>Anchor</tt>.
* @throws FactoryException if the value of <tt>key</tt> is
* neither <tt>top</tt>, <tt>center</tt>,
* nor <tt>bottom</tt>.
* Note, that {@link FactoryException#getClassName()}
* returns the invalid value.
*/
public static Anchor getVerticalAnchor(ConfigParameters config, String key,
Anchor defaultValue) {
Anchor result = defaultValue;
String anchor = config.get(key, null);
if (anchor != null) {
if (anchor.equals(BOTTOM_VALUE)) {
result = Anchor.LEFT_BOTTOM;
} else if (anchor.equals(CENTER_VALUE)) {
result = Anchor.CENTER;
} else if (anchor.equals(TOP_VALUE)) {
result = Anchor.RIGHT_TOP;
} else {
throw new FactoryException(config, key, "Invalid vertcal anchor.");
}
}
return result;
}
private final int _factor;
private Anchor(int factor) {
_factor = factor;
}
/** Returns the factor. */
public int getFactor() {
return _factor;
}
}

View File

@ -1,202 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.awt.Color;
import jcckit.util.ConfigParameters;
/**
* The basic attributes of any {@link BasicGraphicalElement}. This is an
* extension of {@link ShapeAttributes} implementing {@link TextAttributes}.
*
* @author Franz-Josef Elmer
*/
public class BasicGraphicAttributes extends ShapeAttributes
implements TextAttributes {
/** Configuration parameter key. */
public static final String TEXT_COLOR_KEY = "textColor",
FONT_NAME_KEY = "fontName",
FONT_STYLE_KEY = "fontStyle",
FONT_SIZE_KEY = "fontSize",
HORIZONTAL_ANCHOR_KEY = "horizontalAnchor",
VERTICAL_ANCHOR_KEY = "verticalAnchor",
ORIENTATION_ANGLE_KEY = "orientationAngle";
private final Color _textColor;
private final String _fontName;
private final FontStyle _fontStyle;
private final double _fontSize;
private final double _orientationAngle;
private final Anchor _horizontalAnchor;
private final Anchor _verticalAnchor;
/**
* Creates a new instance based on the specified configuration
* parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>textColor = </tt><i>default foreground color of the
* renderer</i></td><td><tt>Color</tt></td><td>no</td>
* <td>The text color.</td></tr>
* <tr><td><tt>fontName = </tt><i>default font name of the
* renderer</i></td><td><tt>String</tt></td><td>no</td>
* <td>The name of the text font. The standard Java font name
* "Serif", "SansSerif", and "Monospaced" can be used.
* Other font names depend on the actual {@link Renderer}
* rendering the corresponding {@link BasicGraphicalElement}.
* </td></tr>
* <tr><td><tt>fontStyle = normal</tt></td><td><tt>String</tt>
* </td><td>no</td>
* <td>The font style. Possible values are:
* <ul><li><tt>normal</tt><li><tt>bold</tt><li><tt>italic</tt>
* <li><tt>bold italic</tt></ul>
* </td></tr>
* <tr><td><tt>fontSize = </tt><i>default font size of the
* renderer</i></td><td><tt>double</tt></td><td>no</td>
* <td>The font size in units of the device-independent
* coordinates.</td></tr>
* <tr><td><tt>orientationAngle = 0</tt></td><td><tt>double</tt></td>
* <td>no</td>
* <td>The orientation angle of the text (in degree).
* Zero means normal orientation whereas a positive value means
* a rotation in counter-clockweise direction.</td></tr>
* <tr><td><tt>horizontalAnchor = left</tt></td><td><tt>String</tt>
* </td><td>no</td>
* <td>Anchor for horizontal text position. Possible values are
* <tt>left</tt>, <tt>center</tt>, and <tt>right</tt>.</td></tr>
* <tr><td><tt>verticalAnchor = center</tt></td><td><tt>String</tt>
* </td><td>no</td>
* <td>Anchor for vertical text position. Possible values are
* <tt>top</tt>, <tt>center</tt>, and <tt>bottom</tt>.</td></tr>
* </table>
* Additional configuration parameters are explained in the
* {@link ShapeAttributes#ShapeAttributes constructor}
* of the superclass {@link ShapeAttributes}.
*/
public BasicGraphicAttributes(ConfigParameters config) {
super(config);
_textColor = config.getColor(TEXT_COLOR_KEY, null);
_fontName = config.get(FONT_NAME_KEY, null);
_fontStyle = FontStyle.getFontStyle(config, FONT_STYLE_KEY,
FontStyle.NORMAL);
_fontSize = config.getDouble(FONT_SIZE_KEY, 0);
_orientationAngle = config.getDouble(ORIENTATION_ANGLE_KEY, 0);
_horizontalAnchor = Anchor.getHorizontalAnchor(config,
HORIZONTAL_ANCHOR_KEY, Anchor.LEFT_BOTTOM);
_verticalAnchor = Anchor.getVerticalAnchor(config,
VERTICAL_ANCHOR_KEY, Anchor.CENTER);
}
/**
* Creates a new instance.
* @param fillColor The fill color. May be <tt>null</tt>.
* @param lineColor The line color. May be <tt>null</tt>.
* @param lineThickness Thickness of the line.
* Negative numbers will be trimmed to zero.
* @param linePattern Line pattern. May be <tt>null</tt>.
* @param textColor The text color. May be <tt>null</tt>.
* @param fontName The font name. May be <tt>null</tt>.
* @param fontStyle The font style. May be <tt>null</tt>.
* @param fontSize The font size in units of the device-independent
* coordinates. May be <tt>null</tt>.
* @param orientationAngle Orientation angle of the text.
* @param horizontalAnchor Horizontal text anchor.
* @param verticalAnchor Vertical text anchor.
*/
public BasicGraphicAttributes(Color fillColor, Color lineColor,
double lineThickness,
double[] linePattern, Color textColor,
String fontName, FontStyle fontStyle,
double fontSize, double orientationAngle,
Anchor horizontalAnchor,
Anchor verticalAnchor) {
super(fillColor, lineColor, lineThickness, linePattern);
_textColor = textColor;
_fontName = fontName;
_fontStyle = fontStyle;
_fontSize = fontSize;
_orientationAngle = orientationAngle;
_horizontalAnchor = horizontalAnchor;
_verticalAnchor = verticalAnchor;
}
/**
* Returns the text color.
* @return <tt>null</tt> means default color of the renderer.
*/
public Color getTextColor() {
return _textColor;
}
/**
* Returns the font name.
* @return <tt>null</tt> means default font name of the renderer.
*/
public String getFontName() {
return _fontName;
}
/**
* Returns the font style.
* @return <tt>null</tt> means default font style of the renderer.
*/
public FontStyle getFontStyle() {
return _fontStyle;
}
/**
* Returns the font size in units of the device-independent coordinates.
*/
public double getFontSize() {
return _fontSize;
}
/**
* Returns the orientation angle in degree. Zero means
* normal text orientation. Any positive angle means a
* counter-clockwise rotation of the text.
*/
public double getOrientationAngle() {
return _orientationAngle;
}
/**
* Returns the anchor for horizontal position of the text.
* Note, that the anchor is related to the text <em>before</em>
* it is rotated by the orientation angle.
* @return one of the three instances of <tt>Anchor</tt>.
*/
public Anchor getHorizontalAnchor() {
return _horizontalAnchor;
}
/**
* Returns the anchor for vertical position of the text.
* Note, that the anchor is related to the text <em>before</em>
* it is rotated by the orientation angle.
* @return one of the three instances of <tt>Anchor</tt>.
*/
public Anchor getVerticalAnchor() {
return _verticalAnchor;
}
}

View File

@ -1,58 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Abstract superclass of all basic {@link GraphicalElement
* GraphicalElements}. Concrete subclasses have to implement
* the method {@link GraphicalElement#renderWith}.
*
* @author Franz-Josef Elmer
*/
public abstract class BasicGraphicalElement implements GraphicalElement {
private final GraphicAttributes _attributes;
/**
* Creates an instance with the specified drawing attributes.
* Note, that a {@link Renderer} should use default attributes
* in the case no attributes are defined.
* @param attributes Drawing attributes or <tt>null</tt> if undefined.
*/
public BasicGraphicalElement(GraphicAttributes attributes) {
_attributes = attributes;
}
/**
* Returns the drawing attributes.
* @return <tt>null</tt> if undefined.
*/
public GraphicAttributes getGraphicAttributes() {
return _attributes;
}
/**
* Returns whether this basic graphical element has a closed shape
* or not. By default always <tt>true</tt>. Subclasses may override
* this behaviour.
* @return <tt>true</tt> if the shape is closed.
*/
public boolean isClosed() {
return true;
}
}

View File

@ -1,81 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Immutable class of a rectangular clipping area.
*
* @author Franz-Josef Elmer
*/
public class ClippingRectangle implements ClippingShape {
private final double _minX, _minY, _maxX, _maxY;
/**
* Creates an instance for the specified coordinates of
* two opposite corner points.
*/
public ClippingRectangle(double x1, double y1, double x2, double y2) {
_minX = Math.min(x1, x2);
_minY = Math.min(y1, y2);
_maxX = Math.max(x1, x2);
_maxY = Math.max(y1, y2);
}
/**
* Returns <tt>true</tt> if the specified point is inside this
* rectangle.
*/
public boolean isInside(GraphPoint point) {
double x = point.getX();
double y = point.getY();
return _minX <= x && x <= _maxX && _minY <= y && y <= _maxY;
}
/** Returns the minimum x value. */
public double getMinX() {
return _minX;
}
/** Returns the maximum x value. */
public double getMaxX() {
return _maxX;
}
/** Returns the minimum y value. */
public double getMinY() {
return _minY;
}
/** Returns the maximum y value. */
public double getMaxY() {
return _maxY;
}
/** Returns this instance. */
public ClippingRectangle getBoundingBox() {
return this;
}
/** Returns a {@link Rectangle}. */
public BasicGraphicalElement getGraphicalElement() {
return new Rectangle(new GraphPoint(0.5 * (_minX + _maxX),
0.5 * (_minY + _maxY)),
_maxX - _minX, _maxY - _minY, null);
}
}

View File

@ -1,47 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Defining a clipping shape applied to all {@link GraphicalElement
* GraphicalElements} of a {@link GraphicalComposite}.
*
* @author Franz-Josef Elmer
*/
public interface ClippingShape {
/**
* Returns <tt>true</tt> if the specified point is inside this
* clipping shape.
*/
public boolean isInside(GraphPoint point);
/**
* Returns the bounding box of this clipping shape.
* This method will be used by renderers who supports only
* rectangular clipping shapes.
*/
public ClippingRectangle getBoundingBox();
/**
* Returns a basic graphical element (such as {@link Rectangle}
* or {@link Polygon}) which may be used by renderers to
* define the clipping shape for the output device.
*/
public BasicGraphicalElement getGraphicalElement();
}

View File

@ -1,35 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.awt.Color;
/**
* Interface for fill attributes.
*
* @author Franz-Josef Elmer
*/
public interface FillAttributes extends GraphicAttributes {
/**
* Returns the fill color.
* @return <tt>null</tt> means no filling.
*/
public Color getFillColor();
}

View File

@ -1,82 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.util.Hashtable;
import jcckit.util.ConfigParameters;
import jcckit.util.FactoryException;
/**
* Font style constants.
* This class is based on the typesafe enumeration pattern.
*
* @author Franz-Josef Elmer
*/
public class FontStyle {
private static final Hashtable REPOSITORY = new Hashtable();
static final String NORMAL_TXT = "normal",
BOLD_TXT = "bold",
ITALIC_TXT = "italic",
BOLD_ITALIC_TXT = "bold italic";
/** Font style constant. */
public static final FontStyle NORMAL = new FontStyle(NORMAL_TXT),
BOLD = new FontStyle(BOLD_TXT),
ITALIC = new FontStyle(ITALIC_TXT),
BOLD_ITALIC = new FontStyle(BOLD_ITALIC_TXT);
private final String _description;
/** Non-public constructor to control the number of instances. */
private FontStyle(String description) {
_description = description;
REPOSITORY.put(description, this);
}
/**
* Returns from the specified configuration parameters the font style
* defined by the specified key or the specified default value.
* @param config Configuration parameters.
* @param key The key of the font style.
* @param defaultValue The default value.
* @return one of the four instances of <tt>FontStyle</tt>.
* @throws FactoryException if the value of the key-value pair denoted
* by <tt>key</tt> is neither <tt>normal</tt>, <tt>bold</tt>,
* <tt>italic</tt>, nor <tt>bold italic</tt>,
* Note, that {@link FactoryException#getClassName()}
* returns the invalid value.
*/
public static FontStyle getFontStyle(ConfigParameters config, String key,
FontStyle defaultValue) {
FontStyle result = defaultValue;
String value = config.get(key, null);
if (value != null) {
result = (FontStyle) REPOSITORY.get(value);
if (result == null) {
throw new FactoryException(config, key, "Invalid font style.");
}
}
return result;
}
/** Returns a human readable description for pretty printing. */
public String toString() {
return _description;
}
}

View File

@ -1,43 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import jcckit.util.Point;
/**
* Immutable class of a two-dimensional point in the device-independent
* coordinate system.
*
* @author Franz-Josef Elmer
*/
public class GraphPoint extends Point {
/**
* Creates an instance for the specified vector.
* If <tt>vector</tt> is <tt>null</tt> or not long enough the
* default value 0 will be used instead.
*/
public GraphPoint(double[] vector) {
super(vector);
}
/** Creates an instance for the specified coordinates. */
public GraphPoint(double x, double y) {
super(x, y);
}
}

View File

@ -1,36 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Marker interface for all types of graphic attributes
* of a {@link BasicGraphicalElement}. Graphic attributes are only
* hints for {@link Renderer Renderers} how to render a
* <tt>BasicGraphicalElement</tt>. Whether they are used and how
* they are interpreted depends on the concrete <tt>Renderer</tt>.
* <p>
* This is only a marker interface. There are several subinterfaces
* specifying various attributes grouped by the type of element to
* be rendered.
*
* @author Franz-Josef Elmer
*/
public interface GraphicAttributes {
}

View File

@ -1,106 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.util.Vector;
/**
* Container for {@link GraphicalElement GraphicalElements}.
*
* @author Franz-Josef Elmer
*/
public class GraphicalComposite implements GraphicalElement {
private final Vector _elements = new Vector();
private final ClippingShape _clippingShape;
/**
* Creates an instance with the specified clipping shape.
* @param clippingShape Clipping shape or <tt>null</tt> if no clipping.
*/
public GraphicalComposite(ClippingShape clippingShape) {
_clippingShape = clippingShape;
}
/**
* Returns the clipping shape.
* @return <tt>null</tt> if no clipping should be applied.
*/
public ClippingShape getClippingShape() {
return _clippingShape;
}
/**
* Adds the specified element at the end of the list of elements.
* @param element Element to be added. <tt>null</tt> is not allowed.
* @throws NullPointerException if <tt>element == null</tt>
*/
public void addElement(GraphicalElement element) {
if (element == null) {
throwNullPointerException();
} else {
_elements.addElement(element);
}
}
/** Remove all elements. */
public void removeAllElements() {
_elements.removeAllElements();
}
/**
* Replaces the specified element at the specified index of
* the list of elements.
* @param element New element. <tt>null</tt> is not allowed.
* @throws NullPointerException if <tt>element == null</tt>
*/
public void replaceElementAt(int index, GraphicalElement element) {
if (element == null) {
throwNullPointerException();
} else {
_elements.setElementAt(element, index);
}
}
private void throwNullPointerException() {
throw new NullPointerException(
"A null as an GraphicalElement is not allowed");
}
/**
* Renders all {@link GraphicalElement GraphicalElements} in the sequence
* they have been added.
* @param renderer Renderer which implements all renderer interfaces
* necessary to render the child elements.
* @throws IllegalArgumentException if <tt>renderer</tt> is not
* an instance of <tt>GraphicalCompositeRenderer</tt>.
*/
public void renderWith(Renderer renderer) {
if (renderer instanceof GraphicalCompositeRenderer) {
GraphicalCompositeRenderer r = (GraphicalCompositeRenderer) renderer;
r.startRendering(this);
for (int i = 0, n = _elements.size(); i < n; i++) {
((GraphicalElement) _elements.elementAt(i)).renderWith(r);
}
r.finishRendering(this);
} else {
throw new IllegalArgumentException(renderer
+ " does not implements GraphicalCompositeRenderer.");
}
}
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Interface of all {@link Renderer Renderers} who render a
* {@link GraphicalComposite}. Note, that a
* <tt>GraphicalCompositeRenderer</tt> does <em>not</em>
* render the element of a <tt>GraphicalComposite</tt>
*
* @author Franz-Josef Elmer
*/
public interface GraphicalCompositeRenderer extends Renderer {
/**
* Starts rendering of the specified composite before its
* elements are rendererd. Implementations of this method
* usually obtain the {@link ClippingShape} from
* <tt>composite</tt>.
*/
public void startRendering(GraphicalComposite composite);
/** Finishes rendering of the specified composite. */
public void finishRendering(GraphicalComposite composite);
}

View File

@ -1,41 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Interface all graphical elements have to implement.
* Together with the marker interface {@link Renderer} it
* realizes the Anticyclic Visitor Pattern, a variant of the
* GoF Visitor Pattern. This allows not only to extend JCCKit with
* new renderers but also with new types of <tt>GraphicalElements</tt>
* without touching existing code.
*
* @author Franz-Josef Elmer
*/
public interface GraphicalElement {
/**
* Renders this element according to the type of renderer.
* Concrete <tt>GraphicalElements</tt> who are not instances of
* {@link GraphicalComposite} dynamically cast <tt>renderer</tt>.
* If it does not implement the type of renderer specific for
* the concrete <tt>GraphicalElement</tt> it should throw an
* <tt>IllegalArgumentException</tt>.
*/
public abstract void renderWith(Renderer renderer);
}

View File

@ -1,52 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.awt.Color;
/**
* Interface for line attributes.
*
* @author Franz-Josef Elmer
*/
public interface LineAttributes extends GraphicAttributes {
/**
* Returns the line color.
* @return <tt>null</tt> means default color of the renderer.
*/
public Color getLineColor();
/**
* Returns the line tickness. 0 means that the line thickness is
* chosen as thin as possible.
* Implementations have to guarantee that the returned value is
* never negative.
*/
public double getLineThickness();
/**
* Returns the line pattern. This is a sequence of length where the
* pen is down or up. The first element is the length where the
* pen is down. The next element is the length where the pen is up.
* The pattern is cyclically repeated.
* @return <tt>null</tt> means solid line.
*/
public double[] getLinePattern();
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* An oval (i.e.&nbsp;an ellipse).
*
* @author Franz-Josef Elmer
*/
public class Oval extends Rectangle {
/**
* Creates a new instance.
* @param center The position of the center of this element.
* @param width The width.
* @param height The height.
* @param attributes Drawing attributes. Can be <tt>null</tt>.
*/
public Oval(GraphPoint center, double width, double height,
GraphicAttributes attributes) {
super(center, width, height, attributes);
}
/**
* Renders this oval with the specified {@link Renderer}.
* @param renderer An instance of {@link OvalRenderer}.
* @throws IllegalArgumentException if <tt>renderer</tt> is not
* an instance of <tt>OvalRenderer</tt>.
*/
public void renderWith(Renderer renderer) {
if (renderer instanceof OvalRenderer) {
((OvalRenderer) renderer).render(this);
} else {
throw new IllegalArgumentException(renderer
+ " does not implements OvalRenderer.");
}
}
}

View File

@ -1,30 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Interface of all {@link Renderer Renderers} who render a
* {@link Oval}.
*
* @author Franz-Josef Elmer
*/
public interface OvalRenderer extends Renderer {
/** Renders the specified oval. */
public void render(Oval oval);
}

View File

@ -1,85 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.util.Vector;
/**
* A polygon or polyline.
*
* @author Franz-Josef Elmer
*/
public class Polygon extends BasicGraphicalElement {
private final Vector _points = new Vector();
private final boolean _closed;
/**
* Creates an instance of the specified graphic attributes.
* @param closed <tt>true</tt> if this polygon is closed.
*/
public Polygon(GraphicAttributes attributes, boolean closed) {
super(attributes);
_closed = closed;
}
/** Returns <tt>true</tt> if this polygon is closed. */
public boolean isClosed() {
return _closed;
}
/** Returns the number points. */
public int getNumberOfPoints() {
return _points.size();
}
/** Returns the point for the specified index. */
public GraphPoint getPoint(int index) {
return (GraphPoint) _points.elementAt(index);
}
/** Adds a new point to the end of the list of points. */
public void addPoint(GraphPoint point) {
_points.addElement(point);
}
/** Removes all points. */
public void removeAllPoints() {
_points.removeAllElements();
}
/** Replaces the point at the specified index by a new one. */
public void replacePointAt(int index, GraphPoint point) {
_points.setElementAt(point, index);
}
/**
* Renders this line with the specified {@link Renderer}.
* @param renderer An instance of {@link PolygonRenderer}.
* @throws IllegalArgumentException if <tt>renderer</tt> is not
* an instance of <tt>PolygonRenderer</tt>.
*/
public void renderWith(Renderer renderer) {
if (renderer instanceof PolygonRenderer) {
((PolygonRenderer) renderer).render(this);
} else {
throw new IllegalArgumentException(renderer
+ " does not implements PolygonRenderer.");
}
}
}

View File

@ -1,30 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Interface of all {@link Renderer Renderers} who render an
* instance of {@link Polygon}.
*
* @author Franz-Josef Elmer
*/
public interface PolygonRenderer extends Renderer {
/** Renders the specified <tt>Polygon</tt> instance. */
public void render(Polygon polygon);
}

View File

@ -1,76 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* A rectangle.
*
* @author Franz-Josef Elmer
*/
public class Rectangle extends BasicGraphicalElement {
private final GraphPoint _center;
private final double _width;
private final double _height;
/**
* Creates a new instance.
* @param center The position of the center of this element.
* @param width The width.
* @param height The height.
* @param attributes Drawing attributes. Can be <tt>null</tt>.
*/
public Rectangle(GraphPoint center, double width, double height,
GraphicAttributes attributes) {
super(attributes);
_center = center;
_width = width;
_height = height;
}
/** Returns the center of this element. */
public GraphPoint getCenter() {
return _center;
}
/** Returns the width of this element. */
public double getWidth() {
return _width;
}
/** Returns the height of this element. */
public double getHeight() {
return _height;
}
/**
* Renders this rectangle with the specified {@link Renderer}.
* @param renderer An instance of {@link RectangleRenderer}.
* @throws IllegalArgumentException if <tt>renderer</tt> is not
* an instance of <tt>RectangleRenderer</tt>.
*/
public void renderWith(Renderer renderer) {
if (renderer instanceof RectangleRenderer) {
((RectangleRenderer) renderer).render(this);
} else {
throw new IllegalArgumentException(renderer
+ " does not implements RectangleRenderer.");
}
}
}

View File

@ -1,30 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Interface of all {@link Renderer Renderers} who render a
* {@link Rectangle}.
*
* @author Franz-Josef Elmer
*/
public interface RectangleRenderer extends Renderer {
/** Renders the specified rectangle. */
public void render(Rectangle rectangle);
}

View File

@ -1,27 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Marker interface. Each subclass is an interface for a specific
* type of {@link GraphicalElement}.
*
* @author Franz-Josef Elmer
*/
public interface Renderer {}

View File

@ -1,104 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.awt.Color;
import jcckit.util.ConfigParameters;
/**
* Basic attributes for shapes.
*
* @author Franz-Josef Elmer
*/
public class ShapeAttributes implements LineAttributes, FillAttributes {
/** Configuration parameter key. */
public static final String FILL_COLOR_KEY = "fillColor",
LINE_COLOR_KEY = "lineColor",
LINE_THICKNESS_KEY = "lineThickness",
LINE_PATTERN_KEY = "linePattern";
private final Color _fillColor;
private final Color _lineColor;
private final double _lineThickness;
private final double[] _linePattern;
/**
* Creates a new instance based on the specified configuration
* parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>fillColor = <i>no filling</i></tt></td><td><tt>Color</tt></td>
* <td>no</td><td>The fill color of the shape.</td></tr>
* <tr><td><tt>lineColor = <i>no line<i></tt></td><td><tt>Color</tt></td>
* <td>no</td><td>The color of a line, a polygon, or the border of a shape.</td></tr>
* <tr><td><tt>lineThickness = 0</tt></td><td><tt>double</tt></td>
* <td>no</td>
* <td>The thickness of a line. A thickness of zero means that
* the renderer will draw the thinest line possible.</td></tr>
* <tr><td><tt>linePattern = </tt><i>solid line</i></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>A sequence of lengths where the pen is alternatively
* down or up. For example, <tt>0.1 0.1</tt> will lead to a dashed
* line whereas <tt>0.02 0.02</tt> is the pattern of a dotted
* line and <tt>0.02 0.02 0.1 0.02</tt> of a dashed-dotted
* line.</td></tr>
* </table>
*/
public ShapeAttributes(ConfigParameters config) {
this(config.getColor(FILL_COLOR_KEY, null),
config.getColor(LINE_COLOR_KEY, null),
config.getDouble(LINE_THICKNESS_KEY, 0),
config.getDoubleArray(LINE_PATTERN_KEY, null));
}
/**
* Creates a new instance.
* @param fillColor The fill color. May be <tt>null</tt>.
* @param lineColor The line color. May be <tt>null</tt>.
* @param lineThickness Thickness of the line.
* Negative numbers will be trimmed to zero.
* @param linePattern Line pattern. May be <tt>null</tt>.
*/
public ShapeAttributes(Color fillColor, Color lineColor,
double lineThickness, double[] linePattern) {
_fillColor = fillColor;
_lineColor = lineColor;
_lineThickness = Math.max(0, lineThickness);
_linePattern = linePattern;
}
public Color getFillColor() {
return _fillColor;
}
public Color getLineColor() {
return _lineColor;
}
public double getLineThickness() {
return _lineThickness;
}
public double[] getLinePattern() {
return _linePattern;
}
}

View File

@ -1,67 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* A single line of text.
*
* @author Franz-Josef Elmer
*/
public class Text extends BasicGraphicalElement {
private final GraphPoint _position;
private final String _text;
/**
* Creates an instance with the specified parameters.
* @param position Position of the text.
* @param text Text.
* @param attributes Drawing attributes. Can be <tt>null</tt>.
*/
public Text(GraphPoint position, String text, GraphicAttributes attributes) {
super(attributes);
_position = position;
_text = text;
}
/** Returns the position. */
public GraphPoint getPosition() {
return _position;
}
/** Returns the text string. */
public String getText() {
return _text;
}
/**
* Renders this line with the specified {@link Renderer}.
* @param renderer An instance of {@link TextRenderer}.
* @throws IllegalArgumentException if <tt>renderer</tt> is not
* an instance of <tt>TextRenderer</tt>.
*/
public void renderWith(Renderer renderer) {
if (renderer instanceof TextRenderer) {
((TextRenderer) renderer).render(this);
} else {
throw new IllegalArgumentException(renderer
+ " does not implements TextRenderer.");
}
}
}

View File

@ -1,75 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
import java.awt.Color;
/**
* Interface for text attributes.
*
* @author Franz-Josef Elmer
*/
public interface TextAttributes extends GraphicAttributes {
/**
* Returns the text color.
* @return <tt>null</tt> means default color of the renderer.
*/
public Color getTextColor();
/**
* Returns the font name.
* @return <tt>null</tt> means default font name of the renderer.
*/
public String getFontName();
/**
* Returns the font style.
* @return <tt>null</tt> means default font style of the renderer.
*/
public FontStyle getFontStyle();
/**
* Returns the font size in units of the device-independent coordinates.
*/
public double getFontSize();
/**
* Returns the orientation angle in degree. Zero means
* normal text orientation. Any positive angle means a
* counter-clockwise rotation of the text.
*/
public double getOrientationAngle();
/**
* Returns the anchor for horizontal position of the text.
* Note, that the anchor is related to the text <em>before</em>
* it is rotated by the orientation angle.
* @return one of the three instances of <tt>Anchor</tt>.
*/
public Anchor getHorizontalAnchor();
/**
* Returns the anchor for vertical position of the text.
* Note, that the anchor is related to the text <em>before</em>
* it is rotated by the orientation angle.
* @return one of the three instances of <tt>Anchor</tt>.
*/
public Anchor getVerticalAnchor();
}

View File

@ -1,30 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.graphic;
/**
* Interface of all {@link Renderer Renderers} who render an
* instance of {@link Text}.
*
* @author Franz-Josef Elmer
*/
public interface TextRenderer extends Renderer {
/** Renders the specified <tt>Text</tt> instance. */
public void render(Text text);
}

View File

@ -1,120 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalElement;
import jcckit.util.ConfigParameters;
import jcckit.util.Factory;
/**
* Abstract superclass of all {@link SymbolFactory SymbolFactories}.
* Subclasses have to implement {@link #createPlainSymbol createPlainSymbol()}.
*
* @author Franz-Josef Elmer
*/
public abstract class AbstractSymbolFactory implements SymbolFactory {
/** Size of all symbols. */
protected final double _size;
/** Attributes of all symbols. */
protected final GraphicAttributes _attributes;
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>size = </tt>0.01</td>
* <td><tt>double</tt></td><td>no</td>
* <td>Size of the symbol in device-independent units.</td></tr>
* <tr><td><tt>attributes</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Configuration parameters for the attributes of the symbol.
* <tt>className</tt> has to be a class which is an instance of
* {@link GraphicAttributes}.</td></tr>
* </table>
*/
public AbstractSymbolFactory(ConfigParameters config) {
_size = config.getDouble(SIZE_KEY, DEFAULT_SIZE);
_attributes = (GraphicAttributes) Factory.createOrGet(
config.getNode(ATTRIBUTES_KEY), null);
}
/**
* Creates a symbol.
* Evaluate <tt>hintFromPreviousPoint</tt> if it is a {@link AttributesHint}.
* Calls {@link #createSymbol(GraphPoint, GraphicAttributes, Hint, Hint)}.
* @param point Symbol position.
* @param hintFromPreviousPoint Hint from the previous point.
* @param hintFromPreviousCurve Hint from the previous curve.
*/
public Symbol createSymbol(GraphPoint point, Hint hintFromPreviousPoint,
Hint hintFromPreviousCurve) {
GraphicAttributes attributes = _attributes;
Hint hintForNextPoint = hintFromPreviousPoint;
if (hintFromPreviousPoint instanceof AttributesHint) {
attributes = ((AttributesHint) hintFromPreviousPoint).getAttributes();
hintForNextPoint
= ((AttributesHint) hintFromPreviousPoint).getNextHint();
}
return createSymbol(point, attributes, hintForNextPoint,
hintFromPreviousCurve);
}
/**
* Creates a symbol.
* Uses {@link #createPlainSymbol createPlainSymbol()}.
* @param point Symbol position.
* @param attributes Symbol attributes.
* @param hintForNextPoint Hint for the next point. Will be delivered
* unchanged in the return <tt>Symbol</tt> object.
* @param hintFromPreviousCurve Hint from the previous curve.
* Will be delivered unchanged in the return <tt>Symbol</tt> object.
* Subclasses may override this behavior.
*/
protected Symbol createSymbol(GraphPoint point, GraphicAttributes attributes,
Hint hintForNextPoint,
Hint hintFromPreviousCurve) {
return new Symbol(createPlainSymbol(point, _size, attributes),
hintForNextPoint, hintFromPreviousCurve);
}
/**
* Creates a symbol for the legend at the specified position.
* Uses {@link #createPlainSymbol createPlainSymbol()}
* @param centerPosition Center position of the symbol.
* @param size The size of the symbol. Will be ignored because the value
* given in the constructor will be used.
*/
public GraphicalElement createLegendSymbol(GraphPoint centerPosition,
double size) {
return createPlainSymbol(centerPosition, _size, _attributes);
}
/**
* Creates the graphical element of the plain symbol.
* @param centerPosition Center position of the symbol.
* @param size The size of the symbol.
* @param attributes The attributes of the symbol.
*/
protected abstract GraphicalElement createPlainSymbol(
GraphPoint centerPosition, double size, GraphicAttributes attributes);
}

View File

@ -1,39 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphicAttributes;
/**
* A {@link Hint} which wraps a {@link GraphicAttributes} instance.
* In addition the method {@link #getNextHint()} creates a new instance
* with different attributes derivated from the wrapped attributes.
*
* @author Franz-Josef Elmer
*/
public interface AttributesHint extends Hint {
/**
* Returns the hint for the next {@link Symbol} of a {@link Curve}.
* The new hint has a different {@link GraphicAttributes}.
*/
public AttributesHint getNextHint();
/** Returns the attributes value. */
public GraphicAttributes getAttributes();
}

View File

@ -1,496 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import java.util.Properties;
import jcckit.graphic.BasicGraphicAttributes;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.LineAttributes;
import jcckit.graphic.ShapeAttributes;
import jcckit.graphic.TextAttributes;
import jcckit.util.ConfigData;
import jcckit.util.ConfigParameters;
import jcckit.util.ConfigParametersBasedConfigData;
import jcckit.util.Factory;
import jcckit.util.Format;
import jcckit.util.PropertiesBasedConfigData;
import jcckit.util.TicLabelFormat;
import jcckit.util.Util;
/**
* Helper class with various parameters defining an axis.
* This helper class is used by {@link CartesianCoordinateSystem}
* to set up a coordinate systems.
* <p>
* This class holds more than a dozen parameters. There are two factory
* methods creating instances for x- and y-axis based on
* {@link ConfigParameters}. They differ in their default parameters for
* those axes.
* <p>
* Note, that there is a direct access of these parameters without getters
* and setters but only for classes in the package <tt>jcckit.plot</tt>.
*
* @author Franz-Josef Elmer
*/
public class AxisParameters {
/** Configuration parameter key. */
public static final String LOG_SCALE_KEY = "logScale",
MINIMUM_KEY = "minimum",
MAXIMUM_KEY = "maximum",
AXIS_LENGTH_KEY = "axisLength",
AXIS_ATTRIBUTES_KEY = "axisAttributes",
AXIS_LABEL_KEY = "axisLabel",
AXIS_LABEL_POSITION_KEY = "axisLabelPosition",
AXIS_LABEL_ATTRIBUTES_KEY = "axisLabelAttributes",
AUTOMATIC_TIC_CALCULATION_KEY
= "automaticTicCalculation",
MINIMUM_TIC_KEY = "minimumTic",
MAXIMUM_TIC_KEY = "maximumTic",
NUMBER_OF_TICS_KEY = "numberOfTics",
TIC_LENGTH_KEY = "ticLength",
TIC_ATTRIBUTES_KEY = "ticAttributes",
TIC_LABEL_FORMAT_KEY = "ticLabelFormat",
TIC_LABEL_POSITION_KEY = "ticLabelPosition",
TIC_LABEL_ATTRIBUTES_KEY = "ticLabelAttributes",
GRID_KEY = "grid",
GRID_ATTRIBUTES_KEY = "gridAttributes";
private static final double LN10 = Math.log(10);
/** If <tt>true</tt> the scale is logarithmic otherwise linear. */
boolean logScale;
/** Minimum data value represented by the axis. */
double minimum;
/** Maximum data value represented by the axis. */
double maximum;
/** Length of the axis in device-independent graphical units. */
double axisLength;
/**
* Line attributes of the axis.
* Can be <tt>null</tt> which means default attributes.
*/
LineAttributes axisAttributes;
boolean automaticTicCalculation;
double minimumTic;
double maximumTic;
int numberOfTics;
/**
* Length of the tics in device-independent graphical units.
* If 0 no tics and tics label will be drawn.
*/
double ticLength;
/**
* Attributes of the tics.
* Can be <tt>null</tt> which means default attributes.
*/
LineAttributes ticAttributes;
/** Tic label formatter. */
TicLabelFormat ticLabelFormat;
/** Position of the tic label relative to the tic. */
GraphPoint ticLabelPosition;
/** Text attributes of the tic labels. */
TextAttributes ticLabelAttributes;
/** If <tt>true</tt> grid lines are drawn. */
boolean grid;
/**
* Attributes of the grid lines.
* Can be <tt>null</tt> which means default attributes.
*/
LineAttributes gridAttributes;
/** Axis label. */
String axisLabel;
/** Position of the axis label relative to the center of the axis. */
GraphPoint axisLabelPosition;
/** Text attributes of the axis label. */
TextAttributes axisLabelAttributes;
/**
* Calculate the tics based on <tt>minimumTic</tt>, <tt>maximumTic</tt>,
* and <tt>numberOfTics</tt>. If <tt>automaticTicCalculation == true</tt>
* appropriated values for these fields are calculated.
*/
double[] calculateTics() {
if (automaticTicCalculation) {
calculateTicsParameters();
}
double[] result = new double[numberOfTics];
if (numberOfTics > 0) {
double b = Util.log(minimumTic, logScale);
double a = Util.log(maximumTic, logScale);
a = numberOfTics > 1 ? (a - b) / (numberOfTics - 1) : 0;
for (int i = 0; i < result.length; i++) {
result[i] = Util.exp(a * i + b, logScale);
}
result[0] = adjust(minimum, result[0]);
result[numberOfTics - 1] = adjust(maximum, result[numberOfTics - 1]);
}
return result;
}
private void calculateTicsParameters() {
double min = Math.min(minimum, maximum);
double max = Math.max(minimum, maximum);
if (logScale) {
int minExponent = (int) (199.9999 + Math.log(min) / LN10) - 199;
int maxExponent = (int) (200.0001 + Math.log(max) / LN10) - 200;
minimumTic = Math.exp(LN10 * minExponent);
maximumTic = Math.exp(LN10 * maxExponent);
numberOfTics = maxExponent - minExponent + 1;
} else {
int baseExponent = (int) (199.69 + Math.log(max - min) / LN10) - 200;
double base = 0.2 * Math.exp(LN10 * baseExponent);
do
{
base *= 5;
int minInt = (int) (999999.999999 + min / base) - 999999;
int maxInt = (int) (1000000.000001 + max / base) - 1000000;
minimumTic = minInt * base;
maximumTic = maxInt * base;
numberOfTics = maxInt - minInt + 1;
} while (numberOfTics > 11);
}
}
/**
* Returns <tt>adjustingValue</tt> if <tt>value</tt> is very close
* to <tt>adjustingValue</tt>. Otherwise <tt>value</tt> is returned.
*/
private static double adjust(double adjustingValue, double value) {
return value != 0 && Math.abs(adjustingValue / value - 1) < 1e-11
? adjustingValue : value;
}
/**
* Returns a <tt>Properties</tt> object with those default parameters
* which are common for x- and y-axis.
*/
private static Properties createDefaultAxisProperties() {
Properties p = new Properties();
p.put(LOG_SCALE_KEY, "false");
p.put(MINIMUM_KEY, "0");
p.put(MAXIMUM_KEY, "1");
p.put(AXIS_LENGTH_KEY, "0.8");
p.put(AXIS_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
ShapeAttributes.class.getName());
p.put(AXIS_LABEL_KEY, "x");
p.put(AXIS_LABEL_POSITION_KEY, "0 -0.05");
p.put(AXIS_LABEL_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
BasicGraphicAttributes.class.getName());
p.put(AXIS_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.HORIZONTAL_ANCHOR_KEY, "center");
p.put(AUTOMATIC_TIC_CALCULATION_KEY, "true");
p.put(TIC_LENGTH_KEY, "0.01");
p.put(TIC_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
ShapeAttributes.class.getName());
p.put(TIC_LABEL_POSITION_KEY, "0 -0.01");
p.put(TIC_LABEL_FORMAT_KEY, "%1.1f");
p.put(TIC_LABEL_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
BasicGraphicAttributes.class.getName());
p.put(TIC_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.HORIZONTAL_ANCHOR_KEY, "center");
p.put(TIC_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.VERTICAL_ANCHOR_KEY, "top");
p.put(GRID_KEY, "false");
p.put(GRID_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
ShapeAttributes.class.getName());
return p;
}
/**
* Returns a <tt>Properties</tt> object of the default parameters for
* an x-axis.
*/
private static Properties createDefaultXAxisProperties() {
Properties p = createDefaultAxisProperties();
p.put(AXIS_LABEL_KEY, "x");
p.put(AXIS_LABEL_POSITION_KEY, "0 -0.05");
p.put(AXIS_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.VERTICAL_ANCHOR_KEY, "top");
p.put(TIC_LABEL_POSITION_KEY, "0 -0.01");
p.put(TIC_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.HORIZONTAL_ANCHOR_KEY, "center");
p.put(TIC_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.VERTICAL_ANCHOR_KEY, "top");
return p;
}
/**
* Creates an x axis based on the specified configuration parameters.
* All numbers (lengths, fontsizes, linethicknesses, etc.) are in
* device-independent units.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>automaticTicCalculation = true</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>Has to be <tt>true</tt> if the tics should be calculated
* automatically.</td></tr>
* <tr><td><tt>axisAttributes = </tt>default values of
* {@link ShapeAttributes}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Attributes of the axis box.</td></tr>
* <tr><td><tt>axisLabel = x</tt></td>
* <td><tt>String</tt></td><td>no</td>
* <td>Axis label.</td></tr>
* <tr><td><tt>axisLabelAttributes = </tt>default values of
* {@link BasicGraphicAttributes} with a text anchor CENTER
* TOP.</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Text attributes of axis label.</td></tr>
* <tr><td><tt>axisLabelPosition = 0 -0.05</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Position of the anchor of the axis
* label relative to the center of the x-axis line.</td></tr>
* <tr><td><tt>axisLength = 0.8</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Length of the x-axis.</td></tr>
* <tr><td><tt>grid = false</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> grid lines will be drawn through the axis
* tics.</td></tr>
* <tr><td><tt>gridAttributes = </tt>default values of
* {@link ShapeAttributes}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Attributes of the grid lines.</td></tr>
* <tr><td><tt>logScale = false</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> the axis will be logarithmic. Otherwise
* the axis is linear.</td></tr>
* <tr><td><tt>maximum = 1</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of one end of the axis.</td></tr>
* <tr><td><tt>maximumTic = </tt>result from automatic calculation</td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of the tic nearest the maximum end
* of the axis.</td></tr>
* <tr><td><tt>minimum = 0</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of one end of the axis.</td></tr>
* <tr><td><tt>minimumTic = </tt>result from automatic calculation</td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of the tic nearest the minimum end
* of the axis.</td></tr>
* <tr><td><tt>numberOfTics = </tt>result from automatic calculation</td>
* <td><tt>int</tt></td><td>no</td>
* <td>Number of tics. The tics between the minimum and maximum tic
* are spaced equidistantly.</td></tr>
* <tr><td><tt>ticAttributes = </tt>default values of
* {@link ShapeAttributes}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Attributes of the tics.</td></tr>
* <tr><td><tt>ticLabelAttributes = </tt>default values of
* {@link BasicGraphicAttributes} with a text anchor CENTER
* TOP.</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Text attributes of tic labels.</td></tr>
* <tr><td><tt>ticLabelFormat = %1.1f</tt></td>
* <td><tt>String</tt> or <tt>ConfigParameters</tt></td><td>no</td>
* <td>Defines rendering of the tic label. By default a
* <tt>printf</tt>-like format string is given (see {@link Format}).
* Note, that an empty string means that tic labels are dropped.
* <p>
* For non-numerical rendering an implementation of a
* {@link TicLabelFormat} can be specified (e.g.
* {@link TicLabelMap}). Note, that a configuration sub tree with
* a <tt>className</tt> key-value pair overwrites any string
* definition.</td></tr>
* <tr><td><tt>ticLabelPosition = 0 -0.01</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Position of the anchor of the tic label relative to the
* tic position on the axis.</td></tr>
* <tr><td><tt>ticLength = 0.01</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Length of the tics. Negative/positive values mean tics
* inside/outside the box.</td></tr>
* </table>
*/
public static AxisParameters createXAxis(ConfigParameters config) {
return createAxis(config, createDefaultXAxisProperties());
}
/**
* Returns a <tt>Properties</tt> object of the default parameters for
* an x-axis.
*/
private static Properties createDefaultYAxisProperties() {
Properties p = createDefaultAxisProperties();
p.put(AXIS_LENGTH_KEY, "0.45");
p.put(AXIS_LABEL_KEY, "y");
p.put(AXIS_LABEL_POSITION_KEY, "-0.1 0");
p.put(AXIS_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.VERTICAL_ANCHOR_KEY, "bottom");
p.put(AXIS_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.ORIENTATION_ANGLE_KEY, "90");
p.put(TIC_LABEL_POSITION_KEY, "-0.01 0");
p.put(TIC_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.HORIZONTAL_ANCHOR_KEY, "right");
p.put(TIC_LABEL_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.VERTICAL_ANCHOR_KEY, "center");
return p;
}
/**
* Creates an y axis based on the specified configuration parameters.
* All numbers (lengths, fontsizes, linethicknesses, etc.) are in
* device-independent units.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>automaticTicCalculation = true</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>Has to be <tt>true</tt> if the tics should be calculated
* automatically.</td></tr>
* <tr><td><tt>axisAttributes = </tt>default values of
* {@link ShapeAttributes}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Attributes of the axis box.</td></tr>
* <tr><td><tt>axisLabel = y</tt></td>
* <td><tt>String</tt></td><td>no</td>
* <td>Axis label.</td></tr>
* <tr><td><tt>axisLabelAttributes = </tt>default values of
* {@link BasicGraphicAttributes} with a text anchor CENTER
* BOTTOM and the text rotated by 90 degree.</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Text attributes of axis label.</td></tr>
* <tr><td><tt>axisLabelPosition = -0.1 0</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Position of the anchor of the axis
* label relative to the center of the y-axis line.</td></tr>
* <tr><td><tt>axisLength = 0.45</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Length of the y-axis.</td></tr>
* <tr><td><tt>grid = false</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> grid lines will be drawn through the axis
* tics.</td></tr>
* <tr><td><tt>gridAttributes = </tt>default values of
* {@link ShapeAttributes}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Attributes of the grid lines.</td></tr>
* <tr><td><tt>logScale = false</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> the axis will be logarithmic. Otherwise
* the axis is linear.</td></tr>
* <tr><td><tt>maximum = 1</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of one end of the axis.</td></tr>
* <tr><td><tt>maximumTic = </tt>result from automatic calculation</td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of the tic nearest the maximum end
* of the axis.</td></tr>
* <tr><td><tt>minimum = 0</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of one end of the axis.</td></tr>
* <tr><td><tt>minimumTic = </tt>result from automatic calculation</td>
* <td><tt>double</tt></td><td>no</td>
* <td>The corresponding data value of the tic nearest the minimum end
* of the axis.</td></tr>
* <tr><td><tt>numberOfTics = </tt>result from automatic calculation</td>
* <td><tt>int</tt></td><td>no</td>
* <td>Number of tics. The tics between the minimum and maximum tic
* are spaced equidistantly.</td></tr>
* <tr><td><tt>ticAttributes = </tt>default values of
* {@link ShapeAttributes}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Attributes of the tics.</td></tr>
* <tr><td><tt>ticLabelAttributes = </tt>default values of
* {@link BasicGraphicAttributes} with a text anchor RIGHT CENTER.
* </td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Text attributes of tic labels.</td></tr>
* <tr><td><tt>ticLabelFormat = %1.1f</tt></td>
* <td><tt>String</tt></td><td>no</td>
* <td>Defines rendering of the tic label. By default a
* <tt>printf</tt>-like format string is given (see {@link Format}).
* Note, that an empty string means that tic labels are dropped.
* <p>
* For non-numerical rendering an implementation of a
* {@link TicLabelFormat} can be specified (e.g.
* {@link TicLabelMap}). Note, that a configuration sub tree with
* a <tt>className</tt> key-value pair overwrites any string
* definition.</td></tr>
* <tr><td><tt>ticLabelPosition = -0.01 0</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Position of the anchor of the tic label relative to the
* tic position on the axis.</td></tr>
* <tr><td><tt>ticLength = 0.01</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Length of the tics. Negative/positive values mean tics
* inside/outside the box.</td></tr>
* </table>
*/
public static AxisParameters createYAxis(ConfigParameters config) {
return createAxis(config, createDefaultYAxisProperties());
}
private static AxisParameters createAxis(ConfigParameters config,
Properties p) {
ConfigData cd = new PropertiesBasedConfigData(p);
ConfigParameters c = new ConfigParameters(cd);
cd = new ConfigParametersBasedConfigData(config, c);
c = new ConfigParameters(cd);
AxisParameters a = new AxisParameters();
a.logScale = c.getBoolean(LOG_SCALE_KEY);
a.minimum = c.getDouble(MINIMUM_KEY);
a.maximum = c.getDouble(MAXIMUM_KEY);
a.axisLength = c.getDouble(AXIS_LENGTH_KEY);
a.axisAttributes
= (LineAttributes) Factory.create(c.getNode(AXIS_ATTRIBUTES_KEY));
a.axisLabel = c.get(AXIS_LABEL_KEY);
a.axisLabelPosition
= new GraphPoint(c.getDoubleArray(AXIS_LABEL_POSITION_KEY));
a.axisLabelAttributes = (TextAttributes) Factory.create(
c.getNode(AXIS_LABEL_ATTRIBUTES_KEY));
a.ticLength = c.getDouble(TIC_LENGTH_KEY);
a.automaticTicCalculation
= c.getBoolean(AUTOMATIC_TIC_CALCULATION_KEY);
if (!a.automaticTicCalculation) {
a.calculateTicsParameters(); // calculate default parameters
a.minimumTic = c.getDouble(MINIMUM_TIC_KEY, a.minimumTic);
a.maximumTic = c.getDouble(MAXIMUM_TIC_KEY, a.maximumTic);
a.numberOfTics = c.getInt(NUMBER_OF_TICS_KEY, a.numberOfTics);
}
a.ticAttributes
= (LineAttributes) Factory.create(c.getNode(TIC_ATTRIBUTES_KEY));
a.ticLabelFormat = createTicLabelFormat(c);
a.ticLabelPosition
= new GraphPoint(c.getDoubleArray(TIC_LABEL_POSITION_KEY));
a.ticLabelAttributes = (TextAttributes) Factory.create(
c.getNode(TIC_LABEL_ATTRIBUTES_KEY));
a.grid = c.getBoolean(GRID_KEY);
a.gridAttributes
= (LineAttributes) Factory.create(c.getNode(GRID_ATTRIBUTES_KEY));
return a;
}
private static TicLabelFormat createTicLabelFormat(ConfigParameters c)
{
TicLabelFormat result = Format.create(c, TIC_LABEL_FORMAT_KEY);
ConfigParameters node = c.getNode(TIC_LABEL_FORMAT_KEY);
if (node.get(Factory.CLASS_NAME_KEY, null) != null) {
result = (TicLabelFormat) Factory.create(node);
}
return result;
}
}

View File

@ -1,131 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.ClippingShape;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.Rectangle;
import jcckit.util.ConfigParameters;
/**
* A factory of bars. The bars are {@link Rectangle Rectangles}.
* Depending on the configuration parameters the bars can be
* horizontal or vertical. Bars of several curves can be side by side or
* stacked. The bar length is determined by the x or y value of the
* curve point in device-independent coordinates. If the value is negative
* the bar goes into the negative direction. For stacked bars the values
* should always be positive.
* <p>
* When used inside a {@link SimpleCurve} soft clipping should always be
* switched off (see
* {@link SimpleCurve#SimpleCurve(ConfigParameters, int, int, ClippingShape, Legend)}).
*
* @author Franz-Josef Elmer
*/
public class BarFactory extends AbstractSymbolFactory {
/** Configuration parameter key. */
public static final String STACKED_KEY = "stacked",
HORIZONTAL_BARS_KEY = "horizontalBars";
private final boolean _stacked;
private final boolean _horizontalBars;
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>horizontalBars = false</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> horizontal bars will be drawn. Otherwise
* vertical bars are drawn.</td></tr>
* <tr><td><tt>stacked = false</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> the bars of several curves will be
* stacked.</td></tr>
* </table>
* In addition the configuration parameters of the
* <a href="AbstractSymbolFactory.html#AbstractSymbolFactory(jcckit.util.ConfigParameters)">
* constructor</a> of the superclass {@link AbstractSymbolFactory} apply.
*/
public BarFactory(ConfigParameters config) {
super(config);
_horizontalBars = config.getBoolean(HORIZONTAL_BARS_KEY, false);
_stacked = config.getBoolean(STACKED_KEY, false);
}
/**
* Creates a bar at the specified point.
* If <tt>hintFromPreviousCurve</tt>
* is not an instance of {@link PositionHint} the values of
* origin and position will be (0,0).
* @param hintFromPreviousCurve Hint from previous curve. Will be used
* to calculate symbol shape and hint for the next curve.
*/
protected Symbol createSymbol(GraphPoint point, GraphicAttributes attributes,
Hint hintForNextPoint,
Hint hintFromPreviousCurve) {
GraphPoint origin = new GraphPoint(null);
GraphPoint position = origin;
if (hintFromPreviousCurve instanceof PositionHint) {
origin = ((PositionHint) hintFromPreviousCurve).getOrigin();
position = ((PositionHint) hintFromPreviousCurve).getPosition();
}
double px = position.getX();
double py = position.getY();
double x = point.getX() - origin.getX();
double y = point.getY() - origin.getY();
if (_horizontalBars) {
y = _size;
position = new GraphPoint(px + 0.5 * x, point.getY() + py);
px += _stacked ? x : 0;
py += _stacked ? 0 : _size;
} else {
x = _size;
position = new GraphPoint(point.getX() + px, py + 0.5 * y);
px += _stacked ? 0 : _size;
py += _stacked ? y : 0;
}
Hint hintForNextCurve = new PositionHint(origin, new GraphPoint(px, py));
return new Symbol(new Rectangle(position, Math.abs(x), Math.abs(y),
attributes),
hintForNextPoint, hintForNextCurve);
}
/**
* Creates a symbol for the legend at the specified position.
* @param centerPosition Center position of the symbol.
* @param size The size of the symbol.
*/
public GraphicalElement createLegendSymbol(GraphPoint centerPosition,
double size) {
return new Rectangle(centerPosition, size, size, _attributes);
}
/**
* Returns <tt>null</tt> because this method isn't needed but has to be
* implemented.
*/
protected GraphicalElement createPlainSymbol(
GraphPoint centerPosition, double size, GraphicAttributes attributes) {
return null;
}
}

View File

@ -1,206 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.data.DataPoint;
import jcckit.graphic.ClippingRectangle;
import jcckit.graphic.ClippingShape;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalComposite;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.LineAttributes;
import jcckit.graphic.Polygon;
import jcckit.graphic.Text;
import jcckit.transformation.CartesianTransformation;
import jcckit.transformation.Transformation;
import jcckit.util.ConfigParameters;
/**
* A Cartesian coordinate system. One or both axes can be logarithmic.
*
* @author Franz-Josef Elmer
*/
public class CartesianCoordinateSystem implements CoordinateSystem {
/** Configuration parameter key. */
public static final String ORIGIN_KEY = "origin",
X_AXIS_KEY = "xAxis",
Y_AXIS_KEY = "yAxis";
private final CartesianTransformation _transformation;
private final GraphicalComposite _view;
private final ClippingRectangle _clippingRectangle;
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>origin = 0.15,&nbsp;0.1</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Position (in device-independent coordinates) of the lower-left
* corner of the axis box.</td></tr>
* <tr><td><tt>xAxis</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Parameters defining the x-axis. For definitions and default
* values see {@link AxisParameters#createXAxis
* AxisParameters.createXAxis()}.</td></tr>
* <tr><td><tt>yAxis</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Parameters defining the y-axis. For definitions and default
* values see {@link AxisParameters#createYAxis
* AxisParameters.createYAxis()}.</td></tr>
* </table>
*/
public CartesianCoordinateSystem(ConfigParameters config) {
this(new GraphPoint(config.getDoubleArray(ORIGIN_KEY,
new double[] {0.15, 0.1})),
AxisParameters.createXAxis(config.getNode(X_AXIS_KEY)),
AxisParameters.createYAxis(config.getNode(Y_AXIS_KEY)));
}
/**
* Creates an instance for the specified origin and parameters
* of both axes.
* @param origin Position (in device-independent coordinates) of the
* lower-left corner of the axis box.
* @param xAxisParameters Parameters of the x-axis.
* @param yAxisParameters Parameters of the y-axis.
*/
public CartesianCoordinateSystem(GraphPoint origin,
AxisParameters xAxisParameters,
AxisParameters yAxisParameters) {
double x = origin.getX();
double y = origin.getY();
_transformation = new CartesianTransformation(xAxisParameters.logScale,
yAxisParameters.logScale,
new DataPoint(xAxisParameters.minimum, yAxisParameters.minimum),
new GraphPoint(x, y),
new DataPoint(xAxisParameters.maximum, yAxisParameters.maximum),
new GraphPoint(x + xAxisParameters.axisLength,
y + yAxisParameters.axisLength));
_clippingRectangle = new ClippingRectangle(x, y,
x + xAxisParameters.axisLength,
y + yAxisParameters.axisLength);
_view = new GraphicalComposite(null);
createView(origin, xAxisParameters, yAxisParameters);
}
/** Creates the graphical representation of this coordinate system. */
private void createView(GraphPoint origin,
AxisParameters xAxisParameters,
AxisParameters yAxisParameters) {
double x0 = origin.getX();
double x1 = x0 + xAxisParameters.axisLength;
double y0 = origin.getY();
double y1 = y0 + yAxisParameters.axisLength;
GraphPoint lowerLeftCorner = new GraphPoint(x0, y0);
GraphPoint upperLeftCorner = new GraphPoint(x0, y1);
GraphPoint lowerRightCorner = new GraphPoint(x1, y0);
GraphPoint upperRightCorner = new GraphPoint(x1, y1);
LineAttributes xLineAttributes = xAxisParameters.axisAttributes;
LineAttributes yLineAttributes = yAxisParameters.axisAttributes;
createTicsAndGrid(true, y0, y1, xAxisParameters);
createTicsAndGrid(false, x0, x1, yAxisParameters);
addLine(lowerLeftCorner, lowerRightCorner, xLineAttributes);
addLine(lowerLeftCorner, upperLeftCorner, yLineAttributes);
addLine(upperLeftCorner, upperRightCorner, xLineAttributes);
addLine(lowerRightCorner, upperRightCorner, yLineAttributes);
createLabel(0.5 * (x0 + x1), y0, xAxisParameters);
createLabel(x0, 0.5 * (y0 + y1), yAxisParameters);
}
private void createLabel(double x, double y, AxisParameters parameters) {
if (parameters.axisLabel.length() > 0) {
_view.addElement(new Text(
new GraphPoint(x + parameters.axisLabelPosition.getX(),
y + parameters.axisLabelPosition.getY()),
parameters.axisLabel, parameters.axisLabelAttributes));
}
}
private void createTicsAndGrid(boolean isXAxis, double low, double high,
AxisParameters parameters) {
double[] tics = parameters.calculateTics();
int offIndex = isXAxis ? 1 : 0;
double[] point = new double[2]; // helper array
for (int i = 0; i < tics.length; i++) {
point[1 - offIndex] = tics[i];
point[offIndex] = 1;
GraphPoint gPoint1 =
_transformation.transformToGraph(new DataPoint(point[0], point[1]));
point[0] = gPoint1.getX();
point[1] = gPoint1.getY();
point[offIndex] = high;
gPoint1 = new GraphPoint(point[0], point[1]);
point[offIndex] += parameters.ticLength;
addLine(gPoint1, new GraphPoint(point[0], point[1]),
parameters.ticAttributes);
point[offIndex] = low;
GraphPoint gPoint2 = new GraphPoint(point[0], point[1]);
if (parameters.grid) {
addLine(gPoint1, gPoint2, parameters.gridAttributes);
}
point[offIndex] -= parameters.ticLength;
addLine(gPoint2, new GraphPoint(point[0], point[1]),
parameters.ticAttributes);
if (parameters.ticLabelFormat != null) {
point[offIndex] += parameters.ticLength;
point[0] += parameters.ticLabelPosition.getX();
point[1] += parameters.ticLabelPosition.getY();
_view.addElement(new Text(new GraphPoint(point[0], point[1]),
parameters.ticLabelFormat.form(tics[i]),
parameters.ticLabelAttributes));
}
}
}
private void addLine(GraphPoint point1, GraphPoint point2,
GraphicAttributes attributes) {
Polygon line = new Polygon(attributes, false);
line.addPoint(point1);
line.addPoint(point2);
_view.addElement(line);
}
/**
* Returns the graphical representation of the coordinate system.
* In each call the same instance is returned.
*/
public GraphicalElement getView() {
return _view;
}
/**
* Returns the clipping rectangle of specified by the axis.
* In each call the same instance is returned.
*/
public ClippingShape getClippingShape() {
return _clippingRectangle;
}
/**
* Returns the transformation of data coordinates into the device-independent
* coordinates of the axis box.
* In each call the same instance is returned.
*/
public Transformation getTransformation() {
return _transformation;
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.Oval;
import jcckit.util.ConfigParameters;
/**
* A factory of circle symbols.
*
* @author Franz-Josef Elmer
*/
public class CircleSymbolFactory extends AbstractSymbolFactory {
/**
* Creates an instance from the specified configuration parameters.
* For the configuration parameters see the
* <a href="AbstractSymbolFactory.html#AbstractSymbolFactory(jcckit.util.ConfigParameters)">
* constructor</a> of the superclass {@link AbstractSymbolFactory}.
*/
public CircleSymbolFactory(ConfigParameters config) {
super(config);
}
/**
* Creates a circle.
* @param centerPosition Position of the center of the circle.
* @param size Diameter of the circle.
* @param attributes Circle attributes.
*/
protected GraphicalElement createPlainSymbol(GraphPoint centerPosition,
double size,
GraphicAttributes attributes) {
return new Oval(centerPosition, size, size, attributes);
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.ClippingShape;
import jcckit.graphic.GraphicalElement;
import jcckit.transformation.Transformation;
/**
* Interface for all generators of coordinate systems. A
* <tt>CoordinateSystem</tt> creates a
* {@link jcckit.graphic.GraphicalComposite} which contains all the
* {@link GraphicalElement GraphicalElements} defining axes, labels, grid, etc.
*
* @author Franz-Josef Elmer
*/
public interface CoordinateSystem {
/**
* Returns the graphical representation of a coordinate
* system. Different invocations of this method may return
* different coordinate systems, e.g., due to changes in the
* transformation or clipping shapes.
*/
public GraphicalElement getView();
/**
* Returns the clipping chape of {@link Curve Curves} drawn on top
* of the coordinates system. Different invocations of
* this method may return different clipping shapes.
*/
public ClippingShape getClippingShape();
/**
* Returns the transformation between data coordinates and
* device-independent graphcial coordinates. Different invocations
* of this method may return different transformations.
*/
public Transformation getTransformation();
}

View File

@ -1,64 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicalElement;
/**
* A curve is defined by a sequence of points in device-independent
* coordinates. The points can be decorated by symbols and/or
* connected by lines.{@link Hint Hints} are used to determine additional
* properties of the symbol. This is especially important for
* charts with bars.
* <p>
* In accordance with the Factory Method Pattern
* the symbols are created by a {@link SymbolFactory}.
*
* @author Franz-Josef Elmer
*/
public interface Curve {
/**
* Returns the graphical representation of a curve.
* Different invocations of this method might return
* different instances.
* This is especially true after adding, inserting, removing, or
* repplacing a point of the curve.
*/
public GraphicalElement getView();
/**
* Returns a symbol which can be used to create the legend for the curve.
* For example, it should return a horizontal line with the symbol
* in the middle if the curve is a line with points decorated by symbols.
*/
public GraphicalElement getLegendSymbol();
/**
* Appends a new point to the curve.
* @param point Position in device-independent coordinates.
* @param hintFromPreviousCurve Hint which may be used to calculate
* the corresponding {@link GraphicalElement}.
* @return hint for next curve.
*/
public Hint addPoint(GraphPoint point, Hint hintFromPreviousCurve);
/** Removes all points from the curve. */
public void removeAllPoints();
}

View File

@ -1,42 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.ClippingShape;
/**
* Interface of a curve factory. A curve factory creates a new instance
* of a {@link Curve}.
*
* @author Franz-Josef Elmer
*/
public interface CurveFactory {
/**
* Creates a new curve instance.
* @param curveIndex The index of the curve in the {@link Plot} to which
* it should belong.
* @param numberOfCurves Number of curves. Will be needed to calculate the
* y-coordinate of the legend symbol.
* @param clippingShape Clipping shape applied to the curve.
* @param legend The legend which will show the curve symbol.
* @return an empty instance.
*/
public Curve create(int curveIndex, int numberOfCurves,
ClippingShape clippingShape, Legend legend);
}

View File

@ -1,136 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalComposite;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.Rectangle;
import jcckit.util.ConfigParameters;
import jcckit.util.Factory;
/**
* Symbol factory for creating symbols with error bars. It wraps
* a {@link SymbolFactory} for creating the symbol. The error bars
* are {@link Rectangle Rectangles}.
* <p>
* Curves with error bars are based on <em>two</em>
* {@link jcckit.data.DataCurve DataCurves}:
* <ol><li>The plain curve.
* <li>An instance which stores the errors in <i>x</i> and <i>y</i>.
* It is assumed that the errors are positive values defining
* the error symmetrically around the curve points.
* </ol>
* <p>
* The <tt>ErrorBarFactory</tt> needs an instance of {@link PositionHint}
* as initial {@link Hint} for the next curve. Its origin must be
* the origin of the data coordinate system in device-independent coordinates.
* The position of <tt>PositionHint</tt> must be undefined.
*
* @author Franz-Josef Elmer
*/
public class ErrorBarFactory implements SymbolFactory {
/** Configuration parameter key. */
public static final String SYMBOL_FACTORY_KEY = "symbolFactory";
private final SymbolFactory _symbolFactory;
private final GraphicAttributes _attributes;
private final double _size;
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>symbolFactory = null</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Definition of the wrapped {@link SymbolFactory} which generates
* the curve symbol without bars. By default an empty
* {@link GraphicalComposite} will be created.</td></tr>
* <tr><td><tt>size = 0</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Width of the error bars.</td></tr>
* <tr><td><tt>attributes = null</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Definition of the {@link GraphicAttributes} of the error
* bars.</td></tr>
* </table>
*/
public ErrorBarFactory(ConfigParameters config) {
_symbolFactory = (SymbolFactory) Factory.createOrGet(
config.getNode(SYMBOL_FACTORY_KEY), null);
_size = config.getDouble(SIZE_KEY, 0);
_attributes = (GraphicAttributes) Factory.createOrGet(
config.getNode(ATTRIBUTES_KEY), null);
}
/**
* Creates the legend symbol. Calls the wrapped {@link SymbolFactory}
* or returns an empty instance of {@link GraphicalComposite} if undefined.
*/
public GraphicalElement createLegendSymbol(GraphPoint centerPosition,
double size) {
return _symbolFactory == null ? new GraphicalComposite(null)
: _symbolFactory.createLegendSymbol(centerPosition, size);
}
/**
* Creates either the curve symbol or the error bars. Error bars are
* created when <tt>hintFromPreviousCurve</tt> is an instance of
* {@link PositionHint} and its position attribute is not <tt>null</tt>.
* Otherwise the curve symbol is created. The position attributes stores
* the curve point (in device-independent coordinates). The origin is
* always as set in the initial <tt>PositionHint</tt>. The hint for
* the next curve wrapped by the returned <tt>Symbol</tt> is always
* a <tt>PositionHint</tt>.
*/
public Symbol createSymbol(GraphPoint point, Hint hintFromPreviousPoint,
Hint hintFromPreviousCurve) {
GraphPoint origin = new GraphPoint(null);
GraphPoint position = null;
if (hintFromPreviousCurve instanceof PositionHint) {
origin = ((PositionHint) hintFromPreviousCurve).getOrigin();
position = ((PositionHint) hintFromPreviousCurve).getPosition();
}
if (position == null) {
if (_symbolFactory == null) {
return new Symbol(new GraphicalComposite(null), hintFromPreviousPoint,
new PositionHint(origin, point));
} else {
return _symbolFactory.createSymbol(point, hintFromPreviousPoint,
new PositionHint(origin, point));
}
} else {
double xError = point.getX() - origin.getX();
double yError = point.getY() - origin.getY();
GraphicalComposite errorBars = new GraphicalComposite(null);
if (xError > 0) {
errorBars.addElement(new Rectangle(position, 2 * xError, _size,
_attributes));
}
if (yError > 0) {
errorBars.addElement(new Rectangle(position, _size, 2 * yError,
_attributes));
}
return new Symbol(errorBars, hintFromPreviousPoint,
new PositionHint(origin, null));
}
}
}

View File

@ -1,32 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
/**
* Marker interface of all types of hints. Hints are used to calculate
* {@link jcckit.graphic.GraphicalElement} representing a point in a {@link
* Curve}. For example, in a chart with stacked
* bars the data determines the height of a bar but the foot of
* a bar is determined by the height of the bar below. Its value will be
* stored in a {@link PositionHint}.
*
* @author Franz-Josef Elmer
*/
public interface Hint {}

View File

@ -1,250 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import java.util.Properties;
import jcckit.graphic.BasicGraphicAttributes;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalComposite;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.Polygon;
import jcckit.graphic.Rectangle;
import jcckit.graphic.ShapeAttributes;
import jcckit.graphic.Text;
import jcckit.graphic.TextAttributes;
import jcckit.util.ConfigData;
import jcckit.util.ConfigParameters;
import jcckit.util.ConfigParametersBasedConfigData;
import jcckit.util.Factory;
import jcckit.util.PropertiesBasedConfigData;
/**
* Helper class for creating the legend of a {@link Plot}.
*
* @author Franz-Josef Elmer
*/
public class Legend {
/** Configuration parameter key. */
public static final String UPPER_RIGHT_CORNER_KEY = "upperRightCorner",
BOX_WIDTH_KEY = "boxWidth",
BOX_HEIGHT_KEY = "boxHeight",
BOX_ATTRIBUTES_KEY = "boxAttributes",
TITLE_KEY = "title",
TITLE_DISTANCE_KEY = "titleDistance",
TITLE_ATTRIBUTES_KEY = "titleAttributes",
LEFT_DISTANCE_KEY = "leftDistance",
BOTTOM_DISTANCE_KEY = "bottomDistance",
TOP_DISTANCE_KEY = "topDistance",
LINE_LENGTH_KEY = "lineLength",
SYMBOL_SIZE_KEY = "symbolSize",
CURVE_TITLE_DISTANCE_KEY = "curveTitleDistance",
CURVE_TITLE_ATTRIBUTES_KEY
= "curveTitleAttributes";
private final GraphicalComposite _box;
private final TextAttributes _curveTitleAttributes;
private final double _xSymbol;
private final double _xText;
private final double _yBase;
private final double _yLastRow;
private final double _length;
private final double _size;
/**
* Creates an instance from the specified configuration parameters.
* All numbers (lengths, fontsizes, linethicknesses, etc.) are in
* device-independent units.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>bottomDistance = 0.02</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Distance between the last row and the bottom of the legend box.
* </td></tr>
* <tr><td><tt>boxAttributes = </tt>default values of
* {@link ShapeAttributes} with a white fill color.</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Attributes of the legend box.</td></tr>
* <tr><td><tt>boxHeight = 0.1</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Height of the legend box.</td></tr>
* <tr><td><tt>boxWidth = 0.2</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Width of the legend box.</td></tr>
* <tr><td><tt>curveTitleAttributes = </tt>default values of
* {@link BasicGraphicAttributes}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Text attributes of curve titles printed in the legend.</td></tr>
* <tr><td><tt>curveTitleDistance = 0.005</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Horizontal distance between the line part of the legend symbol
* and the curve title.</td></tr>
* <tr><td><tt>leftDistance = 0.01</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Horizontal distance between the line part of the legend symbol
* and the left border of the legend box.</td></tr>
* <tr><td><tt>lineLength = 0.035</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Length of the line part of the legend symbol.</td></tr>
* <tr><td><tt>symbolSize = 0.01</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Size of the symbol part of the legend symbol. Will be the
* <tt>size</tt> argument of {@link SymbolFactory#createLegendSymbol
* createLegendSymbol} in a {@link SymbolFactory}.</td></tr>
* <tr><td><tt>titleAttributes = </tt>default values of
* {@link BasicGraphicAttributes} with a text anchor CENTER
* TOP.</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Text attributes of the title of the legend box.</td></tr>
* <tr><td><tt>title = Legend</tt></td>
* <td><tt>String</tt></td><td>no</td>
* <td>Title of the legend box.</td></tr>
* <tr><td><tt>titleDistance = 0.005</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Distance between the center of the upper line of the legend box
* and the anchor of the legend title.</td></tr>
* <tr><td><tt>topDistance = 0.04</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Distance between the first row and the top of the legend box.
* </td></tr>
* <tr><td><tt>upperRightCorner = 0.94,&nbsp;0.54</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Position of the upper-right corner of the legend box.</td></tr>
* </table>
*/
public Legend(ConfigParameters config) {
config = mergeWithDefaultConfig(config);
GraphPoint corner
= new GraphPoint(config.getDoubleArray(UPPER_RIGHT_CORNER_KEY,
new double[] {0.94, 0.54}));
double width = config.getDouble(BOX_WIDTH_KEY, 0.2);
double height = config.getDouble(BOX_HEIGHT_KEY, 0.1);
_curveTitleAttributes = (TextAttributes) Factory.create(
config.getNode(CURVE_TITLE_ATTRIBUTES_KEY));
_xSymbol = corner.getX() - width
+ config.getDouble(LEFT_DISTANCE_KEY, 0.01);
_yBase = corner.getY() - config.getDouble(TOP_DISTANCE_KEY, 0.04);
_yLastRow = corner.getY() - height
+ config.getDouble(BOTTOM_DISTANCE_KEY, 0.02);
_length = config.getDouble(LINE_LENGTH_KEY, 0.035);
_size = config.getDouble(SYMBOL_SIZE_KEY, 0.01);
_xText = _xSymbol + _length
+ config.getDouble(CURVE_TITLE_DISTANCE_KEY, 0.005);
_box = new GraphicalComposite(null);
double xCenter = corner.getX() - width / 2;
_box.addElement(new Rectangle(
new GraphPoint(xCenter, corner.getY() - height / 2), width, height,
(GraphicAttributes) Factory.create(
config.getNode(BOX_ATTRIBUTES_KEY))));
_box.addElement(new Text(
new GraphPoint(xCenter, corner.getY()
- config.getDouble(TITLE_DISTANCE_KEY, 0.005)),
config.get(TITLE_KEY, "Legend"),
(TextAttributes) Factory.create(
config.getNode(TITLE_ATTRIBUTES_KEY))));
}
private ConfigParameters mergeWithDefaultConfig(ConfigParameters config) {
Properties p = new Properties();
p.put(BOX_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
ShapeAttributes.class.getName());
p.put(BOX_ATTRIBUTES_KEY + '/'
+ ShapeAttributes.FILL_COLOR_KEY, "0xffffff");
p.put(BOX_ATTRIBUTES_KEY + '/'
+ ShapeAttributes.LINE_COLOR_KEY, "0");
p.put(TITLE_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
BasicGraphicAttributes.class.getName());
p.put(TITLE_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.HORIZONTAL_ANCHOR_KEY, "center");
p.put(TITLE_ATTRIBUTES_KEY + '/'
+ BasicGraphicAttributes.VERTICAL_ANCHOR_KEY, "top");
p.put(CURVE_TITLE_ATTRIBUTES_KEY + '/' + Factory.CLASS_NAME_KEY,
BasicGraphicAttributes.class.getName());
ConfigData cd = new PropertiesBasedConfigData(p);
cd = new ConfigParametersBasedConfigData(config, new ConfigParameters(cd));
return new ConfigParameters(cd);
}
/**
* Returns the legend box with title but without legend symbols and curve
* titles.
*/
public GraphicalElement getBox() {
return _box;
}
/**
* Creates the symbol part of a legend symbol.
* @param curveIndex Index of the curve. Will be needed to calculate the
* y-coordinate of the symbol.
* @param numberOfCurves Number of curves. Will be needed to calculate the
* y-coordinate of the symbol.
* @param factory Factory for the symbol part of the legend symbol.
* Can be <tt>null</tt>.
* @param withLine <tt>true</tt> if the line part of the legend symbol
* should be created.
* @param lineAttributes Attributes of the line part.
*/
public GraphicalElement createSymbol(int curveIndex, int numberOfCurves,
SymbolFactory factory,
boolean withLine,
GraphicAttributes lineAttributes) {
GraphicalComposite result = new GraphicalComposite(null);
double y = calculateBaseLine(curveIndex, numberOfCurves);
if (withLine) {
Polygon line = new Polygon(lineAttributes, false);
line.addPoint(new GraphPoint(_xSymbol, y));
line.addPoint(new GraphPoint(_xSymbol + _length, y));
result.addElement(line);
}
if (factory != null) {
result.addElement(factory.createLegendSymbol(
new GraphPoint(_xSymbol + _length / 2, y), _size));
}
return result;
}
private double calculateBaseLine(int curveIndex, int numberOfCurves) {
if (numberOfCurves > 1) {
return _yBase + ((_yLastRow - _yBase) / (numberOfCurves - 1))
* curveIndex;
} else {
return 0.5 * (_yBase + _yLastRow);
}
}
/**
* Creates the title part of a legend symbol.
* @param curveIndex Index of the curve. Will be needed to calculate the
* y-coordinate of the title.
* @param numberOfCurves Number of curves. Will be needed to calculate the
* y-coordinate of the symbol.
* @param title Title text.
*/
public GraphicalElement createCurveTitle(int curveIndex, int numberOfCurves,
String title) {
return new Text(new GraphPoint(_xText, calculateBaseLine(curveIndex,
numberOfCurves)),
title, _curveTitleAttributes);
}
}

View File

@ -1,377 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import java.util.Vector;
import jcckit.data.DataCurve;
import jcckit.data.DataEvent;
import jcckit.data.DataListener;
import jcckit.data.DataPlot;
import jcckit.data.DataPoint;
import jcckit.graphic.ClippingShape;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicalComposite;
import jcckit.graphic.GraphicalElement;
import jcckit.transformation.Transformation;
import jcckit.util.ConfigParameters;
import jcckit.util.Factory;
/**
* A plot is determined by a {@link CoordinateSystem}, {@link Curve Curves},
* an optional annotation layer and an optional {@link Legend}. When rendered
* these components are draw in this order.
* <p>
* Registrated {@link PlotListener PlotListeners} will be informed
* when the plot changes.
* <p>
* A {@link DataPlot} can be connected with a <tt>Plot</tt> instance.
* This is done with the method {@link #connect connect()} which registrates
* this <tt>Plot</tt> instance as
* a {@link DataListener} at the connected <tt>DataPlot</tt>.
* After an received {@link DataEvent DataEvents} has been handled
* the registrated <tt>PlotListeners</tt> will receive a
* {@link PlotEvent} of the type {@link PlotEventType#DATA_PLOT_CHANGED}.
*
* @author Franz-Josef Elmer
*/
public class Plot implements DataListener {
/** Configuration parameter key. */
public static final String COORDINATE_SYSTEM_KEY = "coordinateSystem",
CURVE_FACTORY_KEY = "curveFactory",
LEGEND_VISIBLE_KEY = "legendVisible",
LEGEND_KEY = "legend",
INITIAL_HINT_FOR_NEXT_CURVE_KEY
= "initialHintForNextCurve";
private final Vector _plotListeners = new Vector();
private DataPlot _dataPlot;
private final CurveFactory _curveFactory;
private final Vector _curves = new Vector();
private final Vector _nextCurveHints = new Vector();
private final Hint _initialHintForNextCurve;
private final Legend _legend;
private final boolean _legendVisibility;
private GraphicalElement _coordinateSystemView;
private ClippingShape _clippingShape;
private Transformation _transformation;
private GraphicalElement _annotation;
private GraphicalComposite _legendView = new GraphicalComposite(null);
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>coordinateSystem = </tt>{@link CartesianCoordinateSystem}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Definition of the {@link CoordinateSystem}.</td></tr>
* <tr><td><tt>curveFactory = </tt>{@link SimpleCurveFactory}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Definition of the {@link CurveFactory}.</td></tr>
* <tr><td><tt>initialHintForNextCurve = null</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Definition of the initial {@link Hint} which is needed by some
* {@link SymbolFactory SymbolFactories} like {@link BarFactory}.
* </td></tr>
* <tr><td><tt>legend = </tt>default values of {@link Legend}</td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Configuration parameters of a {@link Legend}.</td></tr>
* <tr><td><tt>legendVisible = true</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> the {@link Legend} will be created.</td></tr>
* </table>
*/
public Plot(ConfigParameters config) {
CoordinateSystem coordinateSystem = (CoordinateSystem) Factory.create(
config.getNode(COORDINATE_SYSTEM_KEY),
CartesianCoordinateSystem.class.getName());
setCoordinateSystem(coordinateSystem);
_curveFactory = (CurveFactory) Factory.create(
config.getNode(CURVE_FACTORY_KEY),
SimpleCurveFactory.class.getName());
_initialHintForNextCurve = (Hint) Factory.createOrGet(
config.getNode(INITIAL_HINT_FOR_NEXT_CURVE_KEY), null);
_legend = new Legend(config.getNode(LEGEND_KEY));
_legendVisibility = config.getBoolean(LEGEND_VISIBLE_KEY, true);
}
/**
* Sets the coordinate system. All curves will be regenerated and a
* {@link PlotEvent} of type {@link PlotEventType#COODINATE_SYSTEM_CHANGED}
* will be fired.
*
* @param coordinateSystem New coordinate system.
*/
public void setCoordinateSystem(CoordinateSystem coordinateSystem)
{
_coordinateSystemView = coordinateSystem.getView();
_clippingShape = coordinateSystem.getClippingShape();
_transformation = coordinateSystem.getTransformation();
if (_dataPlot != null)
{
generateCurves(_dataPlot);
}
notifyListeners(
new PlotEvent(this, PlotEventType.COODINATE_SYSTEM_CHANGED, null));
}
/**
* Adds the specified {@link PlotListener}. Does nothing if
* already added.
*/
public void addPlotListener(PlotListener listener) {
if (!_plotListeners.contains(listener)) {
_plotListeners.addElement(listener);
}
}
/**
* Removes the specfied {@link PlotListener}. Does nothing if
* already removed.
*/
public void removePlotListener(PlotListener listener) {
_plotListeners.removeElement(listener);
}
/**
* Sends all registrated {@link PlotListener PlotListeners}
* the specified event.
*/
protected void notifyListeners(PlotEvent event) {
for (int i = 0, n = _plotListeners.size(); i < n; i++) {
((PlotListener) _plotListeners.elementAt(i)).plotChanged(event);
}
}
/**
* Connect the specified {@link DataPlot} with this instance.
* <p>
* If this <tt>Plot</tt> instance is already connected with a
* <tt>DataPlot</tt> the connection will be released and a
* {@link PlotEvent} of the type {@link PlotEventType#DATA_PLOT_DISCONNECTED}
* will be sent to all registrated {@link PlotListener PlotListeners}.
* <p>
* It registers itself at <tt>dataPlot</tt> and
* all its {@link DataCurve DataCurves}.
* <p>
* Finally all curves will be generated and a <tt>PlotEvent</tt>
* of the type {@link PlotEventType#DATA_PLOT_CONNECTED} will be transmitted.
* @param dataPlot Data to be connected with this plot instance.
* Can be <tt>null</tt> in order to disconnect this instance from
* any <tt>DataPlot</tt>.
*/
public void connect(DataPlot dataPlot) {
if (_dataPlot != null) {
_dataPlot.removeDataListener(this);
notifyListeners(new PlotEvent(this, PlotEventType.DATA_PLOT_DISCONNECTED,
_dataPlot));
}
_dataPlot = dataPlot;
if (_dataPlot != null)
{
_dataPlot.addDataListener(this);
generateCurves(_dataPlot);
notifyListeners(new PlotEvent(this, PlotEventType.DATA_PLOT_CONNECTED,
_dataPlot));
}
}
/**
* Transforms a point from device-independent coordinates into
* data coordinates.
* @param point Point in device-independent coordinates.
* @return transform <tt>point</tt>.
*/
public DataPoint transform(GraphPoint point) {
return _transformation.transformToData(point);
}
/**
* Creates a graphical representation of the complete plot.
* @return <tt>GraphicalComposite</tt> containing the views of the
* coordinate system, the curves, and optionally the legend (in this order).
*/
public GraphicalComposite getCompletePlot() {
GraphicalComposite result = new GraphicalComposite(null);
result.addElement(_coordinateSystemView);
GraphicalElement[] curves = getCurves();
for (int i = 0; i < curves.length; i++) {
result.addElement(curves[i]);
}
if (_annotation != null) {
result.addElement(_annotation);
}
if (_legendVisibility) {
result.addElement(getLegend());
}
return result;
}
/** Returns the view of the coordinate system. */
public GraphicalElement getCoordinateSystem() {
return _coordinateSystemView;
}
/** Returns the graphical representations of all curves. */
public GraphicalElement[] getCurves() {
synchronized (_curves) {
GraphicalElement[] curves = new GraphicalElement[_curves.size()];
for (int i = 0; i < curves.length; i++) {
curves[i] = ((Curve) _curves.elementAt(i)).getView();
}
return curves;
}
}
/**
* Returns the annotation layer.
* @return <tt>null</tt> if no annotation layer.
*/
public GraphicalElement getAnnotation()
{
return _annotation;
}
/**
* Sets the annotation layer.
* @param annotation Any kind of graphics which will be drawn on the
* top of the curves but may be covered by the legend.
* Can be <tt>null</tt>.
*/
public void setAnnotation(GraphicalElement annotation)
{
_annotation = annotation;
}
/** Returns <tt>true</tt> if the legend is visible. */
public boolean isLegendVisible() {
return _legendVisibility;
}
/** Returns the graphical representations of the legend. */
public GraphicalElement getLegend() {
return _legendView;
}
/**
* Handles the received {@link DataEvent} and notifies
* {@link PlotListener PlotListeners} by an event of the type
* {@link PlotEventType#DATA_CURVE_CHANGED} or
* {@link PlotEventType#DATA_PLOT_CHANGED}. The following table shows what
* this method does:
* <table border=1 cellpadding=5>
* <tr><th>Source of <tt>event</tt></th>
* <th>All hints for the next curve are <tt>null</tt>?</th>
* <th>Action</th><th>Type of sent {@link PlotEvent}</th></tr>
* <tr><td>{@link DataCurve}</td><td>Yes</td><td>Recreate changed curve.<td>
* <td><tt>DATA_CURVE_CHANGED</tt></td></tr>
* <tr><td>{@link DataCurve}</td><td>No</td><td>Recreate changed curve
* and all curves with large curve index.<td>
* <td><tt>DATA_PLOT_CHANGED</tt></td></tr>
* <tr><td>{@link DataPlot}</td><td>-</td><td>Recreate all curves
* and {@link Legend} view.<td>
* <td><tt>DATA_PLOT_CHANGED</tt></td></tr>
* </table>
*/
public void dataChanged(DataEvent event) {
Integer index = new Integer(0);
PlotEventType type = PlotEventType.DATA_PLOT_CHANGED;
synchronized (_curves) {
int numberOfCurves = _curves.size();
if (event.getContainer() instanceof DataCurve
&& numberOfCurves == _dataPlot.getNumberOfElements()) {
DataCurve curve = (DataCurve) event.getContainer();
index = new Integer(curve.getContainer().getIndexOf(curve));
type = PlotEventType.DATA_CURVE_CHANGED;
fillCurve(index.intValue(), curve);
if (index.intValue() < numberOfCurves - 1) {
Vector curveHints
= (Vector) _nextCurveHints.elementAt(index.intValue());
for (int i = 0, n = curveHints.size(); i < n; i++) {
if (curveHints.elementAt(i) != null) {
type = PlotEventType.DATA_PLOT_CHANGED;
for (int j = index.intValue()+1; j < numberOfCurves; j++) {
fillCurve(j, (DataCurve) _dataPlot.getElement(j));
}
break;
}
}
}
} else {
generateCurves(_dataPlot);
}
}
notifyListeners(new PlotEvent(Plot.this, type, index));
}
/**
* Generates all curves based on the specified data.
* In addition the legend view is created.
*/
private void generateCurves(DataPlot dataPlot) {
synchronized (_curves) {
_legendView = new GraphicalComposite(null);
_legendView.addElement(_legend.getBox());
_curves.setSize(0);
_nextCurveHints.setSize(0);
for (int i = 0, n = dataPlot.getNumberOfElements(); i < n; i++) {
Curve curve = _curveFactory.create(i, n, _clippingShape, _legend);
_curves.addElement(curve);
_nextCurveHints.addElement(new Vector());
DataCurve dataCurve = (DataCurve) dataPlot.getElement(i);
_legendView.addElement(curve.getLegendSymbol());
_legendView.addElement(
_legend.createCurveTitle(i, n, dataCurve.getTitle()));
fillCurve(i, dataCurve);
}
}
}
private void fillCurve(int curveIndex, DataCurve dataCurve) {
Vector curveHints = (Vector) _nextCurveHints.elementAt(curveIndex);
Curve curve = (Curve) _curves.elementAt(curveIndex);
curve.removeAllPoints();
for (int i = 0, n = dataCurve.getNumberOfElements(); i < n; i++) {
setHintForNextCurve(curveHints, i,
curve.addPoint(_transformation.transformToGraph(
(DataPoint) dataCurve.getElement(i)),
getHintForNextCurve(curveIndex - 1, i)));
}
}
private Hint getHintForNextCurve(int curveIndex, int pointIndex) {
Hint result = _initialHintForNextCurve;
if (curveIndex >= 0) {
Vector curveHints = (Vector) _nextCurveHints.elementAt(curveIndex);
result = pointIndex < curveHints.size() ?
(Hint) curveHints.elementAt(pointIndex)
: getHintForNextCurve(curveIndex - 1, pointIndex);
}
return result;
}
private void setHintForNextCurve(Vector curveHints, int pointIndex,
Hint hint) {
while (curveHints.size() <= pointIndex) {
curveHints.addElement(_initialHintForNextCurve);
}
curveHints.setElementAt(hint, pointIndex);
}
}

View File

@ -1,135 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.data.DataPlot;
import jcckit.graphic.Anchor;
import jcckit.graphic.ClippingRectangle;
import jcckit.util.ConfigParameters;
/**
* An abstract canvas containg a single {@link Plot}. The canvas is specified
* by a {@link ClippingRectangle}, called <em>paper</em>. A horizontal and
* vertical {@link Anchor} determine the position of the paper on the actual
* device.
*
* @author Franz-Josef Elmer
*/
public class PlotCanvas implements PlotListener {
/** Configuration parameter key. */
public static final String PAPER_KEY = "paper", HORIZONTAL_ANCHOR_KEY = "horizontalAnchor",
VERTICAL_ANCHOR_KEY = "verticalAnchor", PLOT_KEY = "plot";
private final ClippingRectangle _paper;
private final Anchor _horizontalAnchor;
private final Anchor _verticalAnchor;
private final Plot _plot;
/**
* Creates an instance from the specified configuration parameters. <table
* border=1 cellpadding=5>
* <tr>
* <th>Key &amp; Default Value</th>
* <th>Type</th>
* <th>Mandatory</th>
* <th>Description</th>
* </tr>
* <tr>
* <td><tt>horizontalAnchor = center</tt></td>
* <td><tt>String</tt></td>
* <td>no</td>
* <td>Horizontal position of the paper relative to the device border.
* Possible values are <tt>left</tt>, <tt>center</tt>, and
* <tt>right</tt>.</td>
* </tr>
* <tr>
* <td><tt>paper = 0,&nbsp;0,&nbsp;1,&nbsp;0.6</tt></td>
* <td><tt>double[]</tt></td>
* <td>no</td>
* <td>Rectangle defining the paper. The first two values determine the x-
* and y- coordinates (in device-independent units) of the lower-left
* corner. The last two values determine the upper-right corner.</td>
* </tr>
* <tr>
* <td><tt>plot = </tt>default values of {@link Plot}</td>
* <td><tt>ConfigParameters</tt></td>
* <td>no</td>
* <td>Definition of the {@link Plot}.</td>
* </tr>
* <tr>
* <td><tt>verticalAnchor = center</tt></td>
* <td><tt>String</tt></td>
* <td>no</td>
* <td>Vertical position of the paper relative to the device border.
* Possible values are <tt>top</tt>, <tt>center</tt>, and
* <tt>bottom</tt>.</td>
* </tr>
* </table>
* <p>
* Note, that this instance registers itself at the wrapped {@link Plot}
* instance.
*/
public PlotCanvas(ConfigParameters config) {
double[] paper = config.getDoubleArray(PAPER_KEY, new double[] { 0, 0, 1, 0.6 });
_paper = new ClippingRectangle(paper[0], paper[1], paper[2], paper[3]);
_horizontalAnchor = Anchor.getHorizontalAnchor(config, HORIZONTAL_ANCHOR_KEY, Anchor.CENTER);
_verticalAnchor = Anchor.getVerticalAnchor(config, VERTICAL_ANCHOR_KEY, Anchor.CENTER);
_plot = new Plot(config.getNode(PLOT_KEY));
_plot.addPlotListener(this);
}
/** Returns the paper definition. */
public ClippingRectangle getPaper() {
return _paper;
}
/** Returns the horizontal anchor. */
public Anchor getHorizontalAnchor() {
return _horizontalAnchor;
}
/** Returns the vertical anchor. */
public Anchor getVerticalAnchor() {
return _verticalAnchor;
}
/** Returns the plot. */
public Plot getPlot() {
return _plot;
}
/**
* Connects the wrapped {@link Plot} instance with the specified
* {@link DataPlot}.
*
* @param dataPlot
* Data to be connected with this plot canvas. Can be
* <tt>null</tt> in order to disconnect this instance from a
* <tt>DataPlot</tt>.
*/
public void connect(DataPlot dataPlot) {
_plot.connect(dataPlot);
}
/**
* Handles the spcified event. Here nothing is done. But subclass may
* override this method.
*/
public void plotChanged(PlotEvent event) {
}
}

View File

@ -1,88 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
/**
* A plot event signales some changes of a {@link Plot}.
* It has three attributes:
* <ul><li><b>source</b>: Indicates the <tt>Plot</tt> instance responsible
* for this event.
* <li><b>type</b>: The type of event.
* <li><b>message</b>: The message object. Its meaning depends on the
* type of event:
* <table border=1 cellpadding=5>
* <tr><th>Type</th><th>Meaning of the message object</th></tr>
* <tr><td>{@link PlotEventType#DATA_PLOT_CONNECTED},
* {@link PlotEventType#DATA_PLOT_DISCONNECTED}</td>
* <td>The {@link jcckit.data.DataPlot} (dis)connected with the
* {@link Plot} instance specified by the source.</td>
* <tr><td>{@link PlotEventType#DATA_PLOT_CHANGED}</td>
* <td>An <tt>Integer</tt> indicating the lowest index of
* those curves which have been changed.</td>
* <tr><td>{@link PlotEventType#DATA_CURVE_CHANGED}</td>
* <td>An <tt>Integer</tt> indicating the index of the curve
* which has been changed.</td>
* </table>
* </ul>
*
*
* @author Franz-Josef Elmer
*/
public class PlotEvent {
private final Plot _source;
private final PlotEventType _type;
private final Object _message;
/**
* Creates a new event for the specified source, type, and message.
* @param source Plot causing this event.
* @param type Type of the event. Possible values are
* {@link PlotEventType#DATA_PLOT_CHANGED},
* {@link PlotEventType#DATA_CURVE_CHANGED},
* {@link PlotEventType#DATA_PLOT_CONNECTED}, and
* {@link PlotEventType#DATA_PLOT_DISCONNECTED}.
* @param message Message object. Can be <tt>null</tt>
*/
public PlotEvent(Plot source, PlotEventType type, Object message) {
_source = source;
_type = type;
_message = message;
}
/** Returns the source of this event. */
public Plot getSource() {
return _source;
}
/**
* Returns the event type.
* @return either {@link PlotEventType#DATA_PLOT_CHANGED},
* {@link PlotEventType#DATA_CURVE_CHANGED},
* {@link PlotEventType#DATA_PLOT_CONNECTED}, or
* {@link PlotEventType#DATA_PLOT_DISCONNECTED}.
*/
public PlotEventType getType() {
return _type;
}
/** Returns the message object. */
public Object getMessage() {
return _message;
}
}

View File

@ -1,36 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
/**
* Types of {@link PlotEvent PlotEvents}. Using the typesafe enumeration
* pattern.
*
* @author Franz-Josef Elmer
*/
public class PlotEventType {
/** Event type. */
public static final PlotEventType DATA_PLOT_CONNECTED = new PlotEventType(),
DATA_PLOT_DISCONNECTED = new PlotEventType(),
COODINATE_SYSTEM_CHANGED = new PlotEventType(),
DATA_CURVE_CHANGED = new PlotEventType(),
DATA_PLOT_CHANGED = new PlotEventType();
private PlotEventType() {}
}

View File

@ -1,29 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
/**
* Listener for changes of plots, diagrams, and charts.
*
* @author Franz-Josef Elmer
*/
public interface PlotListener {
/** Receives the specified plot event.*/
public void plotChanged(PlotEvent event);
}

View File

@ -1,75 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphPoint;
import jcckit.util.ConfigParameters;
/**
* An immutable {@link Hint} capsulating two {@link GraphPoint GraphPoints}.
*
* @author Franz-Josef Elmer
*/
public class PositionHint implements Hint {
/** Configuration parameter key. */
public static final String POSITION_KEY = "position",
ORIGIN_KEY = "origin";
private final GraphPoint _position;
private final GraphPoint _origin;
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>position = null</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Definition of position.</td></tr>
* <tr><td><tt>origin = position</tt> or (0,0) if <tt>position</tt>
* undefined</td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Definition of origin.</td></tr>
* </table>
*/
public PositionHint(ConfigParameters config) {
double[] point = config.getDoubleArray(POSITION_KEY, null);
_position = point == null ? null : new GraphPoint(point);
_origin = new GraphPoint(config.getDoubleArray(ORIGIN_KEY, point));
}
/**
* Creates an instance based on two points.
* @param origin The origin.
* @param position The position.
*/
public PositionHint(GraphPoint origin, GraphPoint position) {
_origin = origin;
_position = position;
}
/** Returns the position. */
public GraphPoint getPosition() {
return _position;
}
/** Returns the origin. */
public GraphPoint getOrigin() {
return _origin;
}
}

View File

@ -1,140 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import java.awt.Color;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.ShapeAttributes;
import jcckit.util.ConfigParameters;
/**
* An {@link AttributesHint} which wraps {@link ShapeAttributes}.
* Each call of {@link #getNextHint()} returns a new instance of
* <tt>ShapeAttributes</tt> where fill color, line color and/or
* line thickness has been increased by a constant amount.
*
* @author Franz-Josef Elmer
*/
public class ShapeAttributesHint implements AttributesHint, Cloneable {
/** Configuration parameter key. */
public static final String INITIAL_ATTRIBUTES_KEY = "initialAttributes",
FILL_COLOR_HSB_INCREMENT_KEY
= "fillColorHSBIncrement",
LINE_COLOR_HSB_INCREMENT_KEY
= "lineColorHSBIncrement",
LINE_THICKNESS_INCREMENT_KEY
= "lineThicknessIncrement";
private static float[] extractHSB(Color color) {
return color == null ? null
: Color.RGBtoHSB(color.getRed(), color.getGreen(), color.getBlue(),
null);
}
private static Color createColor(float[] colorHSB) {
return colorHSB == null ? null
: Color.getHSBColor(colorHSB[0], colorHSB[1], colorHSB[2]);
}
private static float[] incrementColor(float[] colorHSB,
double[] increments) {
float[] result = null;
if (colorHSB != null) {
result = (float[]) colorHSB.clone();
for (int i = 0; i < 3; i++) {
result[i] += increments[i];
}
}
return result;
}
private float[] _fillColorHSB;
private float[] _lineColorHSB;
private double _lineThickness;
private double[] _linePattern;
private double[] _fillColorHSBIncrement;
private double[] _lineColorHSBIncrement;
private double _lineThicknessIncrement;
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>initialAttributes = </tt><i>default values of
* {@link ShapeAttributes}</i></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Initial values of shape attributes. Note, that default
* fill and line colors are undefined (they depend on the
* <tt>Renderer</tt>). In this case color increments have no effects.
* </td></tr>
* <tr><td><tt>fillColorHSBIncrement = 0 0 0</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Hue, saturation, and brightness increments of the fill color.
* </td></tr>
* <tr><td><tt>lineColorHSBIncrement = 0 0 0</tt></td>
* <td><tt>double[]</tt></td><td>no</td>
* <td>Hue, saturation, and brightness increments of the line color.
* </td></tr>
* <tr><td><tt>lineThicknessIncrement = 0</tt></td>
* <td><tt>double</tt></td><td>no</td>
* <td>Line thickness increment.</td></tr>
* </table>
*/
public ShapeAttributesHint(ConfigParameters config) {
ShapeAttributes attributes
= new ShapeAttributes(config.getNode(INITIAL_ATTRIBUTES_KEY));
_fillColorHSB = extractHSB(attributes.getFillColor());
_lineColorHSB = extractHSB(attributes.getLineColor());
_lineThickness = attributes.getLineThickness();
_linePattern = attributes.getLinePattern();
_fillColorHSBIncrement
= config.getDoubleArray(FILL_COLOR_HSB_INCREMENT_KEY, new double[3]);
_lineColorHSBIncrement
= config.getDoubleArray(LINE_COLOR_HSB_INCREMENT_KEY, new double[3]);
_lineThicknessIncrement
= config.getDouble(LINE_THICKNESS_INCREMENT_KEY, 0);
}
/**
* Creates a new <tt>ShapeAttributesHint</tt> where all attributes has been
* incremented.
*/
public AttributesHint getNextHint() {
ShapeAttributesHint nextHint = null;
try {
nextHint = (ShapeAttributesHint) clone();
} catch (CloneNotSupportedException e) {}
nextHint._fillColorHSB
= incrementColor(_fillColorHSB, _fillColorHSBIncrement);
nextHint._lineColorHSB
= incrementColor(_lineColorHSB, _lineColorHSBIncrement);
nextHint._lineThickness
= Math.max(0, _lineThickness + _lineThicknessIncrement);
return nextHint;
}
/** Returns the wrapped {@link ShapeAttributes} instance. */
public GraphicAttributes getAttributes() {
return new ShapeAttributes(createColor(_fillColorHSB),
createColor(_lineColorHSB),
_lineThickness, _linePattern);
}
}

View File

@ -1,185 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import java.awt.Color;
import jcckit.graphic.ClippingShape;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicalComposite;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.LineAttributes;
import jcckit.graphic.Polygon;
import jcckit.graphic.ShapeAttributes;
import jcckit.util.ConfigParameters;
import jcckit.util.Factory;
/**
* A simple curve is the basic implementation of the {@link Curve} interface.
*
* @author Franz-Josef Elmer
*/
public class SimpleCurve implements Curve {
/** Configuration parameter key. */
public static final String SYMBOL_FACTORY_KEY = "symbolFactory",
WITH_LINE_KEY = "withLine",
SOFT_CLIPPING_KEY = "softClipping",
LINE_ATTRIBUTES_KEY = "lineAttributes",
INITIAL_HINT_FOR_NEXT_POINT_KEY
= "initialHintForNextPoint";
private final ClippingShape _clippingShape;
private final SymbolFactory _symbolFactory;
private final GraphicalComposite _symbols;
private final GraphicalComposite _completeCurve;
private final GraphicalElement _legendSymbol;
private final Hint _initialHintForNextPoint;
private final Polygon _curve;
private final boolean _softClipping;
private Hint _hintForNextPoint;
/**
* Creates a new curve. The parameter <tt>config</tt> contains:
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>initialHintForNextPoint = null</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Definition of an initial {@link Hint} for the first curve point.
* </td></tr>
* <tr><td><tt>lineAttributes = </tt>a {@link ShapeAttributes}
* instances with default values and line colors based on
* the formula <tt>Color.getHSBColor(curveIndex/6,1,0.8)</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Configuration parameters of an instances of
* {@link jcckit.graphic.GraphicAttributes} for the
* {@link Polygon Polygons} connecting curve points.</td></tr>
* <tr><td><tt>symbolFactory = null</tt></td>
* <td><tt>ConfigParameters</tt></td><td>no</td>
* <td>Configuration parameters defining an instances of
* {@link SymbolFactory} for the {@link Symbol Symbols}
* decorating curve points.</td></tr>
* <tr><td><tt>softClipping = true</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> no explicit clipping takes
* place but the symbol is not drawn if the corresponding curve
* point is outside the axis box.<br>
* If <tt>false</tt> the symbol is
* drawn in any case but it may be clipped by the axis box.
* Soft-clipping should be set to <tt>false</tt> if the
* symbols are not located around the curve point (like for bars).
* </td></tr>
* <tr><td><tt>withLine = true</tt></td>
* <td><tt>boolean</tt></td><td>no</td>
* <td>If <tt>true</tt> curve points are connected by a
* {@link jcckit.graphic.Polygon}.</td></tr>
* </table>
* @param config Configuration parameters described above.
* @param curveIndex Index of this curve in the collection of curves
* defining a {@link Plot}.
* @param numberOfCurves Number of curves in this collection.
* @param clippingShape Clipping shape. Can be <tt>null</tt>.
* @param legend Legend. Will be used to calculate the legend symbol.
* @throws IllegalArgumentException if <tt>symbolFactory == null</tt> and
* <tt>withLine == false</tt>.
*
*/
public SimpleCurve(ConfigParameters config, int curveIndex,
int numberOfCurves, ClippingShape clippingShape,
Legend legend) {
_symbolFactory = (SymbolFactory) Factory.createOrGet(
config.getNode(SYMBOL_FACTORY_KEY), null);
boolean withLine = config.getBoolean(WITH_LINE_KEY, true);
LineAttributes lineAttributes = (LineAttributes) Factory.createOrGet(
config.getNode(LINE_ATTRIBUTES_KEY),
new ShapeAttributes(null, Color.getHSBColor((curveIndex % 6) / 6f,
1f, 0.8f),
0, null));
if (_symbolFactory != null || withLine) {
_clippingShape = clippingShape;
_completeCurve = new GraphicalComposite(null);
if (withLine) {
GraphicalComposite container = new GraphicalComposite(clippingShape);
_curve = new Polygon(lineAttributes, false);
container.addElement(_curve);
_completeCurve.addElement(container);
} else {
_curve = null;
}
_softClipping = config.getBoolean(SOFT_CLIPPING_KEY, true);
if (_symbolFactory != null) {
_symbols = new GraphicalComposite(_softClipping ? null
: clippingShape);
_completeCurve.addElement(_symbols);
} else {
_symbols = null;
}
} else {
throw new IllegalArgumentException(
"Either a SymbolFactory must exist or withLines == true.");
}
_hintForNextPoint = _initialHintForNextPoint
= (Hint) Factory.createOrGet(
config.getNode(INITIAL_HINT_FOR_NEXT_POINT_KEY), null);
_legendSymbol = legend.createSymbol(curveIndex, numberOfCurves,
_symbolFactory, withLine,
lineAttributes);
}
/**
* Returns the graphical representation of a curve.
* @return always the same instance.
*/
public GraphicalElement getView() {
return _completeCurve;
}
/** Returns the legend symbol. */
public GraphicalElement getLegendSymbol() {
return _legendSymbol;
}
/** Appends a new point to the curve if inside the clipping shape. */
public Hint addPoint(GraphPoint point, Hint hintFromPreviousCurve) {
if (_curve != null) {
_curve.addPoint(point);
}
Hint hintForNextCurve = hintFromPreviousCurve;
if (_symbolFactory != null) {
Symbol symbol = _symbolFactory.createSymbol(point, _hintForNextPoint,
hintFromPreviousCurve);
if (_clippingShape == null || !_softClipping
|| _clippingShape.isInside(point)) {
_symbols.addElement(symbol.getSymbol());
}
_hintForNextPoint = symbol.getHintForNextPoint();
hintForNextCurve = symbol.getHintForNextCurve();
}
return hintForNextCurve;
}
public void removeAllPoints() {
if (_curve != null) {
_curve.removeAllPoints();
}
if (_symbols != null) {
_symbols.removeAllElements();
}
_hintForNextPoint = _initialHintForNextPoint;
}
}

View File

@ -1,80 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import java.util.Properties;
import java.util.StringTokenizer;
import jcckit.graphic.ClippingShape;
import jcckit.util.ConfigParameters;
import jcckit.util.PropertiesBasedConfigData;
/**
* Factory for {@link SimpleCurve SimpleCurves}.
*
* @author Franz-Josef Elmer
*/
public class SimpleCurveFactory implements CurveFactory {
/** Configuration parameter key. */
public static final String DEFINITIONS_KEY = "definitions";
private ConfigParameters[] _configs = new ConfigParameters[]
{new ConfigParameters(new PropertiesBasedConfigData(new Properties()))};
/**
* Creates an instance from the specified configuration parameter.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>definitions = </tt><i>one empty <tt>ConfigParameters<tt>
* instance</i></td>
* <td><tt>String[]</tt></td><td>no</td>
* <td>Keys of subtrees defining {@link ConfigParameters}
* used by the {@link SimpleCurve#SimpleCurve constructor} of
* {@link SimpleCurve}.</td></tr>
* </table>
*/
public SimpleCurveFactory(ConfigParameters config) {
String value = config.get(DEFINITIONS_KEY, null);
if (value != null) {
StringTokenizer tokenizer = new StringTokenizer(value);
_configs = new ConfigParameters[tokenizer.countTokens()];
for (int i = 0; i < _configs.length; i++) {
_configs[i] = config.getNode(tokenizer.nextToken());
}
}
}
/**
* Creates an instance of {@link SimpleCurve}.
* @param curveIndex Index of the curve. Will be used to select the
* {@link ConfigParameters} object and the line attributes.
* In addition it will be used to calculate the y-coordinate
* of the legend symbol.
* @param numberOfCurves Number of curves. Will be needed to calculate
* the y-coordinate of the legend symbol.
* @param clippingShape The clipping shape.
* @param legend The legend. Will be needed to create the legend symbol.
*/
public Curve create(int curveIndex, int numberOfCurves,
ClippingShape clippingShape, Legend legend) {
return new SimpleCurve(_configs[curveIndex % _configs.length], curveIndex,
numberOfCurves, clippingShape, legend);
}
}

View File

@ -1,54 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalElement;
import jcckit.graphic.Rectangle;
import jcckit.util.ConfigParameters;
/**
* A factory of square symbols.
*
* @author Franz-Josef Elmer
*/
public class SquareSymbolFactory extends AbstractSymbolFactory {
/**
* Creates an instance from the specified configuration parameters.
* For the configuration parameters see the
* <a href="AbstractSymbolFactory.html#AbstractSymbolFactory(jcckit.util.ConfigParameters)">
* constructor</a> of the superclass {@link AbstractSymbolFactory}.
*/
public SquareSymbolFactory(ConfigParameters config) {
super(config);
}
/**
* Creates a {@link Rectangle}.
* @param centerPosition Position of the center of the rectangle.
* @param size Diameter of the rectangle.
* @param attributes Rectangle attributes.
*/
protected GraphicalElement createPlainSymbol(GraphPoint centerPosition,
double size,
GraphicAttributes attributes) {
return new Rectangle(centerPosition, size, size, attributes);
}
}

View File

@ -1,56 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphicalElement;
/**
* Immutable class holding the graphical represention of the symbol and
* two {@link Hint Hints}.
*
* @author Franz-Josef Elmer
*/
public class Symbol {
private final GraphicalElement _symbol;
private final Hint _hintForNextPoint;
private final Hint _hintForNextCurve;
/** Creates an instance for the specified symbol and hints. */
public Symbol(GraphicalElement symbol, Hint hintForNextPoint,
Hint hintForNextCurve) {
_symbol = symbol;
_hintForNextPoint = hintForNextPoint;
_hintForNextCurve = hintForNextCurve;
}
/** Returns the graphical symbol. */
public GraphicalElement getSymbol() {
return _symbol;
}
/** Returns the hint for the next point. */
public Hint getHintForNextPoint() {
return _hintForNextPoint;
}
/** Returns the hint for the next curve. */
public Hint getHintForNextCurve() {
return _hintForNextCurve;
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicalElement;
/**
* Interface of a symbol factory. A symbol is a {@link GraphicalElement}
* or {@link jcckit.graphic.GraphicalComposite}. A symbol factory creates
* the same type of symbols. In general, they have all the same size.
* But they are distinguished from each other by their positions.
* In addition they may also differ in other properties which will
* be determined by {@link Hint Hints}.
*
* @author Franz-Josef Elmer
*/
public interface SymbolFactory {
/** Common configuration parameter key need by implementing classes. */
public static final String SIZE_KEY = "size",
ATTRIBUTES_KEY = "attributes";
/** Default size of a symbol = 0.01. */
public static final double DEFAULT_SIZE = 0.01;
/**
* Creates a symbol for the specified point taking into account
* the specified hints.
* @param point The position of the symbol. In general it is a transformation
* of a corresponding {@link jcckit.data.DataPoint} into a
* {@link GraphPoint}.
* @param hintFromPreviousPoint Hint from the previous point of the same
* {@link Curve} or <tt>null</tt>.
* @param hintFromPreviousCurve Hint from the previous
* {@link Curve} or <tt>null</tt>.
*/
public Symbol createSymbol(GraphPoint point, Hint hintFromPreviousPoint,
Hint hintFromPreviousCurve);
/**
* Creates a symbol for the legend at the specified position.
* @param centerPosition Center position of the symbol.
* @param size The size of the symbol. Will not be used if the symbol
* of the curve points have all the same size. In this case
* the symbol for the legend has the size of the curve symbols.
*/
public GraphicalElement createLegendSymbol(GraphPoint centerPosition,
double size);
}

View File

@ -1,136 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.plot;
import java.util.StringTokenizer;
import jcckit.util.ConfigParameters;
import jcckit.util.TicLabelFormat;
/**
* Map of number intervals onto a text label. The map is defined by a
* map description string provided by configuration data.
* <p>
* The map description is a list
* of conditions separated by ';'. The conditions are tested from left to
* right until a condition is fulfilled for the tic value. If no condition
* is fullfilled a '?' will be returned.
* <p>
* A condition description has one of the following forms:
* <pre><tt><i>&lt;label&gt;</i></tt></pre>
* <pre><tt><i>&lt;number&gt;</i>=<i>&lt;label&gt;</i></tt></pre>
* <pre><tt><i>&lt;number1&gt;</i>:<i>&lt;number2&gt;</i>=<i>&lt;label&gt;</i></tt></pre>
* <p>
* The first type of condition is always fulfilled. It will return
* <tt><i>&lt;label&gt;</i></tt>. This is a kind of else condtion
* which is put at the end of the condition list.
* <p>
* The second form maps a particular number onto a label. In order to be
* equal with the sepcified number the tic value should not deviate more
* than 1 ppm (part per millions) from <tt><i>&lt;number&gt;</i>.
* <p>
* The third form maps an interval onto a label. The condition reads
* <p>
* <tt><i>&lt;number1&gt;</i></tt>&nbsp;&lt;=&nbsp;tic&nbsp;label&nbsp;&lt;&nbsp;<tt><i>&lt;number2&gt;</i></tt>
* <p>
* Examples:
* <pre><tt>
* 1=monday;2=tuesday;3=wednesday;4=thursday;5=friday;6=saturday;7=sunday
* 0.5:1.5=I; 1.5:2.5 = II; 2.5:3.5 = III; the rest
* </tt></pre>
*
* @author Franz-Josef Elmer
*/
public class TicLabelMap implements TicLabelFormat {
public static final String MAP_KEY = "map";
private static class MapItem {
private double _min = Double.MIN_VALUE;
private double _max = Double.MAX_VALUE;
private final String label;
public MapItem(String item) {
int index = item.indexOf('=');
if (index < 0) {
label = item;
} else {
label = item.substring(index + 1).trim();
item = item.substring(0, index).trim();
index = item.indexOf(':');
if (index < 0) {
_min = new Double(item).doubleValue();
_max = _min == 0 ? Double.MIN_VALUE : _min * 1.000001d;
_min = _min * 0.999999d;
if (_min > _max) {
double z = _min;
_min = _max;
_max = z;
}
} else {
_min = new Double(item.substring(0, index)).doubleValue();
_max = new Double(item.substring(index + 1)).doubleValue();
}
}
}
public boolean isInside(double value) {
return value >= _min && value < _max;
}
}
private final MapItem[] _map;
/**
* Creates an instance from the specified configuration parameters.
* <table border=1 cellpadding=5>
* <tr><th>Key &amp; Default Value</th><th>Type</th><th>Mandatory</th>
* <th>Description</th></tr>
* <tr><td><tt>map</tt></td>
* <td><tt>String</tt></td><td>yes</td>
* <td>Map description as explained above.</td></tr>
* </table>
*/
public TicLabelMap(ConfigParameters config) {
StringTokenizer tokenizer = new StringTokenizer(config.get(MAP_KEY), ";");
_map = new MapItem[tokenizer.countTokens()];
for (int i = 0; i < _map.length; i++)
{
String item = tokenizer.nextToken();
try {
_map[i] = new MapItem(item.trim());
} catch (NumberFormatException e) {
throw new NumberFormatException("Item '" + item + "' of "
+ config.getFullKey(MAP_KEY) + " has an invalid number.");
}
}
}
/**
* Maps the specified tic value onto a text label in accordance
* with the map description.
*/
public String form(double ticValue) {
String result = "?";
for (int i = 0; i < _map.length; i++) {
if (_map[i].isInside(ticValue)) {
result = _map[i].label;
break;
}
}
return result;
}
}

View File

@ -1,313 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.renderer;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import jcckit.graphic.BasicGraphicalElement;
import jcckit.graphic.ClippingRectangle;
import jcckit.graphic.ClippingShape;
import jcckit.graphic.FillAttributes;
import jcckit.graphic.FontStyle;
import jcckit.graphic.GraphPoint;
import jcckit.graphic.GraphicAttributes;
import jcckit.graphic.GraphicalComposite;
import jcckit.graphic.GraphicalCompositeRenderer;
import jcckit.graphic.LineAttributes;
import jcckit.graphic.Oval;
import jcckit.graphic.OvalRenderer;
import jcckit.graphic.Polygon;
import jcckit.graphic.PolygonRenderer;
import jcckit.graphic.Rectangle;
import jcckit.graphic.RectangleRenderer;
import jcckit.graphic.Text;
import jcckit.graphic.TextAttributes;
import jcckit.graphic.TextRenderer;
/**
* Renderer who draws the {@link jcckit.graphic.GraphicalElement
* GraphicalElements} into a <tt>java.awt.Graphics2D</tt> context.
* <p>
* The default color for lines and texts is determined by the current color of
* the <tt>Graphics2D</tt> context when a new instance of
* <tt>Graphics2DRenderer</tt> is created.
* <p>
* The default font is <tt>SansSerif-12</tt>.
*
* @author Franz-Josef Elmer
*/
public class Graphics2DRenderer implements GraphicalCompositeRenderer, PolygonRenderer, OvalRenderer, TextRenderer,
RectangleRenderer {
private static final int FS = 1;
private static final String DEFAULT_FONT_NAME = "SansSerif";
private static final FontStyle DEFAULT_FONT_STYLE = FontStyle.NORMAL;
private static final int DEFAULT_FONT_SIZE = 12;
private Color _defaultColor;
private Graphics2D _graphics;
/**
* Initializes this instance. During renderering the current transformation
* will be leaved unchanged. But the current Clip may be cleared.
*
* @param graphics
* Graphics2D context into which the
* {@link BasicGraphicalElement BaiscGraphicalElements} are
* painted.
* @return this instance.
*/
public Graphics2DRenderer init(Graphics2D graphics) {
_graphics = graphics;
_defaultColor = graphics.getColor(); // the foreground color
return this;
}
/**
* Starts rendering of the specified composite. Does nothing except if
* <tt>composite</tt> has a {@link ClippingShape}. In this case the Clip
* of the <tt>Graphics2D</tt> context becomes the clipping rectangle
* determined by the bounding box of the <tt>ClippingShape</tt>.
*/
public void startRendering(GraphicalComposite composite) {
ClippingShape shape = composite.getClippingShape();
if (shape != null) {
ClippingRectangle rect = shape.getBoundingBox();
_graphics.clip(new Rectangle2D.Double(rect.getMinX(), rect.getMinY(), rect.getMaxX() - rect.getMinX(), rect
.getMaxY()
- rect.getMinY()));
}
}
/**
* Finishes rendering of the specified composite. Does nothing except if
* <tt>composite</tt> has a {@link ClippingShape}. In this case the Clip
* of the <tt>Graphics2D</tt> context will be cleared.
*/
public void finishRendering(GraphicalComposite composite) {
_graphics.setClip(null);
}
/** Paints the specified polygon into the <tt>Graphics2D</tt> context. */
public void render(Polygon polygon) {
int numberOfPoints = polygon.getNumberOfPoints();
if (numberOfPoints > 0) {
Color currentColor = _graphics.getColor();
GeneralPath p = new GeneralPath(GeneralPath.WIND_EVEN_ODD, numberOfPoints);
p.moveTo((float) polygon.getPoint(0).getX(), (float) polygon.getPoint(0).getY());
for (int i = 1; i < numberOfPoints; i++) {
p.lineTo((float) polygon.getPoint(i).getX(), (float) polygon.getPoint(i).getY());
}
if (polygon.isClosed()) {
p.closePath();
}
drawShape(p, polygon, currentColor);
}
}
/**
* Paints the specified rectangle into the current <tt>Graphics</tt>
* context.
*/
public void render(Rectangle rectangle) {
Color currentColor = _graphics.getColor();
GraphPoint center = rectangle.getCenter();
double width = rectangle.getWidth();
double height = rectangle.getHeight();
Rectangle2D rect = new Rectangle2D.Double(center.getX() - 0.5 * width, center.getY() - 0.5 * height, width,
height);
drawShape(rect, rectangle, currentColor);
}
/**
* Paints the specified oval into the current <tt>Graphics</tt> context.
*/
public void render(Oval oval) {
Color currentColor = _graphics.getColor();
GraphPoint center = oval.getCenter();
double width = oval.getWidth();
double height = oval.getHeight();
Ellipse2D ellipse = new Ellipse2D.Double(center.getX() - 0.5 * width, center.getY() - 0.5 * height, width,
height);
drawShape(ellipse, oval, currentColor);
}
private void drawShape(Shape shape, BasicGraphicalElement element, Color backupColor) {
GraphicAttributes attributes = element.getGraphicAttributes();
Color fillColor = null;
if (element.isClosed() && attributes instanceof FillAttributes) {
fillColor = ((FillAttributes) attributes).getFillColor();
}
if (fillColor != null) {
_graphics.setColor(fillColor);
_graphics.fill(shape);
}
Color lineColor = _defaultColor;
if (attributes instanceof LineAttributes) {
LineAttributes la = (LineAttributes) attributes;
BasicStroke stroke = new BasicStroke((float) la.getLineThickness());
double[] linePattern = la.getLinePattern();
if (linePattern != null) {
float[] dash = new float[linePattern.length];
for (int i = 0; i < dash.length; i++) {
dash[i] = (float) la.getLinePattern()[i];
}
stroke = new BasicStroke(stroke.getLineWidth(), BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10f,
dash, 0f);
}
_graphics.setStroke(stroke);
if (la.getLineColor() != null || fillColor != null) {
lineColor = la.getLineColor();
}
}
if (lineColor != null) {
_graphics.setColor(lineColor);
_graphics.draw(shape);
}
_graphics.setColor(backupColor);
}
/**
* Paints the specified text into the current <tt>Graphics</tt> context.
* <p>
* If the font size is zero the default font size will be used.
* <p>
* If the orientation angle is unequal zero the text will first be painted
* into an off-screen image and rotated. Finally, it will be drawn into the
* current <tt>Graphics</tt> context. Note, that only integer multiples of
* 90 degree rotation are performed. Other orientation angles will be
* adjusted to the nearest integer multiple of 90 degree.
*/
public void render(Text text) {
final GraphicAttributes ga = text.getGraphicAttributes();
if (ga instanceof TextAttributes) {
final TextAttributes ta = (TextAttributes) ga;
final Color currentColor = _graphics.getColor();
Color fontColor = ta.getTextColor();
if (fontColor == null) {
fontColor = _defaultColor;
}
_graphics.setColor(fontColor);
final double scale = _graphics.getTransform().getScaleX();
final String str = text.getText();
AffineTransform before = _graphics.getTransform();
_graphics.setTransform(new AffineTransform());
double fs = ta.getFontSize();
fs = fs == 0 ? 1 : fs * scale / DEFAULT_FONT_SIZE;
Font font = createFont(ta, 0);
AffineTransform fontTransform = new AffineTransform();
fontTransform.scale(fs, fs);
fontTransform.rotate(-ta.getOrientationAngle() * Math.PI / 180);
font = font.deriveFont(fontTransform);
_graphics.setFont(font);
Rectangle2D bounds = _graphics.getFontMetrics().getStringBounds(str, _graphics);
fontTransform.rotate(-ta.getOrientationAngle() * Math.PI / 180);
final double yy = bounds.getHeight() + bounds.getY();
Point2D.Double pos = new Point2D.Double(text.getPosition().getX(), text.getPosition().getY());
before.transform(pos, pos);
double x = 0;
double y = 0;
if (ta.getOrientationAngle() == 0) {
x = -0.5 * ta.getHorizontalAnchor().getFactor() * bounds.getWidth();
y = 0.5 * ta.getVerticalAnchor().getFactor() * bounds.getHeight() - yy;
x = pos.x + x;
y = pos.y + y;
} else {
x = 0.5 * ta.getVerticalAnchor().getFactor() * bounds.getHeight();
y = 0.5 * ta.getHorizontalAnchor().getFactor() * bounds.getWidth();
// System.err.println("yy="+y+" dx="+x+" dy="+y);
// x = 0;
// y = 0;
x = pos.x + x;
y = pos.y + y;
}
// if (ta.getOrientationAngle() == 0) {
//// System.err.println("x0=" + x);
//// System.err.println("y0=" + y);
// } else {
// System.err.println("bounds=" + bounds + " y=" + bounds.getY() + " h=" + bounds.getHeight() + " vert="
// + ta.getVerticalAnchor().getFactor()+" horz="+ta.getHorizontalAnchor().getFactor());
// System.err.println("x1=" + x);
// System.err.println("y1=" + y);
// }
_graphics.drawString(str, (float) x, (float) y);
// _graphics.fillRect((int)x, (int)y, 5, 5);
_graphics.setTransform(before);
_graphics.setColor(currentColor);
}
}
/**
* Creates a font instance based on the specified text attributes and font
* size.
*
* @param attributes
* Text attributes (font name and style).
* @param size
* Font size in pixel. If 0 {@link #DEFAULT_FONT_SIZE} will be
* used.
* @return new font instance.
*/
static Font createFont(TextAttributes attributes, int size) {
String fontName = attributes.getFontName();
if (fontName == null) {
fontName = DEFAULT_FONT_NAME;
}
FontStyle fontStyle = attributes.getFontStyle();
if (fontStyle == null) {
fontStyle = DEFAULT_FONT_STYLE;
}
int style = Font.PLAIN;
if (fontStyle == FontStyle.BOLD) {
style = Font.BOLD;
} else if (fontStyle == FontStyle.ITALIC) {
style = Font.ITALIC;
} else if (fontStyle == FontStyle.BOLD_ITALIC) {
style = Font.BOLD + Font.ITALIC;
}
if (size == 0) {
size = DEFAULT_FONT_SIZE;
}
return new Font(fontName, style, size);
}
}

View File

@ -1,107 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.renderer;
import java.awt.Graphics2D;
import jcckit.graphic.Anchor;
import jcckit.graphic.ClippingRectangle;
import jcckit.graphic.GraphPoint;
/**
* Transformation between device-independent coordinates
* and standard Java coordinates. The aspect-ratio will
* be the same. The position in the canvas is determined by a
* {@link jcckit.graphic.Rectangle Rectangle} defining a (virtual)
* paper which is placed in the canvas according to an anchor point.
* Depending on the aspect ratio of the canvas the paper width or
* height occupies the canvas width or height.
*
* @author Franz-Josef Elmer
*/
public class Transformation {
private final double _scale, _x0, _y0;
public String toString() {
return "_scale=" + _scale + " _x0=" + _x0 + " _y0=" + _y0;
}
/**
* Creates an instance for the specified canvas size, paper size,
* and anchor points of the paper.
* @param width Width of the canvas.
* @param height Height of the canvas.
* @param paper Rectangle defining the paper in device-independent
* coordinates.
* @param horizontalAnchor Horizontal anchor of the paper in the canvas.
* @param verticalAnchor Vertical anchor of the paper in the canvas.
*/
public Transformation(int width, int height, ClippingRectangle paper,
Anchor horizontalAnchor, Anchor verticalAnchor) {
double pWidth = paper.getMaxX() - paper.getMinX();
double pHeight = paper.getMaxY() - paper.getMinY();
_scale = Math.min(width / pWidth, height / pHeight);
_x0 = 0.5 * horizontalAnchor.getFactor() * (width - _scale * pWidth)
- _scale * paper.getMinX();
_y0 = 0.5 * verticalAnchor.getFactor() * (_scale * pHeight - height)
+ height + _scale * + paper.getMinY();
}
/** Transforms the device-independent x coordinate into Java coordinates. */
public int transformX(double x) {
return trim(_scale * x + _x0);
}
/** Transforms the device-independent y coordinate into Java coordinates. */
public int transformY(double y) {
return trim(_y0 - _scale * y);
}
/** Transforms the device-independent width into Java width. */
public int transformWidth(double width) {
return trim(_scale * width + 0.5);
}
/** Transforms the device-independent height into Java height. */
public int transformHeight(double height) {
return trim(_scale * height + 0.5);
}
private static int trim(double number)
{
return number > Short.MAX_VALUE
? Short.MAX_VALUE
: (number < Short.MIN_VALUE ? Short.MIN_VALUE : (int) number);
}
/**
* Transforms a point in Java coordinates back into device-independent
* coordinates.
*/
public GraphPoint transformBack(int x, int y) {
return new GraphPoint((x - _x0) / _scale, (_y0 - y) / _scale);
}
public void apply(Graphics2D g) {
g.translate(_x0, _y0);
g.scale(_scale, -_scale);
}
}

View File

@ -1,96 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.transformation;
import jcckit.data.DataPoint;
import jcckit.graphic.GraphPoint;
import jcckit.util.Util;
/**
* Two-dimensional Cartesian transformation. The two independent
* transformations for the x-axis and the y-axis can be logarithmic
* from data coordinates to device-independent coordinates in order to
* realize diagrams with logarithmic scales.
*
* @author Franz-Josef Elmer
*/
public class CartesianTransformation implements Transformation {
private final boolean _xLogScale;
private final double _xOffset;
private final double _xScale;
private final boolean _yLogScale;
private final double _yOffset;
private final double _yScale;
/**
* Creates an instance from the specified reference points.
* Note, that the reference points must differ in x and y coordinates
* otherwise a transformation would not be possible.
* @param xLogScale <tt>true</tt> if logarithmic x axis.
* @param yLogScale <tt>true</tt> if logarithmic y axis.
* @param dataPoint1 First reference point in data coordinates.
* @param graphPoint1 First reference point in device-independent
* coordinates.
* @param dataPoint2 Second reference point in data coordinates.
* @param graphPoint2 Second reference point in device-independent
* coordinates.
* @throws IllegalArgumentException if transformation in at least
* one of both directions is not possible.
*/
public CartesianTransformation(boolean xLogScale, boolean yLogScale,
DataPoint dataPoint1, GraphPoint graphPoint1,
DataPoint dataPoint2, GraphPoint graphPoint2) {
_xLogScale = xLogScale;
double d1 = Util.log(dataPoint1.getX(), xLogScale);
double dd = Util.log(dataPoint2.getX(), xLogScale) - d1;
check(dd, "data", "x", d1);
_xScale = (graphPoint2.getX() - graphPoint1.getX()) / dd;
check(_xScale, "graphical", "x", graphPoint1.getX());
_xOffset = graphPoint1.getX() - d1 * _xScale;
_yLogScale = yLogScale;
d1 = Util.log(dataPoint1.getY(), yLogScale);
dd = Util.log(dataPoint2.getY(), yLogScale) - d1;
check(dd, "data", "y", d1);
_yScale = (graphPoint2.getY() - graphPoint1.getY()) / dd;
check(_yScale, "graphical", "y", graphPoint1.getY());
_yOffset = graphPoint1.getY() - d1 * _yScale;
}
private void check(double valueToCheck, String type, String axis,
double value) {
if (valueToCheck == 0) {
throw new IllegalArgumentException("The " + type
+ " reference points in " + axis + " must be different; both are "
+ value);
}
}
public GraphPoint transformToGraph(DataPoint point) {
return new GraphPoint(
_xOffset + Util.log(point.getX(), _xLogScale) * _xScale,
_yOffset + Util.log(point.getY(), _yLogScale) * _yScale);
}
public DataPoint transformToData(GraphPoint point) {
return new DataPoint(
Util.exp((point.getX() - _xOffset) / _xScale, _xLogScale),
Util.exp((point.getY() - _yOffset) / _yScale, _yLogScale));
}
}

View File

@ -1,44 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.transformation;
import jcckit.data.DataPoint;
import jcckit.graphic.GraphPoint;
/**
* Interface for transformations between data coordinates
* and device-independent coordinates.
*
* @author Franz-Josef Elmer
*/
public interface Transformation {
/**
* Transforms a {@link DataPoint} into a {@link GraphPoint}.
* @param point A point in data coordinates.
* @return <tt>point</tt> tranformed into device-independent coordinates..
*/
public GraphPoint transformToGraph(DataPoint point);
/**
* Transforms a {@link GraphPoint} into a {@link DataPoint}.
* @param point A point in device-independent coordinates..
* @return <tt>point</tt> tranformed into data coordinates.
*/
public DataPoint transformToData(GraphPoint point);
}

View File

@ -1,53 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
import java.applet.Applet;
/**
* Implementation of {@link FlatConfigData} based on
* <tt>java.applet.Applet</tt>.
*
* @author Franz-Josef Elmer
*/
public class AppletBasedConfigData extends FlatConfigData {
private final Applet _applet;
/**
* Creates an instance based on the specified applet.
* The path is undefined.
*/
public AppletBasedConfigData(Applet applet) {
this(applet, null);
}
/** Creates an instance based on the specified properties and path. */
private AppletBasedConfigData(Applet applet, String path) {
super(path);
_applet = applet;
}
protected String getValue(String fullKey) {
return _applet.getParameter(fullKey);
}
protected ConfigData createConfigData(String path) {
return new AppletBasedConfigData(_applet, path);
}
}

View File

@ -1,55 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
/**
* Interface for hierarchically managed key-value pairs. The key is
* always a string which contains any kind of printable character except
* '/', '=', ':', and whitespace characters like ' ' and '\t'.
* The value is either a string or a <tt>ConfigData</tt> object.
* <p>
* This interface will be used by {@link ConfigParameters} in accordance
* with the Strategy design pattern.
*
* @author Franz-Josef Elmer
*/
public interface ConfigData {
/**
* Returns the full key.
* @param key A (relative) key. <tt>null</tt> is not allowed.
* @return the full key including path.
*/
public String getFullKey(String key);
/**
* Returns the value associated with this key.
* @param key The relative key. <tt>null</tt> is not allowed.
* @return the associated value. Will be <tt>null</tt> if no value exists
* for <tt>key</tt>.
*/
public String get(String key);
/**
* Returns the <tt>ConfigData</tt> object associated with this key.
* @param key The relative key. <tt>null</tt> is not allowed.
* @return the associated value. Will never return <tt>null</tt>.
* Instead an empty <tt>ConfigData</tt> is returned.
*/
public ConfigData getNode(String key);
}

View File

@ -1,321 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
import java.awt.Color;
import java.util.StringTokenizer;
import net.sourceforge.plantuml.graphic.HtmlColorSet;
import net.sourceforge.plantuml.graphic.HtmlColorSetSimple;
import net.sourceforge.plantuml.graphic.IHtmlColorSet;
import net.sourceforge.plantuml.ugraphic.ColorMapperIdentity;
/**
* Read-only class for hierarchically organized key-value pairs.
* The key is always a string. The following value types are
* supported:
* <ul><li><tt>String</tt>
* <li><tt>boolean</tt>
* <li><tt>int</tt>
* <li><tt>double</tt>
* <li><tt>double[]</tt>
* <li><tt>Color</tt>
* <li><tt>ConfigParameters</tt>
* </ul>
* <p>
* In accordance with the Strategy design pattern the retrieval of
* a key-value pair is delegated to an instance of
* {@link ConfigData}.
*
* @author Franz-Josef Elmer
*/
public class ConfigParameters {
private final ConfigData _configData;
/** Creates an instance from the specified <tt>ConfigData</tt> object. */
public ConfigParameters(ConfigData configData) {
_configData = configData;
}
/**
* Returns the full key.
* @return the path concatenated with <tt>key</tt>.
* @see ConfigData#getFullKey
*/
public String getFullKey(String key) {
return _configData.getFullKey(key);
}
/**
* Returns the string value associated with the specified key.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @return the corresponding value. Will always be not <tt>null</tt>.
* @throws IllegalArgumentException if no value exists for <tt>key</tt>.
* The exception message is the full key.
*/
public String get(String key) {
String result = _configData.get(key);
if (result == null) {
throw new IllegalArgumentException(getFullKey(key));
}
return result;
}
/**
* Returns the string value associated with the specified key or
* <tt>defaultValue</tt> if undefined.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @param defaultValue The default value. Can be <tt>null</tt>.
* @return the corresponding value or <tt>defaultValue</tt>.
*/
public String get(String key, String defaultValue) {
String result = _configData.get(key);
if (result == null) {
result = defaultValue;
}
return result;
}
/**
* Returns the boolean associated with the specified key.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @return <tt>true</tt> if the value is "true" otherwise <tt>false</tt>.
* @throws IllegalArgumentException if no value exists for <tt>key</tt>.
* The exception message is the full key.
* @throws NumberFormatException if the value is neither "true" nor "false".
*/
public boolean getBoolean(String key) {
return parseBoolean(get(key), key);
}
/**
* Returns the boolean associated with the specified key.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @param defaultValue The default value. Can be <tt>null</tt>.
* @return <tt>true</tt> if the value is "true" otherwise <tt>false</tt>.
* @throws NumberFormatException if the value is neither "true" nor "false".
*/
public boolean getBoolean(String key, boolean defaultValue) {
String value = _configData.get(key);
return value == null ? defaultValue : parseBoolean(value, key);
}
private boolean parseBoolean(String value, String key) {
if (value.equals("true")) {
return true;
} else if (value.equals("false")) {
return false;
} else {
throw createNumberFormatException("boolean", value, key);
}
}
private NumberFormatException createNumberFormatException(String text,
String value,
String key) {
return new NumberFormatException("Not a " + text + ": " + getFullKey(key)
+ " = " + value);
}
/**
* Returns the integer associated with the specified key.
* The value can be either
* <ul><li>a decimal number (starting with a non-zero digit),
* <li>a hexadecimal number (starting with <tt>0x</tt>), or
* <li>an octal number (starting with zero).
* </ul>
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @return the integer value.
* @throws IllegalArgumentException if no value exists for <tt>key</tt>.
* The exception message is the full key.
* @throws NumberFormatException if the value is not a number.
* The exception message contains the full key and the invalid value.
*/
public int getInt(String key) {
return parseInt(get(key), key);
}
/**
* Returns the integer associated with the specified key or
* <tt>defaultValue</tt> if no key-value pair exists for the specified key.
* The value can be either
* <ul><li>a decimal number (starting with a non-zero digit),
* <li>a hexadecimal number (starting with <tt>0x</tt>), or
* <li>an octal number (starting with zero).
* </ul>
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @param defaultValue The default value. Can be <tt>null</tt>.
* @return the integer value.
* @throws NumberFormatException if the value exists but is not a number.
* The exception message contains the full key and the invalid value.
*/
public int getInt(String key, int defaultValue) {
String value = _configData.get(key);
return value == null ? defaultValue : parseInt(value, key);
}
private int parseInt(String value, String key) {
try {
return Integer.decode(value).intValue();
} catch (NumberFormatException e) {
throw createNumberFormatException("number", value, key);
}
}
/**
* Returns the double associated with the specified key.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @return the double value.
* @throws IllegalArgumentException if no value exists for <tt>key</tt>.
* The exception message is the full key.
* @throws NumberFormatException if the value is not a valid number.
* The exception message contains the full key and the invalid value.
*/
public double getDouble(String key) {
return parseDouble(get(key), key);
}
/**
* Returns the double associated with the specified key or
* <tt>defaultValue</tt> if no key-value pair exists for the specified key.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @param defaultValue The default value. Can be <tt>null</tt>.
* @return the double value.
* @throws NumberFormatException if the value exists but is not a valid
* number.
* The exception message contains the full key and the invalid value.
*/
public double getDouble(String key, double defaultValue) {
String value = _configData.get(key);
return value == null ? defaultValue : parseDouble(value, key);
}
private double parseDouble(String value, String key) {
try {
return new Double(value).doubleValue();
} catch (NumberFormatException e) {
throw createNumberFormatException("number", value, key);
}
}
/**
* Returns the array of doubles associated with the specified key.
* The numbers are separated by whitespaces.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @return the array of double values.
* @throws IllegalArgumentException if no value exists for <tt>key</tt>.
* The exception message is the full key.
* @throws NumberFormatException if the value exists but is not a
* sequence of number. The exception message contains
* the full key and the invalid value.
*/
public double[] getDoubleArray(String key) {
return parseDoubleArray(get(key), key);
}
/**
* Returns the array of doubles associated with the specified key
* or <tt>defaultValue</tt> if no key-value pair exists for
* the specified key. The numbers are separated by whitespaces.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @param defaultValue The default value. Can be <tt>null</tt>.
* @return the array of double values.
* @throws NumberFormatException if the value exists but is not a
* sequence of number. The exception message contains
* the full key and the invalid value.
*/
public double[] getDoubleArray(String key, double[] defaultValue) {
String value = _configData.get(key);
return value == null ? defaultValue : parseDoubleArray(value, key);
}
private double[] parseDoubleArray(String value, String key) {
try {
StringTokenizer tokenizer = new StringTokenizer(value);
double[] result = new double[tokenizer.countTokens()];
for (int i = 0; i < result.length; i++) {
result[i] = new Double(tokenizer.nextToken()).doubleValue();
}
return result;
} catch (NumberFormatException e) {
throw createNumberFormatException("sequence of numbers", value, key);
}
}
/**
* Returns the color associated with the specified key.
* The color is coded as
* <ul><li>a decimal number (starting with a non-zero digit),
* <li>a hexadecimal number (starting with <tt>0x</tt>), or
* <li>an octal number (starting with zero).
* </ul>
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @return the color.
* @throws NumberFormatException if the value exists but is not a number.
* The exception message contains the full key and the invalid value.
*/
public Color getColor(String key) {
return parseColor(get(key), key);
}
/**
* Returns the color associated with the specified key or the specified
* default value if no key-value pair exists for the specified key.
* The color is coded as
* <ul><li>a decimal number (starting with a non-zero digit),
* <li>a hexadecimal number (starting with <tt>0x</tt>), or
* <li>an octal number (starting with zero).
* </ul>
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @param defaultValue The default value. Can be <tt>null</tt>.
* @return the color or <tt>null</tt> if the value is an empty string.
* @throws NumberFormatException if the value exists but is not a number.
* The exception message contains the full key and the invalid value.
*/
public Color getColor(String key, Color defaultValue) {
String value = _configData.get(key);
return value == null ? defaultValue : parseColor(value, key);
}
private Color parseColor(String value, String key) {
try {
return value.length() == 0 ? null : decodeInternal(value);
} catch (NumberFormatException e) {
throw createNumberFormatException("number", value, key);
}
}
static private IHtmlColorSet colors = new HtmlColorSetSimple();
private Color decodeInternal(String value) {
if (colors.getColorIfValid(value)!=null) {
return new ColorMapperIdentity().getMappedColor(colors.getColorIfValid(value));
}
return Color.decode(value);
}
/**
* Returns the child node associated with the specified key.
* This method returns in any case a non-<tt>null</tt> result.
* @param key The (relative) key. <tt>null</tt> is not allowed.
* @return the corresponding child node which may be empty.
*/
public ConfigParameters getNode(String key) {
return new ConfigParameters(_configData.getNode(key));
}
}

View File

@ -1,74 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
/**
* An implementation of {@link ConfigData} based on two instances of
* {@link ConfigParameters}. The second one serves as a set of
* default parameters. It will be used if the first one has not the requested
* key-value pair.
*
* @author Franz-Josef Elmer
*/
public class ConfigParametersBasedConfigData implements ConfigData {
private ConfigParameters _config;
private ConfigParameters _defaultConfig;
/**
* Creates an instance.
* @param config A set of key-value pairs.
* @param defaultConfig The default set of key-value pairs.
*/
public ConfigParametersBasedConfigData(ConfigParameters config,
ConfigParameters defaultConfig) {
_config = config;
_defaultConfig = defaultConfig;
}
/**
* Returns the full key.
* @param key A (relative) key. <tt>null</tt> is not allowed.
* @return the full key including path.
*/
public String getFullKey(String key) {
return _config.getFullKey(key);
}
/**
* Returns the value associated with this key.
* @param key The relative key. <tt>null</tt> is not allowed.
* @return the associated value. Will be <tt>null</tt> if no value exists
* for <tt>key</tt>.
*/
public String get(String key) {
String value = _config.get(key, null);
return value == null ? _defaultConfig.get(key, null) : value;
}
/**
* Returns the <tt>ConfigData</tt> object associated with this key.
* @param key The relative key. <tt>null</tt> is not allowed.
* @return the associated value. Will never return <tt>null</tt>.
* Instead an empty <tt>ConfigData</tt> is returned.
*/
public ConfigData getNode(String key) {
return new ConfigParametersBasedConfigData(_config.getNode(key),
_defaultConfig.getNode(key));
}
}

View File

@ -1,120 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
import java.lang.reflect.Constructor;
/**
* General purpose factory method based on {@link ConfigParameters}
* and Java's Reflection API.
*
* @author Franz-Josef Elmer
*/
public class Factory {
/** The constant defining the key <tt>className</tt>. */
public static final String CLASS_NAME_KEY = "className";
/** No public constructor necessary. */
private Factory() {}
/**
* Creates an instance of the specified class.
* @param className Fully-qualified name of a class with a default
* constructor.
* @return a new instance.
* @throws IllegalArgumentException if the instance could be created.
*/
public static Object create(String className) {
try {
return Class.forName(className).newInstance();
} catch (Throwable t) {
throw new IllegalArgumentException("Could not create an instance of "
+ className + " because of " + t);
}
}
/**
* Creates an object based on the specified configuration
* parameters. The class of the object is determined by the
* parameter with the key {@link #CLASS_NAME_KEY}.
* The constructor with a single argument of the type
* <tt>ConfigParameter</tt> is invoked with the argument
* <tt>configParameters</tt>. If such a constructor
* does not exists the default constructor is invoked. If
* neither of these constructors exist a {@link FactoryException}
* is thrown.
* @param configParameters Configuration parameters.
* @return the newly created object.
* @throws IllegalArgumentException if key <tt>className</tt> is missing.
* @throws FactoryException wrapping any kind of exception or error occured.
*/
public static Object create(ConfigParameters configParameters) {
String className = configParameters.get(CLASS_NAME_KEY);
return createObject(configParameters, className);
}
/**
* Creates an object based on the specified configuration
* parameters and default class name. If the
* parameter with the key {@link #CLASS_NAME_KEY} is missed in
* <tt>configParameters</tt> <tt>defaultClassName</tt> is used.
* Otherwise it works as {@link #create(jcckit.util.ConfigParameters)}.
* @param configParameters Configuration parameters.
* @param defaultClassName Default class name.
* @return the newly created object.
* @throws FactoryException wrapping any kind of exception or error occured.
*/
public static Object create(ConfigParameters configParameters,
String defaultClassName) {
String className = configParameters.get(CLASS_NAME_KEY, defaultClassName);
return createObject(configParameters, className);
}
/**
* Creates an object based on the specified configuration
* parameters or returns the default object. This method behaves
* as {@link #create(jcckit.util.ConfigParameters)}, except that is does
* not throw an <tt>IllegalArgumentException</tt> if key <tt>className</tt>
* is missing. Instead <tt>defaultObject</tt> is returned.
*/
public static Object createOrGet(ConfigParameters configParameters,
Object defaultObject) {
String className = configParameters.get(CLASS_NAME_KEY, null);
return className == null ? defaultObject
: createObject(configParameters, className);
}
private static Object createObject(ConfigParameters configParameters,
String className) {
try {
Class c = Class.forName(className);
Object result = null;
Constructor constructor = null;
try {
constructor = c.getConstructor(new Class[] {ConfigParameters.class});
result = constructor.newInstance(new Object[] {configParameters});
} catch (NoSuchMethodException e) {
result = c.newInstance();
}
return result;
} catch (Throwable t) {
throw new FactoryException(configParameters, CLASS_NAME_KEY, t);
}
}
}

View File

@ -1,79 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
import java.lang.reflect.InvocationTargetException;
/**
* Exception thrown in the case of an error during creation of a new
* object by {@link Factory#create}.
*
* @author Franz-Josef Elmer
*/
public class FactoryException extends RuntimeException {
private final String _fullKey;
private final String _className;
private final Object _reason;
/**
* Creates a new instance based on the specified configuration parameters
* and reason object.
* <p>
* If <tt>reason</tt> is an instance of <tt>InvocationTargetException</tt>
* it will be replaced by the wrapped <tt>Throwable</tt>.
* @param configParameters Configuration parameters from which the
* <tt>className</tt> will be extracted (if it exists, otherwise
* <tt>null</tt> will be taken).
* @param reason The reason causing this exception. Most often an
* an exception.
*/
public FactoryException(ConfigParameters configParameters, String key,
Object reason) {
_fullKey = configParameters.getFullKey(key);
_className = configParameters.get(key, null);
if (reason instanceof InvocationTargetException) {
reason = ((InvocationTargetException) reason).getTargetException();
}
_reason = reason;
}
/** Returns the full class name key. */
public String getFullKey() {
return _fullKey;
}
/** Returns the fully qualified class name. */
public String getClassName() {
return _className;
}
/** Returns the reason object causing this exception. */
public Object getReason() {
return _reason;
}
/**
* Renders this instance as follows: <tt>jcckit.util.FactoryException:
* <i>full key</i> = <i>class name</i>: <i>reason</i></tt>.
*/
public String toString() {
return getClass().getName() + ": " + _fullKey + " = " + _className
+ ": " + _reason;
}
}

View File

@ -1,187 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
/**
* An implementation of <tt>ConfigData</tt> based on a flat
* representation of the hierachically organized key-value pairs.
* Concrete subclasses must implement the methods
* {@link #getValue} and {@link #createConfigData} in accordance
* with the Template Method pattern and Factory Method pattern,
* respectively.
* <p>
* In a flat representation of hierachically organized key-value
* pairs all key-value pairs are stored in a single <tt>Hashtable</tt>.
* Its key is the <em>full key</em> of the configuration data (i.e. the key
* including its path).
* <p>
* Example (using the notation for a <tt>.properties</tt> file):
* <pre>
* title = example
* symbolAttributes/className = jcckit.graphic.BasicDrawingAttributes
* symbolAttributes/fillColor = 0xcaffee
* symbolAttributes/lineColor = 0xff0000
* </pre>
* The following table shows the result of some method calls at a
* <tt>FlatConfigData</tt> instance prepared with
* this example:
* <p>
* <center>
* <table border=1 cellspacing=1 cellpadding=5>
* <tr><th>Method call</th><th>Result</th></tr>
* <tr><td>get(&quot;title&quot;)</td><td>example</td></tr>
* <tr><td>getNode(&quot;symbolAttributes&quot;).get(&quot;fillColor&quot;)
* </td><td>0xcaffee</td></tr>
* </table>
* </center>
* <p>
* In addition <tt>FlatConfigData</tt> implements <b>inheritance</b>
* of key-value pairs.
* Basically a node in the tree of key-value pairs
* may extend another node in the tree.
* The extended node inherit all key-value pairs from the extending
* one including the key-value pairs of all descendants.
* The value of a inherited key-value pair may be overridden.
* Also new key-value pairs may be placed in the inherited node or
* anywhere in the subtree.
* Note, that the extending node has to be a node which is not a
* descendant of the extended node (otherwise a circulary chain
* of references occurs). As a consequence not more than 20 inheritance
* levels are allowed.
* <p>
* The implementation of this kind of inheritance in a flat hashtable
* is done by an additional key-value pair of the form
* <pre>
* <i>extending-node</i><b>/</b> = <i>extended-node</i><b>/</b>
* </pre>
* Example:
* <pre>
* A/a/priority = high
* A/a/alpha/hello = universe
* A/a/alpha/answer = 42
* <b>A/b/1/ = A/a/</b>
* A/b/1/alpha/hello = world
* A/b/1/alpha/question = 6 * 7
* </pre>
* The following table shows the result of various method calls
* applied at the node <tt>A/b/1/</tt> of a <tt>FlatConfigData</tt>
* instance prepared with this example:
* <p>
* <center>
* <table border=1 cellspacing=1 cellpadding=5>
* <tr><th>Method call</th><th>Result</th><th>Comment</th></tr>
* <tr><td>get(&quot;priority&quot;)</td><td>high</td><td>inherited</td></tr>
* <tr><td>getNode(&quot;alpha&quot;).get(&quot;hello&quot;)
* </td><td>world</td><td>overridden</td></tr>
* <tr><td>getNode(&quot;alpha&quot;).get(&quot;question&quot;)
* </td><td>6 * 7</td><td>added</td></tr>
* <tr><td>getNode(&quot;alpha&quot;).get(&quot;answer&quot;)
* </td><td>42</td><td>inherited</td></tr>
* </table>
* </center>
*
* @author Franz-Josef Elmer
*/
public abstract class FlatConfigData implements ConfigData {
private final String _path;
/** Creates a new instance for the specified path. */
public FlatConfigData(String path) {
_path = path;
}
/**
* Returns the full key.
* @param key A (relative) key. <tt>null</tt> is not allowed.
* @return the path concatenated with <tt>key</tt> or <tt>key</tt>
* if the path is undefined.
*/
public String getFullKey(String key) {
return _path == null ? key : _path + key;
}
/**
* Returns the value associated with this key.
* @param key The relative key. <tt>null</tt> is not allowed.
* @return the associated value. Will be <tt>null</tt> if no value exists
* for <tt>key</tt>.
*/
public String get(String key) {
return get(_path, key, 0);
}
/**
* Obtains a value in accordance with hierarchy (<tt>path</tt>) and
* inheritance (recursive calls of this routine).
*/
private String get(String path, String key, int numberOfLevels) {
String result = null;
if (numberOfLevels < 20) {
String fullKey = path == null ? key : path + key;
result = getValue(fullKey);
if (result == null) {
// posAfterDelim is the index in path just after '/'
int posAfterDelim = path == null ? -1 : path.length();
String replacement;
while (posAfterDelim > 0) {
// look for a sub-tree
replacement = getValue(path.substring(0, posAfterDelim));
if (replacement != null) {
// sub-tree found, add last part of the original path
result = get(replacement + path.substring(posAfterDelim), key,
numberOfLevels + 1);
// break whether result is null or not.
break;
}
// remove last element from the path
posAfterDelim = path.lastIndexOf('/', posAfterDelim - 2) + 1;
}
}
}
return result;
}
/**
* Returns the <tt>ConfigData</tt> object associated with this key.
* @param key The relative key.
* @return the associated value. Will never return <tt>null</tt>.
* Instead an empty <tt>ConfigData</tt> is returned.
*/
public ConfigData getNode(String key) {
String path = (_path == null ? key : _path + key) + '/';
return createConfigData(path);
}
/**
* Returns the value for the specified full key from the flat
* representation of the hierarchically organized key-value pairs.
* @param fullKey The full key including path. <tt>null</tt> is not allowed.
* @return the value or <tt>null</tt> if not found.
*/
protected abstract String getValue(String fullKey);
/**
* Returns the <tt>FlatConfigData</tt> object for the specified full path.
* In general <tt>path</tt> will be used in the constructor with
* path argument.
* @param path The full path.
* @return a new instance in any case.
*/
protected abstract ConfigData createConfigData(String path);
}

View File

@ -1,208 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
import java.util.Vector;
/**
* A helper class for formatting numbers according to
* a <tt>printf</tt>-like format string. Each instance of
* this class is initialized by a format string for a
* single number.
*
* @author Franz-Josef Elmer
*/
public class Format implements TicLabelFormat {
/**
* Creates a new instance based of specified key-value pair of the
* specified configuration parameters.
* @param config Config parameters.
* @param key The key of the key-value pair in <tt>config</tt> containing
* the format string.
* @return <tt>null</tt> if undefined key-value pair or format string
* is an empty string.
* @throws FactoryException if the format string is invalid.
*/
public static Format create(ConfigParameters config, String key) {
Format result = null;
String format = config.get(key, null);
if (format != null && format.length() > 0) {
try {
result = new Format(format);
} catch (Exception e) {
throw new FactoryException(config, key, e);
}
}
return result;
}
private final FormatElement[] _formatElements;
private final Vector _staticParts;
/**
* Creates an instance for the specified format string.
* The format string is an alternation of some static texts and
* format elements.
* A format element has to start with '%' and it must end with
* one of the following format descriptors:
* <table border=0 cellpadding=5>
* <tr><td><tt>d</tt></td>
* <td>decimal integer</td></tr>
* <tr><td><tt>o</tt></td>
* <td>octal integer</td></tr>
* <tr><td><tt>x</tt></td>
* <td>hex integer</td></tr>
* <tr><td><tt>f</tt></td>
* <td>floating point number with a fixed decimal point</td></tr>
* <tr><td><tt>e,&nbsp;E</tt></td>
* <td>floating point number in logarithmic format</td></tr>
* <tr><td><tt>g,&nbsp;G</tt></td>
* <td>floating point number rendered either in fixed-decimal
* format of logarithmic format depending on the size of
* the mantissa.</td></tr>
* </table>
* The characters between '%' and the decriptor are optional.
* They can be grouped into
* <ul><li>modifier<br>
* it is
* <ul><li>'-' if the formated result should be flushed left
* <li>'+' if the sign should be always appear
* <li>'0' if the leading space should be filled with zeros
* </ul>
* <li>width<br>
* a decimal number given the minimum number of characters
* of the result
* <li>precision
* </ul>
* A plain '%' is coded as '%%'.
* @param formatString The format string.
* @exception IllegalArgumentException if invalid format string.
*/
public Format(String formatString) {
_staticParts = new Vector();
Vector formatElements = new Vector();
StringBuffer part = new StringBuffer();
boolean insideFormatElement = false;
boolean atPercentSymbol = false;
for (int i = 0, n = formatString.length(); i < n; i++) {
char c = formatString.charAt(i);
if (insideFormatElement) {
part.append(c);
if (FormatElement.DESCRIPTORS.indexOf(c) >= 0) {
formatElements.addElement(new String(part));
part.setLength(0);
insideFormatElement = false;
}
} else if (atPercentSymbol) {
atPercentSymbol = false;
if (c != '%') {
_staticParts.addElement(new String(part));
part.setLength(0);
insideFormatElement = true;
}
part.append(c);
if (FormatElement.DESCRIPTORS.indexOf(c) >= 0) {
formatElements.addElement(new String(part));
part.setLength(0);
insideFormatElement = false;
}
} else {
if (c == '%') {
atPercentSymbol = true;
} else {
part.append(c);
}
}
}
if (insideFormatElement) {
formatElements.addElement(new String(part));
} else {
_staticParts.addElement(new String(part));
}
_formatElements = new FormatElement[formatElements.size()];
for (int i = 0; i < _formatElements.length; i++) {
_formatElements[i]
= new FormatElement((String) formatElements.elementAt(i));
}
}
/**
* Format a number.
* If there are no format elements the numbers will be ignored.
* If there are more than one format elements the
* additional format elements will be ignored and only the static parts
* are taken.
* @param number Number to be formated.
* @return Formated number.
*/
public String form(long number) {
StringBuffer result = new StringBuffer();
result.append(_staticParts.elementAt(0));
if (_formatElements.length > 0) {
_formatElements[0].form(result, number);
}
return appendRest(result);
}
/**
* Format a number.
* If there are no format elements the numbers will be ignored.
* If there are more than one format elements the
* additional format elements will be ignored and only the static parts
* are taken.
* @param number Number to be formated.
* @return Formated number.
*/
public String form(double number) {
StringBuffer result = new StringBuffer();
result.append(_staticParts.elementAt(0));
if (_formatElements.length > 0) {
_formatElements[0].form(result, number);
}
return appendRest(result);
}
private String appendRest(StringBuffer buffer) {
for (int i = 1, n = _staticParts.size(); i < n; i++) {
buffer.append(_staticParts.elementAt(i));
}
return new String(buffer);
}
/**
* Format an array of double numbers.
* If there are less format elements than numbers the additional numbers
* will be ignored. If there are less numbers than format elements the
* additional format elements will be ignored and only the static parts
* are taken.
* @param numbers Numbers to be formated.
* @return Formated numbers.
*/
public String form(double[] numbers) {
StringBuffer result = new StringBuffer();
for (int i = 0, n = _staticParts.size(); i < n; i++) {
result.append(_staticParts.elementAt(i));
if (i < _formatElements.length && i < numbers.length) {
_formatElements[i].form(result, numbers[i]);
}
}
return new String(result);
}
}

View File

@ -1,242 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
/**
*
*
* @author Franz-Josef Elmer
*/
class FormatElement {
/** All descriptor characters. */
static final String DESCRIPTORS = "doxfeEgG";
private static final String INT_DESCRIPTORS = "dox";
private static final int INT_DESCRIPTOR = 0;
private static final int FLOAT_DESCRIPTOR = 1;
/**
* Calculate the integer power of a floating point number.
* @param n Exponent.
* @param x Number.
* @return <tt>x^n</tt>.
*/
private static final double power(double x, int n) {
return n < 0 ? 1.0 / power2(x, -n) : power2(x, n);
}
/** Calculate <tt>x^n</tt> recursively assuming <tt>n > 0</tt>. */
private static final double power2(double x, int n) {
switch (n) {
case 0: return 1;
case 1: return x;
default:
double p = power2(x, n / 2);
return p * p * power2(x, n % 2);
}
}
private final char _descriptor;
private final int _descriptorType;
private final double _tenToPrecision;
private boolean _decimalPoint;
private boolean _flushLeft;
private boolean _leadingZeros;
private boolean _alwaysSign;
private int _width;
private int _precision;
/** Creates an instance for the specified format string. */
FormatElement(String formatString) {
int len = formatString.length() - 1;
_descriptor = formatString.charAt(len);
if (DESCRIPTORS.indexOf(_descriptor) < 0) {
throw new IllegalArgumentException("Format element '" + formatString
+ "' does not ends with one of the following characters: "
+ DESCRIPTORS);
}
_descriptorType = INT_DESCRIPTORS.indexOf(_descriptor) >= 0
? INT_DESCRIPTOR : FLOAT_DESCRIPTOR;
if (formatString.length() > 1) {
switch (formatString.charAt(0)) {
case '-':
_flushLeft = true;
formatString = formatString.substring(1);
break;
case '0':
_leadingZeros = true;
formatString = formatString.substring(1);
break;
case '+':
_alwaysSign = true;
formatString = formatString.substring(1);
break;
}
len = formatString.length() - 1;
int index = formatString.indexOf('.');
_decimalPoint = index >= 0;
int last = _decimalPoint ? index : len;
if (last > 0) {
_width = Integer.parseInt(formatString.substring(0, last));
}
if (_decimalPoint) {
index++;
if (index < len) {
_precision = Integer.parseInt(formatString.substring(index, len));
}
}
}
_tenToPrecision = power(10, _precision);
}
/**
* Format a number in accordance of the format string
* given at the initialisation of this instance.
* @param buffer Buffer to which the formated output will be appended.
* @param number Number to be formated.
*/
public void form(StringBuffer buffer, long number) {
if (_descriptorType == FLOAT_DESCRIPTOR) {
form(buffer, (double) number);
} else {
// Format absolut value in the right base
buffer.append(form(number < 0,
Long.toString(Math.abs(number),
_descriptor == 'o' ? 8
: (_descriptor == 'x' ? 16 : 10)),
""));
}
}
/**
* Format a number in accordance of the format string
* given at the initialisation of this instance.
* @param buffer Buffer to which the formated output will be appended.
* @param number Number to be formated.
*/
public void form(StringBuffer buffer, double number) {
if (_descriptorType == INT_DESCRIPTOR) {
form(buffer, (long) Math.floor(number + 0.5));
} else if (_descriptor == 'f') {
buffer.append(formF(number));
} else if (_descriptor == 'e' || _descriptor == 'E') {
buffer.append(formE(number));
} else if (_descriptor == 'g' || _descriptor == 'G') {
String formF = formF(number);
String formE = formE(number);
buffer.append(formF.length() > formE.length() ? formE : formF);
}
}
private String form(boolean negativeValue, String intPart, String fracPart) {
int len = intPart.length() + fracPart.length();
// Buffer holding the result
StringBuffer result = new StringBuffer();
int count = 0;
// add sign if necessary
if (_alwaysSign || negativeValue) {
result.append(negativeValue ? '-' : '+');
count++;
}
// add zeros if necessary
if (_leadingZeros) {
for (int i = count + len; i < _width; i++) {
result.append('0');
count++;
}
}
// add number
result.append(intPart).append(fracPart);
count += len;
// add spaces if necessary
if (_flushLeft) {
for (; count < _width; count++) {
result.append(' ');
}
} else {
for (; count < _width; count++) {
result.insert(0, ' ');
}
}
return new String(result);
}
/** Format floating point number with exponent. */
private String formE(double number) {
// format absolute mantisse
int exponent = 0;
String zeros = "00000000000000000000000".substring(0, _precision + 1);
if (number != 0) {
exponent = (int) Math.floor(Math.log(Math.abs(number)) / Math.log(10));
double mantisse = Math.floor(Math.abs(number * power(10.0,
_precision - exponent)) + 0.5);
if (mantisse >= 10 * _tenToPrecision) {
exponent++;
mantisse = Math.floor(Math.abs(number * power(10.0,
_precision - exponent)) + 0.5);
}
zeros = Long.toString((long) mantisse);
}
// make fractional part
StringBuffer fracPart = new StringBuffer();
if (_decimalPoint) {
fracPart.append('.').append(zeros.substring(1));
}
// make exponent
fracPart.append(Character.isLowerCase(_descriptor) ? 'e': 'E')
.append(exponent < 0 ? '-' : '+');
exponent = Math.abs(exponent);
for (int i = 0, n = fracPart.length(); i < 3; i++) {
fracPart.insert(n, Character.forDigit(exponent % 10, 10));
exponent /= 10;
}
return form(number < 0, zeros.substring(0, 1), new String(fracPart));
}
/** Format floating point number. */
private String formF(double number) {
// Format absolut value
double multiplier = number < 0 ? - _tenToPrecision : _tenToPrecision;
String digits
= Long.toString((long) Math.floor(number * multiplier + 0.5));
String intPart = digits;
StringBuffer fracPart = new StringBuffer();
if (_decimalPoint) {
int len = digits.length() - _precision;
fracPart.append('.').append(digits.substring(Math.max(0, len)));
if (len > 0) {
intPart = digits.substring(0, len);
} else {
intPart = "0";
for (; len < 0; len++) {
fracPart.insert(1, '0');
}
}
}
return form(number < 0, intPart, new String(fracPart));
}
}

View File

@ -1,65 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
/**
* Immutable class of a two-dimensional point with floating point
* coordinates.
*
* @author Franz-Josef Elmer
*/
public class Point {
private final double _x;
private final double _y;
/**
* Creates an instance for the specified vector. The value of the
* first/second element of <tt>vector</tt> denotes the x/y value.
* If <tt>vector</tt> is <tt>null</tt> or not long enough 0 will be used
* as default values.
*/
public Point(double[] vector) {
double x = 0;
double y = 0;
if (vector != null && vector.length > 0) {
x = vector[0];
if (vector.length > 1) {
y = vector[1];
}
}
_x = x;
_y = y;
}
/** Creates an instance for the specified coordinates. */
public Point(double x, double y) {
_x = x;
_y = y;
}
/** Returns the x-coordinate of the point. */
public double getX() {
return _x;
}
/** Returns the y-coordinate of the point. */
public double getY() {
return _y;
}
}

View File

@ -1,81 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
/**
* Implementation of {@link FlatConfigData} based on
* <tt>java.util.Properties</tt>.
*
* @author Franz-Josef Elmer
*/
public class PropertiesBasedConfigData extends FlatConfigData {
private final Properties _properties;
/**
* Creates an instance from the specified <tt>.properties</tt> file.
* @param fileName File name of the <tt>.properties</tt> file relative
* to the working directory or absolute.
* @throws IOException if the <tt>.properties</tt> does not exist or could
* not be read.
*/
public PropertiesBasedConfigData(String fileName) throws IOException {
super(null);
_properties = new Properties();
_properties.load(new FileInputStream(fileName));
}
/**
* Creates an instance based on the specified properties.
* The path is undefined.
*/
public PropertiesBasedConfigData(Properties properties) {
this(properties, null);
}
/** Creates an instance based on the specified properties and path. */
private PropertiesBasedConfigData(Properties properties, String path) {
super(path);
_properties = properties;
}
/**
* Returns the value for the specified full key. The call will be delegated
* to the wrapped <tt>java.util.properties</tt> object.
* @param fullKey The full key including path. <tt>null</tt> is not allowed.
* @return the value or <tt>null</tt> if not found.
*/
protected String getValue(String fullKey) {
return _properties.getProperty(fullKey);
}
/**
* Returns a new instance of <tt>PropertiesBasedConfigData</tt>
* for the specified full path. The wrapped <tt>java.util.Properties</tt>
* will be the same as of this instance.
* @param path The full path.
* @return a new instance.
*/
protected ConfigData createConfigData(String path) {
return new PropertiesBasedConfigData(_properties, path);
}
}

View File

@ -1,33 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
/**
* Format interface for tic labels. Maps a numerical tic value onto a string.
*
* @author Franz-Josef Elmer
*/
public interface TicLabelFormat
{
/**
* Forms the specified tic value to a string. Note, the numerical
* <tt>ticValue</tt> may be mapped onto a non-numerical one.
*/
public String form(double ticValue);
}

View File

@ -1,47 +0,0 @@
/*
* Copyright 2003-2004, Franz-Josef Elmer, All rights reserved
*
* 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 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 Lesser General Public License for more details
* (http://www.gnu.org/copyleft/lesser.html).
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package jcckit.util;
/**
* Collection of static utility methods.
*
* @author Franz-Josef Elmer
*/
public class Util {
/** Private constructor to prevent instanciation of this class. */
private Util() {}
/**
* Returns the natural logarithm of the specified number if
* <tt>logScale</tt> is true.
* @return <tt>x</tt> if <tt>logScale == false</tt>.
*/
public static double log(double x, boolean logScale) {
return logScale ? Math.log(x) : x;
}
/**
* Returns the exponential function of the specified number if
* <tt>logScale</tt> is true.
* @return <tt>x</tt> if <tt>logScale == false</tt>.
*/
public static double exp(double x, boolean logScale) {
return logScale ? Math.exp(x) : x;
}
}

View File

@ -52,6 +52,9 @@ import net.sourceforge.plantuml.graphic.SymbolContext;
import net.sourceforge.plantuml.graphic.TextBlock; import net.sourceforge.plantuml.graphic.TextBlock;
import net.sourceforge.plantuml.graphic.TextBlockUtils; import net.sourceforge.plantuml.graphic.TextBlockUtils;
import net.sourceforge.plantuml.graphic.USymbol; import net.sourceforge.plantuml.graphic.USymbol;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleDefinition;
import net.sourceforge.plantuml.svek.DecorateEntityImage; import net.sourceforge.plantuml.svek.DecorateEntityImage;
import net.sourceforge.plantuml.svek.TextBlockBackcolored; import net.sourceforge.plantuml.svek.TextBlockBackcolored;
import net.sourceforge.plantuml.ugraphic.MinMax; import net.sourceforge.plantuml.ugraphic.MinMax;
@ -146,7 +149,6 @@ public class AnnotatedWorker {
return original; return original;
} }
final TextBlock text = getCaption(); final TextBlock text = getCaption();
return DecorateEntityImage.addBottom(original, text, HorizontalAlignment.CENTER); return DecorateEntityImage.addBottom(original, text, HorizontalAlignment.CENTER);
} }
@ -155,6 +157,11 @@ public class AnnotatedWorker {
if (caption.isNull()) { if (caption.isNull()) {
return TextBlockUtils.empty(0, 0); return TextBlockUtils.empty(0, 0);
} }
if (SkinParam.USE_STYLES()) {
final Style style = StyleDefinition.of(SName.root, SName.caption).getMergedStyle(
skinParam.getCurrentStyleBuilder());
return style.createTextBlockBordered(caption.getDisplay(), skinParam.getIHtmlColorSet(), skinParam);
}
return caption.getDisplay().create(new FontConfiguration(getSkinParam(), FontParam.CAPTION, null), return caption.getDisplay().create(new FontConfiguration(getSkinParam(), FontParam.CAPTION, null),
HorizontalAlignment.CENTER, getSkinParam()); HorizontalAlignment.CENTER, getSkinParam());
} }
@ -165,6 +172,9 @@ public class AnnotatedWorker {
return original; return original;
} }
ISkinParam skinParam = getSkinParam(); ISkinParam skinParam = getSkinParam();
// if (SkinParam.USE_STYLES()) {
// throw new UnsupportedOperationException();
// }
final FontConfiguration fontConfiguration = new FontConfiguration(skinParam, FontParam.TITLE, null); final FontConfiguration fontConfiguration = new FontConfiguration(skinParam, FontParam.TITLE, null);
final TextBlock block = TextBlockUtils.title(fontConfiguration, title.getDisplay(), skinParam); final TextBlock block = TextBlockUtils.title(fontConfiguration, title.getDisplay(), skinParam);

View File

@ -38,6 +38,8 @@ package net.sourceforge.plantuml;
import java.awt.Font; import java.awt.Font;
import net.sourceforge.plantuml.graphic.FontConfiguration; import net.sourceforge.plantuml.graphic.FontConfiguration;
import net.sourceforge.plantuml.style.SName;
import net.sourceforge.plantuml.style.StyleDefinition;
interface FontParamConstant { interface FontParamConstant {
String FAMILY = "SansSerif"; String FAMILY = "SansSerif";
@ -179,4 +181,18 @@ public enum FontParam {
return new FontConfiguration(skinParam, this, null); return new FontConfiguration(skinParam, this, null);
} }
public StyleDefinition getStyleDefinition() {
if (this == FOOTER) {
return StyleDefinition.of(SName.root, SName.footer);
}
if (this == HEADER) {
return StyleDefinition.of(SName.root, SName.header);
}
if (this == TITLE) {
return StyleDefinition.of(SName.root, SName.title);
}
System.err.println("Warning " + this);
return null;
}
} }

View File

@ -43,6 +43,9 @@ import net.sourceforge.plantuml.graphic.HtmlColor;
import net.sourceforge.plantuml.graphic.SkinParameter; import net.sourceforge.plantuml.graphic.SkinParameter;
import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.skin.ArrowDirection; import net.sourceforge.plantuml.skin.ArrowDirection;
import net.sourceforge.plantuml.skin.Padder;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.ConditionEndStyle; import net.sourceforge.plantuml.svek.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle; import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.svek.PackageStyle; import net.sourceforge.plantuml.svek.PackageStyle;
@ -168,4 +171,10 @@ public interface ISkinParam extends ISkinSimple {
public boolean isUseVizJs(); public boolean isUseVizJs();
public Padder getSequenceDiagramPadder();
public StyleBuilder getCurrentStyleBuilder();
public void muteStyle(Style modifiedStyle);
} }

View File

@ -56,10 +56,16 @@ import net.sourceforge.plantuml.version.Version;
public class OptionPrint { public class OptionPrint {
static public void printTestDot() throws InterruptedException { static public void printTestDot() throws InterruptedException {
for (String s : GraphvizUtils.getTestDotStrings(false)) { final List<String> result = new ArrayList<String>();
System.out.println(s); final int errorCode = GraphvizUtils.addDotStatus(result, false);
for (String s : result) {
if (errorCode == 0) {
System.out.println(s);
} else {
System.err.println(s);
}
} }
exit(); exit(errorCode);
} }
static public void printHelp() throws InterruptedException { static public void printHelp() throws InterruptedException {
@ -149,12 +155,12 @@ public class OptionPrint {
System.out.println(" -cypher\t\tTo cypher texts of diagrams so that you can share them"); System.out.println(" -cypher\t\tTo cypher texts of diagrams so that you can share them");
System.out.println(); System.out.println();
System.out.println("If needed, you can setup the environment variable GRAPHVIZ_DOT."); System.out.println("If needed, you can setup the environment variable GRAPHVIZ_DOT.");
exit(); exit(0);
} }
static private void exit() throws InterruptedException { static private void exit(int errorCode) throws InterruptedException {
if (OptionFlags.getInstance().isSystemExit()) { if (OptionFlags.getInstance().isSystemExit() || errorCode != 0) {
System.exit(0); System.exit(errorCode);
} }
throw new InterruptedException("exit"); throw new InterruptedException("exit");
} }
@ -163,11 +169,11 @@ public class OptionPrint {
for (String s : License.getCurrent().getTextFull()) { for (String s : License.getCurrent().getTextFull()) {
System.out.println(s); System.out.println(s);
} }
exit(); exit(0);
} }
public static void printVersion() throws InterruptedException { public static void printVersion() throws InterruptedException {
System.out.println("PlantUML version " + Version.versionString() + " (" + Version.compileTimeString() + ")"); System.out.println(Version.fullDescription());
System.out.println("(" + License.getCurrent() + " source distribution)"); System.out.println("(" + License.getCurrent() + " source distribution)");
for (String v : interestingProperties()) { for (String v : interestingProperties()) {
System.out.println(v); System.out.println(v);
@ -176,10 +182,12 @@ public class OptionPrint {
System.out.println(v); System.out.println(v);
} }
System.out.println(); System.out.println();
for (String s : GraphvizUtils.getTestDotStrings(false)) { final List<String> result = new ArrayList<String>();
final int errorCode = GraphvizUtils.addDotStatus(result, false);
for (String s : result) {
System.out.println(s); System.out.println(s);
} }
exit(); exit(errorCode);
} }
public static Collection<String> interestingProperties() { public static Collection<String> interestingProperties() {
@ -250,7 +258,7 @@ public class OptionPrint {
} }
public static void checkVersion() throws InterruptedException { public static void checkVersion() throws InterruptedException {
System.out.println("PlantUML version " + Version.versionString() + " (" + Version.compileTimeString() + ")"); System.out.println(Version.fullDescription());
System.out.println(); System.out.println();
final int lastversion = PSystemVersion.extractDownloadableVersion(null, null); final int lastversion = PSystemVersion.extractDownloadableVersion(null, null);
if (lastversion == -1) { if (lastversion == -1) {
@ -270,19 +278,19 @@ public class OptionPrint {
} }
} }
exit(); exit(0);
} }
public static void printAbout() throws InterruptedException { public static void printAbout() throws InterruptedException {
for (String s : PSystemVersion.getAuthorsStrings(false)) { for (String s : PSystemVersion.getAuthorsStrings(false)) {
System.out.println(s); System.out.println(s);
} }
OptionPrint.exit(); exit(0);
} }
public static void printLanguage() throws InterruptedException { public static void printLanguage() throws InterruptedException {
new LanguageDescriptor().print(System.out); new LanguageDescriptor().print(System.out);
exit(); exit(0);
} }
} }

View File

@ -38,6 +38,9 @@ package net.sourceforge.plantuml;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import net.sourceforge.plantuml.acearth.PSystemXearthFactory; import net.sourceforge.plantuml.acearth.PSystemXearthFactory;
import net.sourceforge.plantuml.activitydiagram.ActivityDiagramFactory; import net.sourceforge.plantuml.activitydiagram.ActivityDiagramFactory;
@ -45,6 +48,7 @@ import net.sourceforge.plantuml.activitydiagram3.ActivityDiagramFactory3;
import net.sourceforge.plantuml.api.PSystemFactory; import net.sourceforge.plantuml.api.PSystemFactory;
import net.sourceforge.plantuml.bpm.BpmDiagramFactory; import net.sourceforge.plantuml.bpm.BpmDiagramFactory;
import net.sourceforge.plantuml.classdiagram.ClassDiagramFactory; import net.sourceforge.plantuml.classdiagram.ClassDiagramFactory;
import net.sourceforge.plantuml.command.UmlDiagramFactory;
import net.sourceforge.plantuml.command.regex.RegexConcat; import net.sourceforge.plantuml.command.regex.RegexConcat;
import net.sourceforge.plantuml.compositediagram.CompositeDiagramFactory; import net.sourceforge.plantuml.compositediagram.CompositeDiagramFactory;
import net.sourceforge.plantuml.core.Diagram; import net.sourceforge.plantuml.core.Diagram;
@ -69,7 +73,6 @@ import net.sourceforge.plantuml.error.PSystemErrorUtils;
import net.sourceforge.plantuml.flowdiagram.FlowDiagramFactory; import net.sourceforge.plantuml.flowdiagram.FlowDiagramFactory;
import net.sourceforge.plantuml.font.PSystemListFontsFactory; import net.sourceforge.plantuml.font.PSystemListFontsFactory;
import net.sourceforge.plantuml.help.HelpFactory; import net.sourceforge.plantuml.help.HelpFactory;
import net.sourceforge.plantuml.jcckit.PSystemJcckitFactory;
import net.sourceforge.plantuml.math.PSystemLatexFactory; import net.sourceforge.plantuml.math.PSystemLatexFactory;
import net.sourceforge.plantuml.math.PSystemMathFactory; import net.sourceforge.plantuml.math.PSystemMathFactory;
import net.sourceforge.plantuml.mindmap.MindMapDiagramFactory; import net.sourceforge.plantuml.mindmap.MindMapDiagramFactory;
@ -139,10 +142,9 @@ public class PSystemBuilder {
Log.info("Compilation duration " + (System.currentTimeMillis() - now)); Log.info("Compilation duration " + (System.currentTimeMillis() - now));
RegexConcat.printCacheInfo(); RegexConcat.printCacheInfo();
} }
} }
private List<PSystemFactory> getAllFactories(ISkinSimple skinParam) { private static List<PSystemFactory> getAllFactories(ISkinSimple skinParam) {
final List<PSystemFactory> factories = new ArrayList<PSystemFactory>(); final List<PSystemFactory> factories = new ArrayList<PSystemFactory>();
factories.add(new PSystemWelcomeFactory()); factories.add(new PSystemWelcomeFactory());
factories.add(new PSystemColorsFactory()); factories.add(new PSystemColorsFactory());
@ -173,8 +175,8 @@ public class PSystemBuilder {
factories.add(new PSystemDitaaFactory(DiagramType.DITAA)); factories.add(new PSystemDitaaFactory(DiagramType.DITAA));
factories.add(new PSystemDitaaFactory(DiagramType.UML)); factories.add(new PSystemDitaaFactory(DiagramType.UML));
if (License.getCurrent() == License.GPL || License.getCurrent() == License.GPLV2) { if (License.getCurrent() == License.GPL || License.getCurrent() == License.GPLV2) {
factories.add(new PSystemJcckitFactory(DiagramType.JCCKIT)); // factories.add(new PSystemJcckitFactory(DiagramType.JCCKIT));
factories.add(new PSystemJcckitFactory(DiagramType.UML)); // factories.add(new PSystemJcckitFactory(DiagramType.UML));
// factories.add(new PSystemLogoFactory()); // factories.add(new PSystemLogoFactory());
factories.add(new PSystemSudokuFactory()); factories.add(new PSystemSudokuFactory());
} }

View File

@ -104,6 +104,7 @@ public class Pipe {
ps.println(); ps.println();
} else { } else {
ps.println(result); ps.println(result);
error.goOk();
} }
} else { } else {
final OutputStream os = noStdErr ? new ByteArrayOutputStream() : ps; final OutputStream os = noStdErr ? new ByteArrayOutputStream() : ps;

View File

@ -36,6 +36,7 @@
package net.sourceforge.plantuml; package net.sourceforge.plantuml;
import java.awt.Font; import java.awt.Font;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
@ -62,6 +63,11 @@ import net.sourceforge.plantuml.graphic.IHtmlColorSet;
import net.sourceforge.plantuml.graphic.SkinParameter; import net.sourceforge.plantuml.graphic.SkinParameter;
import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.skin.ArrowDirection; import net.sourceforge.plantuml.skin.ArrowDirection;
import net.sourceforge.plantuml.skin.Padder;
import net.sourceforge.plantuml.style.FromSkinparamToStyle;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.style.StyleLoader;
import net.sourceforge.plantuml.svek.ConditionEndStyle; import net.sourceforge.plantuml.svek.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle; import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.svek.PackageStyle; import net.sourceforge.plantuml.svek.PackageStyle;
@ -77,6 +83,21 @@ import net.sourceforge.plantuml.ugraphic.sprite.SpriteImage;
public class SkinParam implements ISkinParam { public class SkinParam implements ISkinParam {
public static final String DEFAULT_STYLE = "plantuml.skin";
// public static final String DEFAULT_STYLE = "debug.skin";
static public boolean USE_STYLES() {
return USE_STYLE2.get();
}
private static ThreadLocal<Boolean> USE_STYLE2 = new ThreadLocal<Boolean>();
private SkinParam(UmlDiagramType type) {
USE_STYLE2.set(false);
this.type = type;
}
private static final String stereoPatternString = "\\<\\<(.*?)\\>\\>"; private static final String stereoPatternString = "\\<\\<(.*?)\\>\\>";
private static final Pattern2 stereoPattern = MyPattern.cmpile(stereoPatternString); private static final Pattern2 stereoPattern = MyPattern.cmpile(stereoPatternString);
@ -96,13 +117,19 @@ public class SkinParam implements ISkinParam {
public void setParam(String key, String value) { public void setParam(String key, String value) {
for (String key2 : cleanForKey(key)) { for (String key2 : cleanForKey(key)) {
params.put(key2, StringUtils.trin(value)); params.put(key2, StringUtils.trin(value));
if (key2.startsWith("usebetastyle")) {
USE_STYLE2.set("true".equalsIgnoreCase(value));
}
if (USE_STYLES()) {
final FromSkinparamToStyle convertor = new FromSkinparamToStyle(key2, value, getCurrentStyleBuilder());
final Style style = convertor.getStyle();
if (style != null) {
muteStyle(style);
}
}
} }
} }
private SkinParam(UmlDiagramType type) {
this.type = type;
}
public static SkinParam create(UmlDiagramType type) { public static SkinParam create(UmlDiagramType type) {
return new SkinParam(type); return new SkinParam(type);
} }
@ -1015,15 +1042,17 @@ public class SkinParam implements ISkinParam {
} }
public double getPadding() { public double getPadding() {
final String value = getValue("padding"); final String name = "padding";
if (value != null && value.matches("\\d+(\\.\\d+)?")) { return getAsDouble(name);
return Double.parseDouble(value);
}
return 0;
} }
public double getPadding(PaddingParam param) { public double getPadding(PaddingParam param) {
final String value = getValue(param.getSkinName()); final String name = param.getSkinName();
return getAsDouble(name);
}
private double getAsDouble(final String name) {
final String value = getValue(name);
if (value != null && value.matches("\\d+(\\.\\d+)?")) { if (value != null && value.matches("\\d+(\\.\\d+)?")) {
return Double.parseDouble(value); return Double.parseDouble(value);
} }
@ -1079,4 +1108,37 @@ public class SkinParam implements ISkinParam {
return useVizJs; return useVizJs;
} }
public Padder getSequenceDiagramPadder() {
final double padding = getAsDouble("SequenceMessagePadding");
final double margin = getAsDouble("SequenceMessageMargin");
final String borderColor = getValue("SequenceMessageBorderColor");
final String backgroundColor = getValue("SequenceMessageBackGroundColor");
if (padding == 0 && margin == 0 && borderColor == null && backgroundColor == null) {
return Padder.NONE;
}
final HtmlColor border = getIHtmlColorSet().getColorIfValid(borderColor);
final HtmlColor background = getIHtmlColorSet().getColorIfValid(backgroundColor);
final double roundCorner = getRoundCorner(CornerParam.DEFAULT, null);
return Padder.NONE.withMargin(margin).withPadding(padding).withBackgroundColor(background)
.withBorderColor(border).withRoundCorner(roundCorner);
}
private StyleBuilder styleBuilder;
public StyleBuilder getCurrentStyleBuilder() {
if (styleBuilder == null && SkinParam.USE_STYLES()) {
try {
this.styleBuilder = StyleLoader.mainStyle(this);
} catch (IOException e) {
e.printStackTrace();
}
}
return styleBuilder;
}
public void muteStyle(Style modifiedStyle) {
if (SkinParam.USE_STYLES()) {
styleBuilder = getCurrentStyleBuilder().muteStyle(modifiedStyle);
}
}
} }

View File

@ -46,6 +46,9 @@ import net.sourceforge.plantuml.graphic.IHtmlColorSet;
import net.sourceforge.plantuml.graphic.SkinParameter; import net.sourceforge.plantuml.graphic.SkinParameter;
import net.sourceforge.plantuml.graphic.color.Colors; import net.sourceforge.plantuml.graphic.color.Colors;
import net.sourceforge.plantuml.skin.ArrowDirection; import net.sourceforge.plantuml.skin.ArrowDirection;
import net.sourceforge.plantuml.skin.Padder;
import net.sourceforge.plantuml.style.Style;
import net.sourceforge.plantuml.style.StyleBuilder;
import net.sourceforge.plantuml.svek.ConditionEndStyle; import net.sourceforge.plantuml.svek.ConditionEndStyle;
import net.sourceforge.plantuml.svek.ConditionStyle; import net.sourceforge.plantuml.svek.ConditionStyle;
import net.sourceforge.plantuml.svek.PackageStyle; import net.sourceforge.plantuml.svek.PackageStyle;
@ -327,5 +330,16 @@ public class SkinParamDelegator implements ISkinParam {
return skinParam.getStereotypeAlignment(); return skinParam.getStereotypeAlignment();
} }
public Padder getSequenceDiagramPadder() {
return skinParam.getSequenceDiagramPadder();
}
public StyleBuilder getCurrentStyleBuilder() {
return skinParam.getCurrentStyleBuilder();
}
public void muteStyle(Style modifiedStyle) {
skinParam.muteStyle(modifiedStyle);
}
} }

View File

@ -435,7 +435,8 @@ public class StringUtils {
while (matcher.find()) { while (matcher.find()) {
final String num = matcher.group(1); final String num = matcher.group(1);
final int value = Integer.parseInt(num, 16); final int value = Integer.parseInt(num, 16);
matcher.appendReplacement(result, new String(Character.toChars(value))); final String replace = new String(Character.toChars(value));
matcher.appendReplacement(result, Matcher.quoteReplacement(replace));
} }
matcher.appendTail(result); matcher.appendTail(result);
return result.toString(); return result.toString();

View File

@ -39,6 +39,7 @@ import net.sourceforge.plantuml.Direction;
import net.sourceforge.plantuml.LineLocation; import net.sourceforge.plantuml.LineLocation;
import net.sourceforge.plantuml.StringUtils; import net.sourceforge.plantuml.StringUtils;
import net.sourceforge.plantuml.activitydiagram.ActivityDiagram; import net.sourceforge.plantuml.activitydiagram.ActivityDiagram;
import net.sourceforge.plantuml.classdiagram.command.CommandLinkClass;
import net.sourceforge.plantuml.command.CommandExecutionResult; import net.sourceforge.plantuml.command.CommandExecutionResult;
import net.sourceforge.plantuml.command.SingleLineCommand2; import net.sourceforge.plantuml.command.SingleLineCommand2;
import net.sourceforge.plantuml.command.regex.IRegex; import net.sourceforge.plantuml.command.regex.IRegex;
@ -53,6 +54,7 @@ import net.sourceforge.plantuml.cucadiagram.IEntity;
import net.sourceforge.plantuml.cucadiagram.Link; import net.sourceforge.plantuml.cucadiagram.Link;
import net.sourceforge.plantuml.cucadiagram.LinkDecor; import net.sourceforge.plantuml.cucadiagram.LinkDecor;
import net.sourceforge.plantuml.cucadiagram.LinkType; import net.sourceforge.plantuml.cucadiagram.LinkType;
import net.sourceforge.plantuml.descdiagram.command.CommandLinkElement;
public class CommandIf extends SingleLineCommand2<ActivityDiagram> { public class CommandIf extends SingleLineCommand2<ActivityDiagram> {
@ -69,7 +71,15 @@ public class CommandIf extends SingleLineCommand2<ActivityDiagram> {
new RegexLeaf("BAR", "(?:==+)[%s]*([\\p{L}0-9_.]+)[%s]*(?:==+)"), // new RegexLeaf("BAR", "(?:==+)[%s]*([\\p{L}0-9_.]+)[%s]*(?:==+)"), //
new RegexLeaf("QUOTED", "[%g]([^%g]+)[%g](?:[%s]+as[%s]+([\\p{L}0-9_.]+))?"))), // new RegexLeaf("QUOTED", "[%g]([^%g]+)[%g](?:[%s]+as[%s]+([\\p{L}0-9_.]+))?"))), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("ARROW", "([=-]+(?:(left|right|up|down|le?|ri?|up?|do?)(?=[-=.]))?[=-]*\\>)?"), // //new RegexOptional(new RegexLeaf("ARROW", "([=-]+(?:(left|right|up|down|le?|ri?|up?|do?)(?=[-=.]))?[=-]*\\>)")), //
new RegexOptional(new RegexConcat( //
new RegexLeaf("ARROW_BODY1", "([-.]+)"), //
new RegexLeaf("ARROW_STYLE1", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), //
new RegexLeaf("ARROW_DIRECTION", "(\\*|left|right|up|down|le?|ri?|up?|do?)?"), //
new RegexLeaf("ARROW_STYLE2", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), //
new RegexLeaf("ARROW_BODY2", "([-.]*)"), //
new RegexLeaf("\\>") //
)), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("BRACKET", "\\[([^\\]*]+[^\\]]*)\\]")), // new RegexOptional(new RegexLeaf("BRACKET", "\\[([^\\]*]+[^\\]]*)\\]")), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
@ -82,8 +92,8 @@ public class CommandIf extends SingleLineCommand2<ActivityDiagram> {
} }
@Override @Override
protected CommandExecutionResult executeArg(ActivityDiagram system, LineLocation location, RegexResult arg) { protected CommandExecutionResult executeArg(ActivityDiagram diagram, LineLocation location, RegexResult arg) {
final IEntity entity1 = CommandLinkActivity.getEntity(system, arg, true); final IEntity entity1 = CommandLinkActivity.getEntity(diagram, arg, true);
if (entity1 == null) { if (entity1 == null) {
return CommandExecutionResult.error("No if possible at this point"); return CommandExecutionResult.error("No if possible at this point");
} }
@ -97,20 +107,26 @@ public class CommandIf extends SingleLineCommand2<ActivityDiagram> {
ifCode = null; ifCode = null;
ifLabel = arg.get("IF2", 0); ifLabel = arg.get("IF2", 0);
} }
system.startIf(Code.of(ifCode)); diagram.startIf(Code.of(ifCode));
int lenght = 2; int lenght = 2;
if (arg.get("ARROW", 0) != null) { if (arg.get("ARROW_BODY1", 0) != null) {
final String arrow = StringUtils.manageArrowForCuca(arg.get("ARROW", 0)); // final String arrow = StringUtils.manageArrowForCuca(arg.get("ARROW", 0));
// lenght = arrow.length() - 1;
final String arrowBody1 = CommandLinkClass.notNull(arg.get("ARROW_BODY1", 0));
final String arrowBody2 = CommandLinkClass.notNull(arg.get("ARROW_BODY2", 0));
final String arrowDirection = CommandLinkClass.notNull(arg.get("ARROW_DIRECTION", 0));
final String arrow = StringUtils.manageArrowForCuca(arrowBody1 + arrowDirection + arrowBody2 + ">");
lenght = arrow.length() - 1; lenght = arrow.length() - 1;
} }
final IEntity branch = system.getCurrentContext().getBranch(); final IEntity branch = diagram.getCurrentContext().getBranch();
Link link = new Link(entity1, branch, new LinkType(LinkDecor.ARROW, LinkDecor.NONE), Link link = new Link(entity1, branch, new LinkType(LinkDecor.ARROW, LinkDecor.NONE),
Display.getWithNewlines(arg.get("BRACKET", 0)), lenght, null, ifLabel, system.getLabeldistance(), Display.getWithNewlines(arg.get("BRACKET", 0)), lenght, null, ifLabel, diagram.getLabeldistance(),
system.getLabelangle()); diagram.getLabelangle(), diagram.getSkinParam().getCurrentStyleBuilder());
if (arg.get("ARROW", 0) != null) { if (arg.get("ARROW", 0) != null) {
final Direction direction = StringUtils.getArrowDirection(arg.get("ARROW", 0)); final Direction direction = StringUtils.getArrowDirection(arg.get("ARROW", 0));
if (direction == Direction.LEFT || direction == Direction.UP) { if (direction == Direction.LEFT || direction == Direction.UP) {
@ -118,7 +134,8 @@ public class CommandIf extends SingleLineCommand2<ActivityDiagram> {
} }
} }
system.addLink(link); link.applyStyle(arg.getLazzy("ARROW_STYLE", 0));
diagram.addLink(link);
return CommandExecutionResult.ok(); return CommandExecutionResult.ok();
} }

View File

@ -91,7 +91,8 @@ public class CommandLinkActivity extends SingleLineCommand2<ActivityDiagram> {
new RegexLeaf("ARROW_STYLE1", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), // new RegexLeaf("ARROW_STYLE1", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), //
new RegexLeaf("ARROW_DIRECTION", "(\\*|left|right|up|down|le?|ri?|up?|do?)?"), // new RegexLeaf("ARROW_DIRECTION", "(\\*|left|right|up|down|le?|ri?|up?|do?)?"), //
new RegexLeaf("ARROW_STYLE2", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), // new RegexLeaf("ARROW_STYLE2", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), //
new RegexLeaf("ARROW_BODY2", "([-.]*)\\>"), // new RegexLeaf("ARROW_BODY2", "([-.]*)"), //
new RegexLeaf("\\>"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("BRACKET", "\\[([^\\]*]+[^\\]]*)\\]")), // new RegexOptional(new RegexLeaf("BRACKET", "\\[([^\\]*]+[^\\]]*)\\]")), //
@ -160,7 +161,7 @@ public class CommandLinkActivity extends SingleLineCommand2<ActivityDiagram> {
type = type.goDotted(); type = type.goDotted();
} }
Link link = new Link(entity1, entity2, type, linkLabel, lenght); Link link = new Link(entity1, entity2, type, linkLabel, lenght, diagram.getSkinParam().getCurrentStyleBuilder());
if (arrowDirection.contains("*")) { if (arrowDirection.contains("*")) {
link.setConstraint(false); link.setConstraint(false);
} }

View File

@ -100,12 +100,14 @@ public class CommandLinkLongActivity extends CommandMultilines2<ActivityDiagram>
new RegexLeaf("ARROW_STYLE1", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), // new RegexLeaf("ARROW_STYLE1", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), //
new RegexLeaf("ARROW_DIRECTION", "(\\*|left|right|up|down|le?|ri?|up?|do?)?"), // new RegexLeaf("ARROW_DIRECTION", "(\\*|left|right|up|down|le?|ri?|up?|do?)?"), //
new RegexLeaf("ARROW_STYLE2", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), // new RegexLeaf("ARROW_STYLE2", "(?:\\[(" + CommandLinkElement.LINE_STYLE + ")\\])?"), //
new RegexLeaf("ARROW_BODY2", "([-.]*)\\>"), // new RegexLeaf("ARROW_BODY2", "([-.]*)"), //
new RegexLeaf("\\>"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexOptional(new RegexLeaf("BRACKET", "\\[([^\\]*]+[^\\]]*)\\]")), // new RegexOptional(new RegexLeaf("BRACKET", "\\[([^\\]*]+[^\\]]*)\\]")), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("DESC", "[%g]([^%g]*?)"), // new RegexLeaf("[%g]"), //
new RegexLeaf("DESC", "([^%g]*?)"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
RegexLeaf.end()); RegexLeaf.end());
} }
@ -208,7 +210,7 @@ public class CommandLinkLongActivity extends CommandMultilines2<ActivityDiagram>
if (arrow.contains(".")) { if (arrow.contains(".")) {
type = type.goDotted(); type = type.goDotted();
} }
Link link = new Link(entity1, entity2, type, linkLabel, lenght); Link link = new Link(entity1, entity2, type, linkLabel, lenght, diagram.getSkinParam().getCurrentStyleBuilder());
final Direction direction = StringUtils.getArrowDirection(arrowBody1 + arrowDirection + arrowBody2 + ">"); final Direction direction = StringUtils.getArrowDirection(arrowBody1 + arrowDirection + arrowBody2 + ">");
if (direction == Direction.LEFT || direction == Direction.UP) { if (direction == Direction.LEFT || direction == Direction.UP) {
link = link.getInv(); link = link.getInv();

View File

@ -163,7 +163,7 @@ public class InstructionIf extends WithNote implements Instruction, InstructionC
final public boolean kill() { final public boolean kill() {
if (endifCalled) { if (endifCalled) {
for (Branch branch : thens) { for (Branch branch : thens) {
if (branch.getLast().kill() == false) { if (branch.getLast() != null && branch.getLast().kill() == false) {
return false; return false;
} }
if (elseBranch != null && elseBranch.getLast() != null && elseBranch.getLast().kill() == false) { if (elseBranch != null && elseBranch.getLast() != null && elseBranch.getLast().kill() == false) {

View File

@ -55,7 +55,9 @@ public class CommandCase extends SingleLineCommand2<ActivityDiagram3> {
return RegexConcat.build(CommandCase.class.getName(), RegexLeaf.start(), // return RegexConcat.build(CommandCase.class.getName(), RegexLeaf.start(), //
new RegexLeaf("case"), // new RegexLeaf("case"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TEST", "\\((.*?)\\)"), // new RegexLeaf("\\("), //
new RegexLeaf("TEST", "(.*?)"), //
new RegexLeaf("\\)"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
RegexLeaf.end()); RegexLeaf.end());
} }

View File

@ -58,7 +58,7 @@ public class CommandElse3 extends SingleLineCommand2<ActivityDiagram3> {
new RegexOptional( // new RegexOptional( //
new RegexConcat( // new RegexConcat( //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("WHEN", "(?:\\(([^()]*)\\))?") // new RegexLeaf("WHEN", "(?:\\((.*)\\))?") //
)), // )), //
new RegexLeaf(";?"), // new RegexLeaf(";?"), //
RegexLeaf.end()); RegexLeaf.end());

View File

@ -64,7 +64,9 @@ public class CommandElseIf2 extends SingleLineCommand2<ActivityDiagram3> {
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("if"), // new RegexLeaf("if"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TEST", "\\((.*?)\\)"), // new RegexLeaf("\\("), //
new RegexLeaf("TEST", "(.*?)"), //
new RegexLeaf("\\)"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexOptional( // new RegexOptional( //
new RegexConcat( // new RegexConcat( //

View File

@ -53,7 +53,7 @@ public class CommandEndPartition3 extends SingleLineCommand2<ActivityDiagram3> {
static IRegex getRegexConcat() { static IRegex getRegexConcat() {
return RegexConcat.build(CommandEndPartition3.class.getName(), // return RegexConcat.build(CommandEndPartition3.class.getName(), //
RegexLeaf.start(), // RegexLeaf.start(), //
new RegexLeaf("(\\})"), // new RegexLeaf("\\}"), //
RegexLeaf.end()); // RegexLeaf.end()); //
} }

View File

@ -63,7 +63,9 @@ public class CommandIf2 extends SingleLineCommand2<ActivityDiagram3> {
ColorParser.exp4(), // ColorParser.exp4(), //
new RegexLeaf("if"), // new RegexLeaf("if"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TEST", "\\((.*?)\\)"), // new RegexLeaf("\\("), //
new RegexLeaf("TEST", "(.*?)"), //
new RegexLeaf("\\)"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexOptional( // new RegexOptional( //
new RegexConcat( // new RegexConcat( //

View File

@ -58,11 +58,15 @@ public class CommandIf4 extends SingleLineCommand2<ActivityDiagram3> {
ColorParser.exp4(), // ColorParser.exp4(), //
new RegexLeaf("if"), // new RegexLeaf("if"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("TEST", "\\((.*?)\\)"), // new RegexLeaf("\\("), //
new RegexLeaf("TEST", "(.*?)"), //
new RegexLeaf("\\)"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("(is|equals?)"), // new RegexLeaf("(is|equals?)"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("WHEN", "\\((.+?)\\)"), // new RegexLeaf("\\("), //
new RegexLeaf("WHEN", "(.+?)"), //
new RegexLeaf("\\)"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //
new RegexLeaf("then"), // new RegexLeaf("then"), //
RegexLeaf.spaceZeroOrMore(), // RegexLeaf.spaceZeroOrMore(), //

Some files were not shown because too many files have changed in this diff Show More