Importing release version 322 from old repos

This commit is contained in:
Marcel Kronfeld
2007-12-11 16:38:11 +00:00
parent 8cecdb016d
commit 7ae15be788
668 changed files with 109288 additions and 0 deletions

View File

@@ -0,0 +1,726 @@
/**
* Filename: $RCSfile: DArea.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.Border;
import java.util.Vector;
// zum Drucken:
import java.awt.print.*;
import wsi.ra.print.PagePrinter;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
/**
* DArea is the crossing of the <code>JComponent</code>s and the
* <code>DComponent</code>s. It's the <code>DParent</code> which can be added to
* <code>JComponent</code>s
*/
public class DArea extends JComponent implements DParent, Printable
{
private static final boolean under_construction = false;
/**
* the default minimal rectangle which is shown
*/
public static final DRectangle DEFAULT_MIN_RECT = new DRectangle(-1, -1, 2, 2);
/**
* the container in which all DElements of the area are contained except
* the grid
*/
private DContainer container;
/**
* min_rectangle is set, when all elements are removed
* the intersection of visible_rect and max_rectangle is the currently visible
* rectangle
*/
protected DRectangle min_rect = DEFAULT_MIN_RECT,
visible_rect = DEFAULT_MIN_RECT;
protected Double min_x, min_y, max_x, max_y;
/**
* the grid of the area
*/
private DGrid grid;
private boolean auto_focus = false,
auto_grid = false,
grid_to_front = false;
/**
* maximal number of grid lines
*/
private int max_grid = 10;
/**
* the measures of the area
* it calculates the coordinates
*/
private DMeasures measures;
private DBorder dborder = new DBorder();
/**
* initializes the DArea with the initial capacity of 10 components
*/
public DArea(){
this( 10 );
}
/**
* initializes the DArea with the specialized initial capacity of components
* (@see java.util.Vector)
*
* @param the initial capacity
*/
public DArea( int initial_capacity ){
container = new DContainer();
container.setDParent( this );
grid = new DGrid( visible_rect, 1, 1 );
grid.setVisible( false );
grid.setDParent( this );
measures = new DMeasures( this );
}
/**
* returns the currently visible rectangle in DArea coordinates
*
* @return DRectangle the size and position of the visible area
*/
public DRectangle getDRectangle(){
DRectangle rect = (DRectangle)visible_rect.clone();
if( min_x != null ) rect.x = Math.max(rect.x, getMinX() );
if( min_y != null ) rect.y = Math.max(rect.y, getMinY() );
if( max_x != null ) rect.width = Math.min(rect.width, getMaxX() - getMinX());
if( max_y != null ) rect.height = Math.min(rect.height, getMaxY() - getMinY());
return rect;
}
/**
* switches the auto focus of this DArea on or off
*
* @param b on or off
*/
public void setAutoFocus( boolean b ){
boolean old = auto_focus;
auto_focus = b;
if( old != b ) repaint();
}
/**
* returns whether the DArea's auto focus is on or not
*
* @return <code>true</code> or <code>false</code>
*/
public boolean isOnAutoFocus(){ return auto_focus; }
/**
* sets the visible rectangle to this size
*
* @param x the x coordinate of the left border
* @param y the y coordinate of the bottom border
* @param width the width of the area
* @param height the height of the area
*/
public void setVisibleRectangle( double x, double y, double width, double height ){
//System.out.println("DArea.setVisibleRectangle(...)");
setVisibleRectangle( new DRectangle( x, y, width, height ) );
}
/**
* sets the visible rectangle
*
* @param rect the visible <code>DRectangle</code> in DArea coordinates
*/
public void setVisibleRectangle( DRectangle rect ){
if( under_construction )System.out.println("DArea.setVisibleRectangle(DRectangle)");
if( rect.isEmpty() ) throw
new IllegalArgumentException(
"You shopuld never try to set an empty rectangle\n"
+ "as the visible rectangle of an DArea" );
if( !rect.equals( visible_rect ) && rect.width > 0 && rect.height > 0 ){
auto_focus = false;
visible_rect = (DRectangle)rect.clone();
repaint();
}
}
/**
* sets the minimal rectangle
*
* @param x
* @param y
* @param width
* @param height
*/
public void setMinRectangle( double x, double y, double width, double height ){
setMinRectangle( new DRectangle( x, y, width, height ) );
}
/**
* sets the minimal rectangle
*
* @param rect the visible <code>DRectangle</code> in DArea coordinates
*/
public void setMinRectangle( DRectangle rect ){
if( rect.isEmpty() ) min_rect = DEFAULT_MIN_RECT;
else min_rect = (DRectangle)rect.clone();
}
/**
* method returns the minimal rectangle which is set as the visible when all
* elements are removed and the area is on auto focus
*
* @return the minmal rectangle
*/
public DRectangle getMinRectangle(){
return (DRectangle)min_rect.clone();
}
/**
* method sets the maximal rectangle whioch can be viewed with the
* DArea. This method can be used if the area is used with scale functions
* which are not invertible on all reals
*
* @param x the minmal x value
* @param y the minmal y value
* @param width of the maximal rectangle
* @param height of the maximal rectangle
*/
public void setMaxRectangle( double x, double y, double width, double height ){
setMaxRectangle( new DRectangle( x, y, width, height ) );
}
/**
* method sets the maximal rectangle whioch can be viewed with the
* DArea. This method can be used if the area is used with scale functions
* which are not invertible on all reals
*
* @param the rect maximal rectangle of the DArea
* @deprecated see setMinX, setMinY, setMaxX, setMaxY
*/
public void setMaxRectangle( DRectangle rect ){
if( !rect.contains( min_rect ) ) throw
new IllegalArgumentException("Maximal rectangle does not contain minmal rectangle");
setMinX( rect.x );
setMinY( rect.y );
setMaxX( rect.x + rect.width );
setMaxY( rect.y + rect.height );
}
/**
* method returns the maximal rectangle of the area
*
* @return the maximal rectangle
* @deprecated see getMaxX, getMaxY, getMinX, getMinY
*/
public DRectangle getMaxRectangle(){
return new DRectangle(min_x.doubleValue(),
min_y.doubleValue(),
max_x.doubleValue() - min_x.doubleValue(),
max_y.doubleValue() - min_y.doubleValue() );
}
/**
* method sets the minimal x-value which can be displayed by the DArea
* might be helpful, if scale functions are used which are not defined overall
*
* @param mix the minimal x-value
*/
public void setMinX( double mix ){
if( mix > min_rect.x ) throw
new IllegalArgumentException(
"Mimimal y-value axes intersects minmal rectangle.");
min_x = new Double( mix );
}
/**
* method resets the minimal x-value
*/
public void releaseMinX(){
min_x = null;
}
/**
* method returns the minmal x-value which can be displayed in the DArea
*
* @return the minmal x-value
*/
public double getMinX(){
if( min_x != null ) return min_x.doubleValue();
return 0;
}
/**
* method sets the minimal y-value which can be displayed by the DArea
* might be helpful, if scale functions are used which are not defined overall
*
* @param miy the minimal y-value
*/
public void setMinY( double miy ){
if( miy > min_rect.y ) throw
new IllegalArgumentException(
"Mimimal y-value axes intersects minmal rectangle.");
min_y = new Double( miy );
}
/**
* method resets the minimal y-value
*/
public void releaseMinY(){
min_y = null;
}
/**
* method returns the minmal y-value which can be displayed in the DArea
*
* @return the minmal y-value
*/
public double getMinY(){
if( min_y != null ) return min_y.doubleValue();
return 0;
}
/**
* method sets the maximal x-value which can be displayed by the DArea
* might be helpful, if scale functions are used which are not defined overall
*
* @param max the maximal x-value
*/
public void setMaxX( double max ){
if( max < min_rect.x + min_rect.width ) throw
new IllegalArgumentException(
"Maximal x-value axes intersects minmal rectangle.");
max_x = new Double( max );
}
/**
* method resets the maximal x-value
*/
public void releaseMaxX(){
max_x = null;
}
/**
* method returns the maxmal x-value which can be displayed in the DArea
*
* @return the maxmal x-value
*/
public double getMaxX(){
if( max_x != null ) return max_x.doubleValue();
return 0;
}
/**
* method sets the maximal y-values which can be displayed by the DArea
* might be helpful, if scale functions are used which are not defined overall
*
* @param may the maximal y-value
*/
public void setMaxY( double may ){
if( may < min_rect.y + min_rect.height ) throw
new IllegalArgumentException(
"Maximal y-value axes intersects minmal rectangle.");
max_y = new Double( may );
}
/**
* method resets the maximal y-value
*/
public void releaseMaxY(){
max_y = null;
}
/**
* method returns the maximal y-value which can be displayed in the DArea
*
* @return the maximal y-value
*/
public double getMaxY(){
if( max_y != null ) return max_y.doubleValue();
return 0;
}
/**
* paints the DArea by a Graphics object
*
* @param g the java.awt.Graphics object
*/
public void paint( Graphics g ){
if( under_construction ) System.out.println("DArea.paint(Graphics)");
if( auto_focus ) {
container.restore();
visible_rect = (DRectangle)container.getRectangle().clone();
}
if( visible_rect.isEmpty() ) visible_rect = (DRectangle)min_rect.clone();
super.paint( g );
measures.setGraphics( g );
if( grid.isVisible() && !grid_to_front ) paintGrid( measures );
container.paint( measures );
if( grid.isVisible() && grid_to_front ) paintGrid( measures );
}
/**
* repaints a part of the visible area
*
* @param r the rectangle to repaint
*/
public void repaint( DRectangle r ){
if( under_construction ) System.out.println("DArea.repaint(DRectangle)"+r);
if( r == null ) throw
new IllegalArgumentException("Cannot repaint a null DRectangle");
if( r.isAll() || auto_focus ) repaint();
else{
Point p1 = measures.getPoint( r.x, r.y ),
p2 = measures.getPoint( r.x + r.width, r.y + r.height);
if( p1 == null || p2 == null ) repaint();
else {
DBorder b = getDBorder();
repaint( p1.x - b.left,
p2.y - b.top,
p2.x - p1.x + 1 + b.left + b.right,
p1.y - p2.y + 1 + b.top + b.bottom );
}
}
}
/**
* adds a new component to the area
*
* @param e the new DElement
*/
public void addDElement( DElement e ){
container.addDElement( e );
}
/**
* removes a certain element from the area
*
* @param e the element to remove
*/
public boolean removeDElement( DElement e ){
return container.removeDElement( e );
}
/**
* removes all elements from the area
*/
public void removeAllDElements()
{
visible_rect = (DRectangle)min_rect.clone();
container.removeAllDElements();
}
/**
* returnes all DElements in the container
*
* @return the elements of the container
*/
public DElement[] getDElements(){
return container.getDElements();
}
/**
* method returns true, if the given element is contained in the container
*
* @param e the element
* @return if it is contained
*/
public boolean contains( DElement e ){
return container.contains( e );
}
/**
* sets the grid visible or not
*
* @param aFlag visible or not
*/
public void setGridVisible( boolean aFlag ){
if( under_construction ) System.out.println("DArea.setGridVisisble: "+aFlag);
grid.rectangle = getDRectangle();
grid.setVisible( aFlag );
}
/**
* returns if the grid is visible
* <code>true</code> if the grid is visible or <code>false</code> if not
*
* @return true or false
*/
public boolean isGridVisible(){
return grid.isVisible();
}
/**
* sets the grid to the front
* that means that the grid is painted as last element
* default value is <code>false</code>
*
* @param aFlag grid t front or not
*/
public void setGridToFront( boolean aFlag ){
boolean old = grid_to_front;
grid_to_front = aFlag;
if( old != aFlag && grid.isVisible() ) repaint();
}
/**
* sets the grid's horizontal and vertical distance
* that means that the grid's lines will have these distances
* in area coordinates
*
* @param hor_dist the horizontal distance
* @param ver_dist the vertical distance
*/
public void setGrid( double hor_dist, double ver_dist ){
grid = new DGrid( visible_rect, hor_dist, ver_dist );
grid.setDParent( this );
auto_grid = false;
repaint();
}
/**
* sets the auto grid on or off
* if it's on, the grid's distances (@see #setGrid(double, double))
* are automatically calculated
*
* @param b auto grid on or not
*/
public void setAutoGrid( boolean b ){
if( b ) {
grid.rectangle = getDRectangle();
grid.setVisible( true );
}
if( b == auto_grid ) return;
auto_grid = b;
repaint();
}
/**
* returns if the auto grid is switched on
*
* @return true if the grid is on, else false
*/
public boolean hasAutoGrid(){ return auto_grid; }
/**
* sets the color of the grid
*
* @param java.awt.Color
*/
public void setGridColor( Color color ){
grid.setColor( color );
}
/**
* sets the maximal number of grid lines
* default value is 10
*
* @param no maximal number of grid lines
*/
public void setMaxGrid( int no ){
if( no < 1 ) return;
int old = max_grid;
max_grid = no;
if( old != no ) repaint();
}
/**
* prints the area and it's content
* @see java.awt.print.Printable and
* @see java.awt.print.PrintJob
*
* @param g the Graphics object
* @param pf the @see java.awt.print.PageFormat
* @param pi the page index
*
* @return int @see java.awt.print.Printable
*/
public int print( Graphics g, PageFormat pf, int pi ){
if( under_construction ) System.out.println("DArea.print(...)");
if( pi > 0 ) return Printable.NO_SUCH_PAGE;
Border sb = getBorder();
if( !(sb instanceof ScaledBorder) ) sb = null;
else ( (ScaledBorder)sb ).show_outer_border = false;
PagePrinter printer = new PagePrinter( this, g, pf );
int ret = printer.print();
if( sb != null ) ( (ScaledBorder)sb ).show_outer_border = true;
return ret;
}
/**
* sets a new scale function to the x-axis
* That means that not the standard linear scale is shown but the image
* of the linear scale under the given function
*
* @param x_s the scale function for the x-axis
*/
public void setXScale( DFunction x_s ){
if( x_s == null && measures.x_scale == null ) return;
measures.x_scale = x_s;
repaint();
}
/**
* sets a new scale function to the y-axis
* That means that not the standard linear scale is shown but the image
* of the linear scale under the given function
*
* @param y_s the scale function for the y-axis
*/
public void setYScale( DFunction y_s ){
if( y_s == null && measures.y_scale == null ) return;
measures.y_scale = y_s;
repaint();
}
/**
* returns the measures of the DArea
* The DMeasures object calculates the different coodinates and contains a
* Graphics object to paint the DElements of the area
*
* @return the measures of the DArea
*/
public DMeasures getDMeasures(){
return measures;
}
/**
* method 'adds' a certain border around the contained rectangle
* that means that it takes the old border
* and takes the maxima of the old and the new values
*
* @param clip the java.awt.Insets object of the new clip
*/
public void addDBorder( DBorder b ){
dborder.insert(b);
}
/**
* method returns the current border around the rectangle
*
* @return the border
*/
public DBorder getDBorder(){
return dborder;
}
public void restoreBorder(){
dborder = container.getDBorder();
if( under_construction ) System.out.println("DArea.restoreBorder -> "+dborder);
}
/**
* method paints the grid
* how the method paints the grid depends on whether the area is wrapped in a
* <code>ScaledBorder</code> or not and on the auto_grid option
*/
private void paintGrid( DMeasures m ){
if( under_construction ) System.out.println("DArea.paintGrid(DMeasures)");
grid.rectangle = getDRectangle();
if( auto_grid ){
Border b = getBorder();
if( b instanceof ScaledBorder ){
ScaledBorder sb = (ScaledBorder)b;
paintGrid( sb, m );
return;
}
else{
grid.hor_dist = ScaledBorder.aBitBigger( grid.rectangle.width / max_grid );
grid.ver_dist = ScaledBorder.aBitBigger( grid.rectangle.height / max_grid );
}
}
grid.paint( m );
}
/**
* paints the grid when auto_grid is selected and the area is surrounded
* by an instance of ScaledBorder
*
* @param sb the ScaledBorder around the area
* @param m the measures of the area
*/
private void paintGrid(ScaledBorder sb, DMeasures m){
if( under_construction ) System.out.println("DArea.paintGrid(ScaledBorder, DMeasures)");
Dimension d = getSize();
FontMetrics fm = m.getGraphics().getFontMetrics();
grid.hor_dist = sb.getSrcdX(fm, d);
grid.ver_dist = sb.getSrcdY(fm, d);
if( m.x_scale == null && m.y_scale == null ) grid.paint( m );
else{// selber malen
Graphics g = m.g;
g.setColor( grid.getColor() );
DRectangle rect = getDRectangle(),
src_rect = m.getSourceOf( rect );
int x = (int)(src_rect.x / grid.hor_dist),
y = (int)(src_rect.y / grid.ver_dist);
if( x * grid.hor_dist < src_rect.x ) x++;
if( y * grid.ver_dist < src_rect.y ) y++;
DPoint min = new DPoint( rect.x, rect.y ),
max = new DPoint( min.x + rect.width, min.y + rect.height );
double pos;
for( ; (pos = x * grid.hor_dist) < src_rect.x + src_rect.width; x++ ){
if( m.x_scale != null ) pos = m.x_scale.getImageOf( pos );
Point p1 = m.getPoint( pos, min.y ),
p2 = m.getPoint( pos, max.y );
g.drawLine( p1.x, p1.y, p2.x, p2.y );
}
for( ; (pos = y * grid.ver_dist) < src_rect.y + src_rect.height; y++ ){
if( m.y_scale != null ) pos = m.y_scale.getImageOf( pos );
Point p1 = m.getPoint( min.x, pos ),
p2 = m.getPoint( max.x, pos );
g.drawLine( p1.x, p1.y, p2.x, p2.y );
}
}
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,205 @@
package wsi.ra.chart2d;
/**
* Title:
* Description:
* Copyright: Copyright (c) 2001
* Company:
* @author
* @version 1.0
*/
/**
* This class stores an array of double values.
* It can be used as data stack for an DPointSet object.
* For that use, it is important to tell the DPoitSet object, when the data has
* been modified.
*/
public class DArray implements DIntDoubleMap{
private int initial_capacity, size;
private double capacity_multiplier = 2, max, min;
private double[] value;
/**
* Constructor for an DArray object with default values for the initial
* capacity (5) and the capacity multiplier (2).
*/
public DArray(){
this(5, 2);
}
/**
* Constructor for an DArray object with default value for the capacity
* multiplier (2).
*
* @param initial_capacity the initial capacity of the array
*/
public DArray(int initial_capacity){
this(initial_capacity, 2);
}
/**
* Constructor for an DArray object
*
* @param initial_capacity the initial capacity of the array
* @param capacity_multiplier the capacity multiplier when the array overflows
*/
public DArray(int initial_capacity, double capacity_multiplier){
if( initial_capacity < 1 ) throw
new IllegalArgumentException("The initial capacity has to be at least 1");
if( capacity_multiplier <= 1 ) throw
new IllegalArgumentException("The capacity multiplier has to be bigger than 1");
this.initial_capacity = initial_capacity;
value = new double[initial_capacity];
this.capacity_multiplier = capacity_multiplier;
}
/**
* method sets the image value to the given source value
*
* @param source the source value
* @param image the image value
*/
public boolean setImage(int source, double image){
if(source<0 || source>=size) throw
new ArrayIndexOutOfBoundsException(source);
boolean min_max_changed = false, restore = false;
if( image < min ){ min = image; min_max_changed = true; }
else if( image > max ){ max = image; min_max_changed = true; }
if( value[source] == min || value[source] == max ) restore = true;
value[source] = image;
if( restore ) min_max_changed = restore() || min_max_changed;
return min_max_changed;
}
/**
* method returns the image value of the given source value
*
* @param source the source value
* @return the image value
*/
// public double getImage(int source){
// if(source<0 || source>=size) throw
// new ArrayIndexOutOfBoundsException(source);
// return value[source];
// }
public double getImage(int source){
if(source<0) new ArrayIndexOutOfBoundsException(source);
if(source>=size && size > 1) return value[size-1];
return value[source];
}
/**
* the given image value becomes the image of (highest source value + 1)
*
* @param image the new image value
* @return <code>true<\code> when the minmal or the maximal image value
* has been changed by this method call, else it returns
* <code>false</code> @see #getMinImageValue(), #getMaxImageValue()
*/
public boolean addImage(double image){
if( size >= value.length ){
int new_length = (int)(value.length * capacity_multiplier);
if( !(new_length > value.length) ) new_length++;
double[] new_val = new double[new_length];
System.arraycopy(value,0,new_val,0,value.length);
value = new_val;
}
boolean min_max_changed = false;
if( size == 0 ){ min = image; max = image; min_max_changed = true;}
else
if( image > max ) { max = image; min_max_changed = true; }
else if( image < min ) { min = image; min_max_changed = true; }
value[size++] = image;
return min_max_changed;
}
/**
* method returns the number of (source,image)-pairs stored in the array
*
* @return the size of the source value set
*/
public int getSize(){
return size;
}
/**
* this method checks if the minimal and the maximal image value has changed
*
* @return <code>true</code> if one of them changed
*/
public boolean restore(){
if( size == 0 ) return false;
double old_min = min, old_max = max;
min = value[0];
max = value[0];
for( int i=1; i<size; i++ )
if( value[i] < min ) min = value[i];
else if( value[i] > max ) max = value[i];
return (old_min != min) || (old_max != max);
}
/**
* throws all information away
*/
public void reset(){
size = 0;
value = new double[initial_capacity];
}
/**
* returns the minmal image value
*
* @return the minmal image value
*/
public double getMinImageValue(){
if( size == 0 ) throw
new IllegalArgumentException("DArray is empty. No minimal value exists");
return min;
}
/**
* returns the maxmal image value
*
* @return the maxmal image value
*/
public double getMaxImageValue(){
if( size == 0 ) throw
new IllegalArgumentException("DArray is empty. No maximal value exists");
return max;
}
/**
* method checks if the given object is equal to this DArray object.
* It looks for differences in the stored image values
*
* @param o the object to compare with
* @return <code>true</code> when the object is an DArray object, containing
* the same values
*/
public boolean equals(Object o){
if( !(o instanceof DArray) ) return false;
DArray comp = (DArray)o;
if( comp.size != size ) return false;
if( comp.max != max ) return false;
if( comp.min != min ) return false;
for( int i=0; i<size; i++ )
if( comp.value[i] != value[i] ) return false;
return true;
}
public String toString(){
String text = "wsi.ra.chart2d.DArray[size:"+size;
if( size < 11 )
for( int i=0; i<size; i++ ) text += ", "+value[i];
text += "]";
return text;
}
public double[] toArray(double[] v){
if( v == null || v.length < size ) v = new double[size];
System.arraycopy(value,0,v,0,size);
return v;
}
}

View File

@@ -0,0 +1,45 @@
/**
* Filename: $RCSfile: DBorder.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
import java.awt.Insets;
public class DBorder extends Insets{
public DBorder(){
this( 0, 0, 0, 0 );
}
public DBorder(int top, int left, int bottom, int right ){
super( top, left, bottom, right );
}
public boolean insert( DBorder b ){
boolean changed = false;
if( b.top > top ){ top = b.top; changed = true; }
if( b.bottom > bottom ){ bottom = b.bottom; changed = true; }
if( b.left > left ){ left = b.left; changed = true; }
if( b.right > right ){ right = b.right; changed = true; }
return changed;
}
public boolean equals( Object o ){
if( o instanceof DBorder )
return super.equals( o );
return false;
}
public String toString(){
return "wsi.ra.chart2d.DBorder[top="+top+",left="+left
+",bottom="+bottom+",right="+right+"]";
}
}

View File

@@ -0,0 +1,159 @@
/**
* Filename: $RCSfile: DComponent.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.Color ;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
/**
* <code>DComponent</code> is the mother of all objects which can be displayed
* by a <code>DArea</code> object, even when it would be also enough to
* implement the <code>DElement</code> interface to an class
*
* DComponent is abstract because the paint method has to be overridden
*/
public abstract class DComponent implements DElement
{
/**
* the color of the component
*/
protected Color color;
/**
* the rectangle in which the component lies
*/
protected DRectangle rectangle;
/**
* the parent of the component which is responsible for repainting
*/
protected DParent parent;
private boolean visible = true;
/**
* this border respresents the additional space around the clip of the
* graphics context, which is calculated by the union of all DRectangles of
* the components. For example it is used by DPointIcons or DLabels.
*/
private DBorder border = new DBorder();
/**
* this constructor is necessary to avoid infinite loops in constructing
* DRectangles
*/
DComponent(boolean is_rect){}
public DComponent(){ rectangle = DRectangle.getEmpty(); }
/**
* returns the rectangle in which the object lies
*/
public DRectangle getRectangle(){
return (DRectangle)rectangle.clone();
}
/**
* method sets a certain border around the contained rectangle
*
* @param b the new DBorder
*/
public void setDBorder( DBorder b ){
if( parent != null ) {
if( border.insert(b) ) { parent.addDBorder( b ); repaint(); }
else { border = b; parent.restoreBorder(); }
}
else border = b;
}
/**
* method returns the current border around the rectangle
*
* @return the DBorder of the DComponent
*/
public DBorder getDBorder(){
return border;
}
/**
* sets the parent of the component, which should take care of painting the
* component to the right time
*/
public void setDParent( DParent parent ){
if( this.parent != null && this.parent != parent ){
this.parent.removeDElement( this );
this.parent.repaint( getRectangle() );
}
this.parent = parent;
}
/**
* returns the parent of the component
*/
public DParent getDParent(){ return parent; }
/**
* invoces the parent to repaint the rectangle in which the component lies
*/
public void repaint(){
//System.out.println("DComponent.repaint()");
if( parent != null ) parent.repaint( getRectangle() );
}
/**
* sets the color of the component
*/
public void setColor( Color color ){
if( this.color == null || !this.color.equals( color ) ) {
this.color = color;
repaint();
}
}
/**
* returns the color of the component
*/
public Color getColor(){ return color; }
/**
* sets the component visible or not
*/
public void setVisible( boolean aFlag ){
boolean changed = ( aFlag != visible );
visible = aFlag;
if( changed ) repaint();
}
/**
* returns if the component should be visible when the parent shows the right
* area
*/
public boolean isVisible(){ return visible; }
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,223 @@
/**
* Filename: $RCSfile: DContainer.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.util.Vector ;
import java.awt.Color ;
import java.awt.Graphics;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
public class DContainer extends DComponent implements DParent{
/**
* the elements of the container and their keys ( Strings )
*/
protected Vector elements, keys;
public DContainer(){ this(10); }
public DContainer(int initial_capacity){
super();
elements = new Vector(initial_capacity);
keys = new Vector(initial_capacity);
}
public void repaint( DRectangle r ){
DParent parent = getDParent();
if( parent != null ) parent.repaint( r );
}
/**
* method adds a new DElement to the container
* if the container already contains this element, the method simply returns
* the method checks whether the DElement is an ancestor of the container
* itself. In that case it throws an IllegalArgumentException.
*
* @param e the new DElement to add
*/
public void addDElement( DElement e ){
addDElement( null, e );
}
/**
* method adds a new DElement to the container by a certain key name
* if the container already contains this element, the method simply returns
* the method checks whether the DElement is an ancestor of the container
* itself. In that case it throws an IllegalArgumentException.
*
* @param key the name of the DElement in the container
* @param e the new DElement to add
*/
public void addDElement( String key, DElement e ){
if( elements.contains( e ) ) return;
if( e instanceof DParent ){
DParent he = (DParent)e, me = (DParent)this;
if( he == me ) throw new
IllegalArgumentException("Adding DParent to itself");
me = getDParent();
while( me != null ){
if( he == me )throw new
IllegalArgumentException("Adding DContainer's parent to itself");
if( me instanceof DElement )
me = ((DElement)me).getDParent();
else me = null;
}
}
elements.add( e );
addDBorder( e.getDBorder() );
keys.add( key );
e.setDParent( this );
DRectangle r = e.getRectangle();
rectangle.insert( r );
if( e.isVisible() ) repaint( r );
}
/**
* method removes a certain DElement from the container an returns whether it
* contained it before
*
* @param e the DElement to remove
* @return if this was possible
*/
public boolean removeDElement( DElement e ){
int index = elements.indexOf( e );
if( index > -1 ){
elements.remove( index );
keys.remove( index );
repaint( e.getRectangle() );
restore();
return true;
}
return false;
}
/**
* method removes all DElements from the container
*/
public void removeAllDElements()
{
elements.removeAllElements();
keys.removeAllElements();
rectangle = DRectangle.getEmpty();
repaint();
}
/**
* method returns all DElements of the container
*
* @return the elements of the container
*/
public DElement[] getDElements(){
DElement[] es = new DElement[ elements.size() ];
elements.toArray(es);
return es;
}
/**
* method returns the first DElement of the contaioner belonging to
* the given key
*
* @param key the name of the DElement in the container
* @return the element when it could be found or null else
*/
public DElement getDElement( String key ){
int index = -1;
for( int i=0; index == -1 && i < keys.size(); i++ )
if( ((String)keys.get(i)).equals( key ) ) index = i;
return (index<keys.size())? (DElement)elements.get(index):(DElement)null;
}
// implementing DComponent:
/**
* method calls all currently visible DElements of the container to paint
* themselves by the given DMeasures object
*
* @param m the DMeasures object
*/
public void paint( DMeasures m ){
DElement e;
for( int i=0; i<elements.size(); i++ ){
e = (DElement)elements.elementAt(i);
if( e.isVisible() && !m.getDRectangle().getIntersection( e.getRectangle() ).isEmpty()){
m.g.setColor( DEFAULT_COLOR );
e.paint( m );
}
}
}
/**
* method returns true, if the given element is contained in the container
*
* @param e the element
* @return if it is contained
*/
public boolean contains( DElement e ){
return elements.contains( e );
}
/**
* method sets the given color to all contained DElements of the container
*
* @param c the new Color of the elements
*/
public void setColor(Color c){
for( int i=0; i<elements.size(); i++ )
((DElement)elements.get(i)).setColor(c);
super.setColor(c);
}
/**
* method adds the given border to the current border of the container
* that means, that if necessary it will enlarge it and tells it to its
* parent
*
* @param b the border to add
*/
public void addDBorder(DBorder b){
if( getDBorder().insert(b) && parent != null ) parent.addDBorder(b);
}
public void restoreBorder(){
DBorder b = new DBorder();
for( int i=0; i<elements.size(); i++ )
b.insert( ((DElement)elements.get(i)).getDBorder() );
setDBorder( b );
}
/**
* restores the container, that means that the rectangle is completely new calculated
* this method is used after removing one of the elements
*/
boolean restore(){
DRectangle old = (DRectangle)rectangle.clone();
rectangle = DRectangle.getEmpty();
setDBorder( new DBorder() );
for( int i=0; i<elements.size(); i++ ){
DElement elt = (DElement)elements.elementAt(i);
rectangle.insert(elt.getRectangle());
addDBorder( elt.getDBorder() );
}
return !old.equals( rectangle );
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,51 @@
/**
* Filename: $RCSfile: DElement.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.Color ;
/*==========================================================================*
* INTERFACE DECLARATION
*==========================================================================*/
/**
* some useful methods for objects which should be paintable in a scaled area
*/
public interface DElement
{
Color DEFAULT_COLOR = Color.black;
DRectangle getRectangle();
void setDParent( DParent parent );
DParent getDParent();
void paint( DMeasures m );
void repaint();
void setVisible( boolean aFlag );
boolean isVisible();
void setColor( Color color );
Color getColor();
void setDBorder( DBorder b );
DBorder getDBorder();
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,63 @@
/**
* Filename: $RCSfile: DFunction.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.Point ;
import java.awt.Color ;
import java.awt.Graphics ;
/*==========================================================================*
* ABSTRACT CLASS DECLARATION
*==========================================================================*/
public abstract class DFunction extends DComponent
{
public DFunction(){
rectangle = DRectangle.getAll();
}
public abstract boolean isDefinedAt( double source );
public abstract boolean isInvertibleAt( double image );
public abstract double getSourceOf( double image ) throws IllegalArgumentException;
public abstract double getImageOf( double source ) throws IllegalArgumentException;
public void paint( DMeasures m ){
Graphics g = m.getGraphics();
if( color != null ) g.setColor( color );
DRectangle rect = m.getDRectangle(),
src_rect = m.getSourceOf( rect );
Point sw = m.getPoint( rect.x, rect.y ),
ne = m.getPoint( rect.x + rect.width, rect.y + rect.height );
int int_w = ne.x - sw.x;
Point last = null, next;
for( int i = 0; i < int_w; i++ ){
double x_val = src_rect.x + i / (double)int_w * src_rect.width ;
if( m.x_scale != null ) x_val = m.x_scale.getImageOf( x_val );
if( isDefinedAt( x_val ) ){
next = m.getPoint( x_val, getImageOf( x_val ) );
if( last != null ) g.drawLine( last.x, last.y, next.x, next.y );
last = next;
}
else last = null;
}
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,115 @@
/**
* Filename: $RCSfile: DGrid.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.Color ;
import java.awt.Graphics ;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
/**
* this class paints a grid with certain line distances on a DParent
*/
public class DGrid extends DComponent
{
/**
* the distances between the lines
*/
double hor_dist, ver_dist;
private Color DEFAULT_COLOR = Color.lightGray;
/**
* constructor with the size and position of the grid and the line distances
*
* @param rectangle the rectangle around the grid
* @param hor_dist the horizontal distance between the lines in D-coordinates,
* not in pixel coordinates!
* @param ver_dist vertical distance between the lines in D-coordinates,
* not in pixel coordinates!
*/
public DGrid( DRectangle rectangle, double hor_dist, double ver_dist ){
this.rectangle = rectangle;
this.hor_dist = hor_dist;
this.ver_dist = ver_dist;
color = DEFAULT_COLOR;
}
/**
* constructor with the size and position of the grid and the line distances
*
* @param rectangle the rectangle around the grid
* @param hor_dist the horizontal distance between the lines in D-coordinates,
* not in pixel coordinates!
* @param ver_dist the vertical distance between the lines in D-coordinates,
* not in pixel coordinates!
* @param color the color of the grid
* ( can also be set by setColor( java.awt.Color ) )
*/
public DGrid( DRectangle rectangle, double hor_dist, double ver_dist, Color color ){
this.rectangle = rectangle;
this.hor_dist = hor_dist;
this.ver_dist = ver_dist;
this.color = color;
}
/**
* paints the grid...
*
* @param m the <code>DMeasures</code> object to paint the grid
*/
public void paint( DMeasures m ){
Graphics g = m.getGraphics();
if( color != null ) g.setColor( color );
double minX, minY, pos;
DPoint p1, p2;
DLine l;
minX = (int)( rectangle.x / hor_dist );
if( minX * hor_dist <= rectangle.x ) minX++;
minX *= hor_dist;
minY = (int)( rectangle.y / ver_dist );
if( minY * ver_dist <= rectangle.y ) minY++;
minY *= ver_dist;
p1 = new DPoint( 0, rectangle.y );
p2 = new DPoint( 0, rectangle.y + rectangle.height );
for( pos = minX; pos<=rectangle.x + rectangle.width; pos += hor_dist ){
p1.x = p2.x = pos;
l = new DLine( p1, p2, color );
l.paint( m );
}
p1.x = rectangle.x;
p2.x = p1.x + rectangle.width;
for( pos = minY; pos<=rectangle.y + rectangle.height; pos += ver_dist ){
p1.y = p2.y = pos;
l = new DLine( p1, p2, color );
l.paint( m );
}
}
public String toString(){
return "chart2d.DGrid[ hor: "+hor_dist+", ver: "+ver_dist+" ]";
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,88 @@
package wsi.ra.chart2d;
/**
* Title:
* Description:
* Copyright: Copyright (c) 2001
* Company:
* @author
* @version 1.0
*/
/**
* This interface is used by DPointSet to store values as images of integer
* values which can be displayed in a DArea. All modifications of the values can
* only be shown by the DArea, when the DPointSet.repaint method is
* called. This should be done in the implementation of the #setImage and
* #addImage method. To get the functionality of the DArea, the methods
* #getMaxImageValue and #getMinImageValue are necessary.
*/
public interface DIntDoubleMap {
/**
* implementation should change the map in that way, that from now the
* image of index is v
*
* @param source the preimage of the image
* @param image the new image of the source value
* @return <code>true<\code> when the minmal or the maximal image value
* has been changed by this method call, else it returns
* <code>false</code> @see #getMinImageValue(), #getMaxImageValue()
*/
boolean setImage(int source, double image);
/**
* implementation should return the image of source
*
* @param source the preimage
* @return the image value
*/
double getImage(int source);
/**
* the image of the highest source value + 1 should be the given image value
*
* @param image the new image value
* @return <code>true<\code> when the minmal or the maximal image value
* has been changed by this method call, else it returns
* <code>false</code> @see #getMinImageValue(), #getMaxImageValue()
*/
boolean addImage(double image);
/**
* implementation should return the number of source values
*
* @return the number of source values
*/
int getSize();
/**
* returns the maximal image value
*
* @return the maximal image value
* @throw an IllegalArgumentException when it has no image values
*/
double getMaxImageValue();
/**
* returns the minimal image value
*
* @return the minmal image value
* @throw an IllegalArgumentException when it has no image values
*/
double getMinImageValue();
/**
* checks the minimal and the maximal image values and returns <code>true</code>
* when at least one of them has changed
*
* @return <code>true</code> when either the maximal image value or the
* minmal image value has changed
*/
boolean restore();
/**
* method removes all image values and sets the size to 0
*/
void reset();
}

View File

@@ -0,0 +1,70 @@
/**
* Filename: $RCSfile: DLine.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.* ;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
public class DLine extends DComponent
{
DPoint start, end;
public DLine( double x1, double y1, double x2, double y2 ){
this( new DPoint( x1, y1 ), new DPoint( x2, y2 ) );
}
public DLine( DPoint start, DPoint end ){
this.start = start;
this.end = end;
}
public DLine( double x1, double y1, double x2, double y2, Color color ){
this( new DPoint( x1, y1 ), new DPoint( x2, y2 ), color );
}
public DLine( DPoint start, DPoint end, Color color ){
this.start = start;
this.end = end;
this.color = color;
}
public DRectangle getRectangle(){
double x = start.x, y = start.y, width = end.x - x, height = end.y - y;
if( width < 0 ) { x += width; width *= -1; }
if( height < 0 ) { y += height; height *= -1; }
return new DRectangle( x, y, width, height );
}
public void paint( DMeasures m ){
//System.out.println("DLine.paint(Measures): "+this);
Graphics g = m.getGraphics();
if( color != null ) g.setColor( color );
Point p1 = m.getPoint( start ),
p2 = m.getPoint( end ) ;
g.drawLine( p1.x, p1.y, p2.x, p2.y );
}
public String toString(){
return "DLine[("+start.x+","+start.y+") --> ("+end.x+","+end.y+", color: "+color+"]";
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,274 @@
/**
* Filename: $RCSfile: DMeasures.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.Point ;
import java.awt.Graphics ;
import java.awt.Dimension ;
import java.awt.Insets ;
import java.awt.Component ;
//import javax.swing.JComponent ;
import java.io.Serializable;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
public class DMeasures implements Serializable
{
/**
*
*/
private static final long serialVersionUID = 243092480517044848L;
private boolean under_construction = false;
// when in use for a DArea:
Graphics g;
// when in use for a ScaledBorder:
ScaledBorder sb;
// for both:
DFunction x_scale, y_scale;
Component comp;
Insets insets;
/**
* package private constructor for the DMeasures object
* the object can be obtained by calling the method getDMeasures of an DArea
* object
*
* @param area the DArea object
*/
DMeasures( DArea area ){
comp = area;
}
DMeasures( ScaledBorder sb ){
this.sb = sb;
}
/**
* method returns the pixel-point which belongs to the DPoint in the
* D-coordinates
* it says where to paint a certain DPoint
* returns <code>null</code> if the double coordinates do not belong to the
* image of the scale functions
*
* @param p the DPoint
* @return the coresponding pixel Point
*/
public Point getPoint( DPoint p ){
//System.out.println("DMeasures.getPoint :"+org );
return getPoint( p.x, p.y );
}
/**
* method returns the pixel-point which belongs to the given D-coordinates
* it says where to paint a certain DPoint
* returns <code>null</code> if the double coordinates do not belong to the
* image of the scale functions
*
* @param x the double x D-coordinate
* @param y the double y D-coordinate
* @return the coresponding pixel Point
*/
public Point getPoint( double x, double y ){
DRectangle rect = getSourceOf( getDRectangle() );
try{
if( x_scale != null ) x = x_scale.getSourceOf( x );
if( y_scale != null ) y = y_scale.getSourceOf( y );
}
catch( IllegalArgumentException e ){ return null; }
Point dp = new Point();
Dimension dim = getInner();
Insets insets = getInsets();
dp.x = (int)( dim.width * (x - rect.x)/(double)rect.width ) + insets.left;
dp.y = (int)( dim.height * (1 - (y - rect.y)/(double)rect.height)) + insets.top;
return dp;
}
/**
* method returns the point in D-coordinates which corresponds to the
* given pixel-point
* returns <code>null</code> if the given coordinates can not be calculated to
* the double coordinates, when they represent a point outside of the definition
* area of the scale functions
*
* @param p Point in pixel coordinates
* @return the coresponding DPoint
*/
public DPoint getDPoint( Point p ){
return getDPoint( p.x, p.y );
}
/**
* method returns the point in D-coordinates which corresponds to the
* given pixel-coordinates
* returns <code>null</code> if the given coordinates can not be calculated to
* the double coordinates, when they represent a point outside of the definition
* area of the scale functions
*
* @param x x-pixel coordinate
* @param y y-pixel coordinate
* @return the coresponding DPoint
*/
public DPoint getDPoint( int x, int y ){
DRectangle rect = getSourceOf( getDRectangle() );
Dimension dim = getInner();
Insets insets = getInsets();
x -= insets.left;
y -= insets.top;
double dx, dy;
dx = rect.x + rect.width * x/(double)dim.width;
dy = rect.y + rect.height * (1 - y/(double)dim.height );
try{
if( x_scale != null ) dx = x_scale.getImageOf( dx );
if( y_scale != null ) dy = y_scale.getImageOf( dy );
}
catch( IllegalArgumentException nde ){ return null; }
return new DPoint( dx, dy );
}
/**
* returns the visible rectangle in D-coordinates of the shown component
*
* return the visible rectangle
*/
public DRectangle getDRectangle(){
if( under_construction ) System.out.println("DMeasures.getDRectangle");
if( sb != null ) return getImageOf( sb.src_rect );
return ((DArea)comp).getDRectangle();
}
/**
* returns the current Graphics object, which might be used by components to
* paint themselves
* the method sets the clipping area of the Graphics object to the currently
* visible rectangle
*
* @return the Graphics object ( or null if no object was set )
*/
public Graphics getGraphics(){
if( under_construction ) System.out.println("DMeasures.getGraphics");
if( g != null ){
Dimension d = comp.getSize();
Insets insets = getInsets();
g.setClip( insets.left + 1, // dann sieht man noch was von der linken Achse
insets.top,
d.width - insets.left - insets.right,
d.height - insets.top - insets.bottom);
}
return g;
}
/**
* used by DArea to set a new Graphics object
*/
void setGraphics( Graphics g ){
if( under_construction ) System.out.println("DMeasures.setGraphics");
this.g = g;
}
/**
* used by ScaledBorder to update the DMeasures object
*
* @param c the parent component the border
*/
void update( Component c, Insets insets ){
this.comp = c;
this.insets = insets;
x_scale = sb.x_scale;
y_scale = sb.y_scale;
}
private Dimension getInner(){
Dimension d = comp.getSize();
Insets insets = getInsets();
d.width -= insets.left + insets.right;
d.height -= insets.top + insets.bottom;
return d;
}
/**
* method returns the source rectangle of the given rectangle
* they differ if there are scale functions selected which are not the identity
* if the given rectangle does not belong to the image area of the scale
* functions, the method returns <code>null</code>
*
* @param rect the image rectangle
* @return the source of it
*/
DRectangle getSourceOf( DRectangle rect ){
if( under_construction ) System.out.println("DMeasures.getSourceOf: "+rect);
if( !getDRectangle().contains( rect ) ) throw
new IllegalArgumentException("The rectangle lies not in the currently painted rectangle");
if( x_scale == null && y_scale == null ) return rect;
if( rect.isEmpty() ) return (DRectangle)rect.clone();
DPoint p1 = new DPoint( rect.x, rect.y ),
p2 = new DPoint( rect.x + rect.width, rect.y + rect.height );
try{
if( x_scale != null ){
p1.x = x_scale.getSourceOf( p1.x );
p2.x = x_scale.getSourceOf( p2.x );
}
if( y_scale != null ){
p1.y = y_scale.getSourceOf( p1.y );
p2.y = y_scale.getSourceOf( p2.y );
}
}
catch( IllegalArgumentException nde ){ return null; }
return new DRectangle( p1.x, p1.y, p2.x - p1.x, p2.y - p1.y );
}
/**
* method returns the image rectangle of the given rectangle
* they differ if there are scale functions selected which are not the identity
* if the given rectangle does not belong to the defintion area of the scale
* functions, the method returns <code>null</code>
*
* @param rect the source rectangle
* @return the source of it
*/
DRectangle getImageOf( DRectangle rect ){
if( under_construction ) System.out.println("DMeasures.getImageOf: "+rect);
if( x_scale == null && y_scale == null ) return rect;
if( rect.isEmpty() ) return (DRectangle)rect.clone();
DPoint p1 = new DPoint( rect.x, rect.y ),
p2 = new DPoint( rect.x + rect.width, rect.y + rect.height );
try{
if( x_scale != null ){
p1.x = x_scale.getImageOf( p1.x );
p2.x = x_scale.getImageOf( p2.x );
}
if( y_scale != null ){
p1.y = y_scale.getImageOf( p1.y );
p2.y = y_scale.getImageOf( p2.y );
}
}
catch( IllegalArgumentException nde ){ return null; }
return new DRectangle( p1.x, p1.y, p2.x - p1.x, p2.y - p1.y );
}
private Insets getInsets(){
if( sb != null ) return insets;
return ((DArea)comp).getInsets();
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,34 @@
/**
* Filename: $RCSfile: DParent.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:41 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
import java.awt.Graphics;
/*==========================================================================*
* INTERFACE DECLARATION
*==========================================================================*/
public interface DParent
{
void addDElement( DElement e );
boolean removeDElement( DElement e );
void repaint( DRectangle r );
DElement[] getDElements();
boolean contains( DElement e );
void addDBorder( DBorder b );
void restoreBorder();
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,99 @@
/**
* Filename: $RCSfile: DPoint.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:42 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.* ;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
public class DPoint extends DComponent
{
public double x, y;
public String label;
protected DPointIcon icon = null;
public DPoint( ){
}
public void initpoint( double x, double y ){
this.x = x;
this.y = y;
rectangle = new DRectangle( x, y, 0, 0 );
}
public DPoint( double x, double y ){
this.x = x;
this.y = y;
rectangle = new DRectangle( x, y, 0, 0 );
}
public void paint( DMeasures m ){
Graphics g = m.getGraphics();
if( color != null ) g.setColor( color );
Point dp = m.getPoint( this );
if( label != null ){
FontMetrics fm = g.getFontMetrics();
g.drawString( label,
dp.x - fm.stringWidth( label ) / 2,
dp.y + fm.getAscent()
);
}
if( icon == null )
g.drawRect( dp.x, dp.y, 1, 1 );
else{
g.translate( dp.x, dp.y );
icon.paint( g );
g.translate( -dp.x, -dp.y );
}
}
/**
* method sets an icon for a better displaying of the point
*
* @param icon the DPointIcon
*/
public void setIcon( DPointIcon icon ){
this.icon = icon;
if( icon == null ) setDBorder(new DBorder(1,1,1,1));
else setDBorder( icon.getDBorder() );
}
/**
* method returns the current icon of the point
*
* @return the DPointIcon
*/
public DPointIcon getIcon(){
return icon;
}
public Object clone(){
DPoint copy = new DPoint( x, y );
copy.color = color;
return copy;
}
public String toString(){
String text = "DPoint[";
if( label != null ) text += label+", ";
text += "x: "+x+", y: "+y+", color: "+color+"]";
return text;
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,38 @@
package wsi.ra.chart2d;
/**
* Filename: $RCSfile: DPointIcon.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version:
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
import java.awt.Graphics;
/**
* A simple interface which can be used to paint certain icons at DPoints
* ( @see chart2d.DPoint.setIcon or chart2d.DPointSet.setIcon ).
* Different points may be easier recognized in a complex graph.
* The container does not guarantee that the whole icon is visible in the graph
* because the icon does not concern the DRectangle of the DElement.
*/
public interface DPointIcon {
/**
* this method has to be overridden to paint the icon. The point itself lies
* at coordinates (0, 0)
*/
void paint( Graphics g );
/**
* the border which is necessary to be paint around the DPoint that the whole
* icon is visible
*
* @return the border
*/
DBorder getDBorder();
}

View File

@@ -0,0 +1,350 @@
/**
* Filename: $RCSfile: DPointSet.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:42 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.* ;
import wsi.ra.tool.IntegerArrayList;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
public class DPointSet extends DComponent
{
protected DPointIcon icon = null;
/*-------------------------------------------------------------------------*
* private member variables
*-------------------------------------------------------------------------*/
protected DIntDoubleMap x, y;
protected boolean connected;
protected Stroke stroke = new BasicStroke();
protected JumpManager jumper = new JumpManager();
/*-------------------------------------------------------------------------*
* constructor
*-------------------------------------------------------------------------*/
public DPointSet(){
this(10, 2);
}
public DPointSet( int initial_capacity ){
this(initial_capacity, 2);
}
public DPointSet( int initial_capacity, int length_multiplier ){
this( new DArray(initial_capacity, length_multiplier),
new DArray(initial_capacity, length_multiplier) );
}
public DPointSet(DIntDoubleMap x_values, DIntDoubleMap y_values){
if( x_values.getSize() != y_values.getSize() ) throw
new IllegalArgumentException(
"The number of x-values has to be the same than the number of y-values"
);
x = x_values;
y = y_values;
restore();
setDBorder(new DBorder(1,1,1,1));
}
/*-------------------------------------------------------------------------*
* public methods
*-------------------------------------------------------------------------*/
public void paint( DMeasures m ){
Graphics2D g = (Graphics2D)m.getGraphics();
g.setStroke(stroke);
if( color != null ) g.setColor( color );
int size = getSize();
if( connected && size > 1 ){
jumper.restore();
while( jumper.hasMoreIntervals() ){
int[] interval = jumper.nextInterval();
Point p1 = null, p2;
for( int i=interval[0]; i<interval[1]; i++ ){
p2 = m.getPoint( x.getImage(i), y.getImage(i) );
if( p1 != null)
g.drawLine( p1.x, p1.y, p2.x, p2.y );
if( icon != null ){
g.setStroke( new BasicStroke() );
g.translate(p2.x, p2.y);
icon.paint(g);
g.translate(-p2.x, -p2.y);
g.setStroke( stroke );
}
p1 = p2;
}
}
}
else{
Point p;
for( int i=0; i<size; i++ ){
p = m.getPoint( x.getImage(i), y.getImage(i) );
if( icon == null ){
g.drawLine(p.x - 1, p.y - 1, p.x + 1, p.y + 1);
g.drawLine(p.x + 1, p.y - 1, p.x - 1, p.y + 1);
}
else{
g.setStroke( new BasicStroke() );
g.translate(p.x, p.y);
icon.paint(g);
g.translate(-p.x, -p.y);
}
}
}
g.setStroke( new BasicStroke() );
}
public void addDPoint( DPoint p ){
x.addImage(p.x);
y.addImage(p.y);
rectangle.insert(p);
repaint();
}
public void addDPoint( double x, double y ){
addDPoint(new DPoint(x, y));
}
/**
* method causes the DPointSet to interupt the connected painting at the
* current position
*/
public void jump(){
jumper.addJump();
}
/**
* method removes all jump positions
* if the DPointSet is connected, all points will be painted connected to
* their following point
*/
public void removeJumps(){
jumper.reset();
}
/**
* method returns the DPoint at the given index
*
* @param index the index of the DPoint
* @return the DPoint at the given index
*/
public DPoint getDPoint( int index ){
if( index >= x.getSize() ) {
System.out.println("getDPoint() index"+index);
System.out.println("x.getSize() "+x.getSize());
throw new ArrayIndexOutOfBoundsException(index);
}
DPoint p = new DPoint( x.getImage( index ), y.getImage( index ) );
p.setIcon( icon );
p.setColor( color );
return p;
}
/**
* method puts the given DPoint at the given position in the set
*
* @param index the index of the point
* @param p the point to insert
*/
public void setDPoint( int index, DPoint p ){
if( index >= x.getSize() ) throw new ArrayIndexOutOfBoundsException(index);
rectangle.insert(p);
x.setImage(index,p.x);
y.setImage(index,p.y);
restore();
repaint();
}
/**
* method sets an icon for a better displaying of the point set
*
* @param icon the DPointIcon
*/
public void setIcon( DPointIcon icon ){
this.icon = icon;
if( icon == null ) setDBorder(new DBorder(1,1,1,1));
else setDBorder( icon.getDBorder() );
}
/**
* method returns the current icon of the point set
*
* @return the DPointIcon
*/
public DPointIcon getIcon(){
return icon;
}
/**
* method sets the stroke of the line
* if the points were not connected, they now will be connected
*
* @param s the new stroke
*/
public void setStroke( Stroke s ){
if( s == null ) s = new BasicStroke();
stroke = s;
repaint();
}
/**
* method returns the current stroke of the line
*
* @return the stroke
*/
public Stroke getStroke(){
return stroke;
}
public void setConnected( boolean aFlag ){
boolean changed = !( aFlag == connected );
connected = aFlag;
if( changed ) repaint();
}
public void removeAllPoints(){
if( x.getSize() == 0 ) return;
x.reset();
y.reset();
jumper.reset();
repaint();
rectangle = DRectangle.getEmpty();
}
public String toString(){
String text = "wsi.ra.chart2d.DPointSet[size:"+getSize();
for( int i=0; i<x.getSize(); i++ )
text += ",("+x.getImage(i)+","+y.getImage(i)+")";
text += "]";
return text;
}
/**
* method returns the index to the nearest <code>DPoint</code> in this <code>DPointSet</code>.
*
* @return the index to the nearest <code>DPoint</code>. -1 if no nearest <code>DPoint</code> was found.
*/
public int getNearestDPointIndex(DPoint point){
double minValue = Double.MAX_VALUE;
int minIndex = -1;
for( int i=0; i<x.getSize(); i++ ){
double dx = point.x - x.getImage(i);
double dy = point.y - y.getImage(i);
double dummy = dx*dx + dy*dy;
if (dummy < minValue){
minValue = dummy;
minIndex = i;
}
}
return minIndex;
}
/**
* method returns the nearest <code>DPoint</code> in this <code>DPointSet</code>.
*
* @return the nearest <code>DPoint</code>
*/
public DPoint getNearestDPoint(DPoint point){
int minIndex = getNearestDPointIndex(point);
if(minIndex == -1) return null;
else return new DPoint(x.getImage(minIndex), y.getImage(minIndex));
}
// public int getSize(){
// int size = x.getSize();
// if( size != y.getSize() ) throw
// new ArrayStoreException(
// "The number of x-values is not equal to the number of y-values.\n"
// +"The size of the DPointSet isn<73>t clear."
// );
// return size;
// }
/**
*
*/
public int getSize(){ // testhu
int size = x.getSize();
if( size <= y.getSize() )
return size;
return x.getSize();
}
protected void restore(){
if( getSize() == 0){
rectangle = DRectangle.getEmpty();
return;
}
double min_x = x.getMinImageValue(),
max_x = x.getMaxImageValue(),
min_y = y.getMinImageValue(),
max_y = y.getMaxImageValue();
rectangle = new DRectangle(min_x, min_y, max_x - min_x, max_y - min_y );
}
/**
* this class stores the jump positions (see this.jump)
*/
class JumpManager{
protected IntegerArrayList jumps = new IntegerArrayList();
protected int index = -1;
public void addJump(){
jumps.add(getSize());
}
public int[] nextInterval(){
int no_jumps = jumps.size();
if( index >= no_jumps ) throw
new ArrayIndexOutOfBoundsException("No more intervals in JumpManager");
int[] inter = new int[2];
if( index == -1 ) inter[0] = 0;
else inter[0] = jumps.get(index);
index++;
if( index < no_jumps ) inter[1] = jumps.get(index);
else inter[1] = getSize();
return inter;
}
public boolean hasMoreIntervals(){
return index < jumps.size();
}
public void restore(){
index = -1;
}
public void reset(){
index = -1;
jumps.clear();
}
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,207 @@
/**
* Filename: $RCSfile: DRectangle.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:42 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.* ;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
public class DRectangle extends DComponent
{
public double x, y, width, height;
public static final int PART = 0, ALL = 1, EMPTY = 2;
protected int status;
protected Color fillColor;
private DRectangle( int status ){
super(true);
this.status = status;
}
public DRectangle( double x, double y, double width, double height ){
super(true);
this.x = x;
this.y = y;
if( width < 0 ) throw
new IllegalArgumentException("Width of a DRectangle has to be >= 0");
this.width = width;
if( height < 0 ) throw
new IllegalArgumentException("Height of a DRectangle has to be >= 0");
this.height = height;
status = PART;
}
public DRectangle getRectangle(){ return this; }
public void paint( DMeasures m ){
if( isEmpty() ) return;
Graphics g = m.getGraphics();
Color old_color = g.getColor();
DRectangle rect = m.getDRectangle();
rect = rect.getIntersection( this );
Point p1 = m.getPoint( rect.x, rect.y ),
p2 = m.getPoint( rect.x + rect.width, rect.y + rect.height );
if( fillColor != null ){
g.setColor( fillColor );
g.fillRect( p1.x, p2.y, p2.x - p1.x, p1.y - p2.y );
}
if( !isAll() ){
if( color != null ) g.setColor( color );
else g.setColor( DEFAULT_COLOR );
g.drawRect( p1.x, p2.y, p2.x - p1.x, p1.y - p2.y );
}
g.setColor( old_color );
}
public boolean contains( DPoint p ){
if( status == ALL ) return true;
if( status == EMPTY ) return false;
if( p.x < x ) return false;
if( p.y < y ) return false;
if( p.x > x + width ) return false;
if( p.y > y + height ) return false;
return true;
}
public boolean contains( DRectangle rect ){
if( status == ALL || rect.isEmpty() ) return true;
if( status == EMPTY || rect.isAll() ) return false;
if( !contains( new DPoint( rect.x, rect.y ) ) ) return false;
if( !contains( new DPoint( rect.x + rect.width, rect.y + rect.height ) ) ) return false;
return true;
}
public DRectangle getIntersection( DRectangle r ){
if( status == ALL ) return (DRectangle)r.clone();
if( status == EMPTY ) return DRectangle.getEmpty();
if( r.status == ALL ) return (DRectangle)clone();
if( r.status == EMPTY ) return DRectangle.getEmpty();
DRectangle s = (DRectangle)this.clone();
if( s.x < r.x ){
s.x = r.x;
s.width -= r.x - s.x;
}
if( s.y < r.y ){
s.y = r.y;
s.height -= r.y - s.y;
}
if( s.x + s.width > r.x + r.width )
s.width = r.x + r.width - s.x;
if( s.y + s.height > r.y + r.height )
s.height = r.y + r.height - s.y;
if( s.width < 0 || s.height < 0 ) return DRectangle.getEmpty();
else return s;
}
/**
* method resizes the rectangle to insert p
*
* @param the dPoint p to insert
* @return true when the size of the rectangle changed
*/
public boolean insert( DPoint p ){
if( p.x == Double.NaN || p.y == Double.NaN ) return false;
if( isAll() ) return false;
if( contains( p ) ) return false;
if( isEmpty() ){
x = p.x; y = p.y; width = height = 0;
status = PART;
return true;
}
if( p.x < x ) {
width += x - p.x;
x = p.x;
}
else if( p.x > x + width ) width = p.x - x;
if( p.y < y ) {
height += y - p.y;
y = p.y;
}
else if( p.y > y + height ) height = p.y - y;
return true;
}
/**
* method inserts the given rectangle to this instance of it
* and returns true when the size changed
*
* @param rect the rectangle to inserts
* @return true if the size changed
*/
public boolean insert( DRectangle rect ){
if( isAll() || rect.isEmpty() ) return false;
if( rect.isAll() ){ status = ALL; return true; }
if( isEmpty() ){
x = rect.x; y = rect.y; width = rect.width; height = rect.height;
status = PART;
return true;
}
boolean changed = false;
changed = insert( new DPoint( rect.x, rect.y ) );
changed = insert( new DPoint( rect.x + rect.width, rect.y + rect.height ) )? true : changed;
return changed;
}
public Object clone(){
DRectangle copy = new DRectangle( x, y, width, height );
copy.status = status;
if( color != null ) copy.color = new Color( color.getRGB() );
return copy;
}
public String toString(){
String text = "DRectangle[ ";
switch( status ){
case ALL : text += "all"; break;
case EMPTY : text += "empty"; break;
case PART : text += x+", "+y+", "+width+", "+height;
}
text += " ]";
return text;
}
public boolean equals( DRectangle r ){
if( r.status != status ) return false;
if( r.x != x ) return false;
if( r.y != y ) return false;
if( r.width != width ) return false;
if( r.height != height ) return false;
return true;
}
public void setFillColor( Color fill_color ){
if( fillColor == null || !fillColor.equals( fill_color ) ){
fillColor = fill_color;
repaint();
}
}
public Color getFillColor(){
return fillColor;
}
public static DRectangle getAll(){ return new DRectangle( ALL ); }
public boolean isAll(){ return status == ALL; }
public static DRectangle getEmpty(){ return new DRectangle( EMPTY ); }
public boolean isEmpty(){ return status == EMPTY; }
}
/****************************************************************************
* END OF FILE
****************************************************************************/

View File

@@ -0,0 +1,493 @@
/**
* Filename: $RCSfile: ScaledBorder.java,v $
* Purpose:
* Language: Java
* Compiler: JDK 1.3
* Authors: Fabian Hennecke
* Version: $Revision: 1.1.1.1 $
* $Date: 2003/07/03 14:59:42 $
* $Author: ulmerh $
* Copyright (c) Dept. Computer Architecture, University of Tuebingen, Germany
*/
package wsi.ra.chart2d;
/*==========================================================================*
* IMPORTS
*==========================================================================*/
import java.awt.* ;
import javax.swing.BorderFactory;
import javax.swing.border.* ;
import java.awt.geom.AffineTransform ;
import java.text.NumberFormat;
import java.text.DecimalFormat;
/*==========================================================================*
* CLASS DECLARATION
*==========================================================================*/
/**
* ScaledBorder puts an border around Components
* ( especially around DrawingAreas ) with scaled and labeled axes
*/
public class ScaledBorder implements Border
{
private boolean under_construction = false;
/**
* length of the distance markers on the axes in pixels
*/
int marker_length = 2;
/**
* length in pixels of the arrows at the ends of the axes
*/
int arrow_length = 10;
/**
* a flag if the arrows should be visible
*/
public boolean show_arrows = true;
/**
* distance between the x-values in digits
*/
int x_value2value = 2;
/**
* distance between y-label and y-values in digit width
*/
int y_label2values = 1;
/**
* distance between y-values and y-axis markers in parts of the digit width
*/
int y_values2marker = 2;
/**
* distance between values and arrows in pixels
*/
int x_values2arrow = 10,
y_values2arrow = 10;
/**
* distance between arrows and outer border
*/
int axis2border = 4;
/**
* distance between labels and the border in pixels
*/
public int x_label2border = 6,
y_label2border = 6;
/**
* the size of the source rectangle
* that means before the values are mdified by scale functions
*/
DRectangle src_rect;
/**
* the minimal increment of the scales
*/
public double minimal_increment;
/**
* the displayed labels
*/
public String x_label, y_label;
/**
* foreground and background colors
*/
public Color foreground, background;
/**
* the border which is shown around the scaled border
*/
Border outer_border;
/**
* flag if the outer border should be displayed
*/
boolean show_outer_border = true;
/**
* scale functions if, for example, an logarithmic function is needed instead
* of a linear.
*/
public DFunction x_scale, y_scale;
/**
* formatters of the x- and y-axis numbers
* @see java.text.NumberFormat
*/
public NumberFormat format_x = new DecimalFormat(),
format_y = new DecimalFormat();
private double src_dX = -1, src_dY = -1;
private boolean do_refresh,
auto_scale_x = true,
auto_scale_y = true;
private Insets old_insets;
private DMeasures m;
/**
* constructor creates a default ScaledBorder inside of a lowered BevelBorder
*/
public ScaledBorder(){
this(
BorderFactory.createBevelBorder(
BevelBorder.LOWERED,
Color.white,
Color.lightGray,
Color.black,
Color.lightGray
)
);
}
/**
* constructor creates a new <code>ScaledBorder<code/>
* surrounded by the specified <code>Border<code/>
*/
public ScaledBorder( Border outer ){
outer_border = outer;
m = new DMeasures( this );
}
/**
* method tells the border to calculate the differences between displayed
* x-values by itself
*/
public void setAutoScaleX(){ auto_scale_x = true; }
/**
* method tells the border to calculate the differences between displayed
* y-values by itself
*/
public void setAutoScaleY(){ auto_scale_y = true; }
/**
* method sets the differences between source x-values of the displayed values
* @see setAutoScaleX().
* If scale functions are used there might be a difference between the shown values
* and the source values
*/
public void setSrcdX(double dX){
auto_scale_x = false;
src_dX = dX;
}
/**
* method sets the differences between source y-values of the displayed values
* @see setAutoScaleY().
* If scale functions are used there might be a difference between the shown values
* and the source values
*/
public void setSrcdY(double dY){
auto_scale_y = false;
src_dY = dY;
}
public void paintBorder(Component c, Graphics g, int x, int y, int width, int height){
if( under_construction ) System.out.println("ScaledBorder.paintBorder()");
if( foreground == null ) foreground = c.getForeground();
if( background == null ) background = c.getBackground();
Color old_color = g.getColor();
g.setColor( background );
g.fillRect( x, y, width, height );
g.setColor( old_color );
Insets outer_insets = new Insets( 0, 0, 0, 0);// insets of the outer border
if( show_outer_border ) {
outer_border.paintBorder( c, g, x, y, width, height );
outer_insets = outer_border.getBorderInsets( c );
}
do_refresh = true;
Insets inner_insets = getBorderInsets(c);
Dimension d = c.getSize(),
cd = new Dimension( d.width - inner_insets.left - inner_insets.right,
d.height - inner_insets.top - inner_insets.bottom );
FontMetrics fm = g.getFontMetrics();
int fontAsc = fm.getAscent();
do_refresh = false;
m.update(c, inner_insets);
// axes
g.setColor( foreground );
g.drawLine( inner_insets.left, inner_insets.top,
inner_insets.left, inner_insets.top + cd.height );
g.drawLine( inner_insets.left, inner_insets.top + cd.height,
inner_insets.left + cd.width, inner_insets.top + cd.height );
if( show_arrows ){
g.drawLine( inner_insets.left, inner_insets.top,
inner_insets.left, inner_insets.top - y_values2arrow );
g.drawLine( inner_insets.left - marker_length, inner_insets.top - y_values2arrow,
inner_insets.left, inner_insets.top - y_values2arrow - arrow_length );
g.drawLine( inner_insets.left + marker_length, inner_insets.top - y_values2arrow,
inner_insets.left, inner_insets.top - y_values2arrow - arrow_length);
g.drawLine( inner_insets.left - marker_length, inner_insets.top - y_values2arrow,
inner_insets.left + marker_length, inner_insets.top - y_values2arrow );
g.drawLine( inner_insets.left + cd.width , inner_insets.top + cd.height,
inner_insets.left + cd.width + x_values2arrow, inner_insets.top + cd.height );
g.drawLine( inner_insets.left + cd.width + x_values2arrow,
inner_insets.top + cd.height - marker_length,
inner_insets.left + cd.width + x_values2arrow + arrow_length,
inner_insets.top + cd.height );
g.drawLine( inner_insets.left + cd.width + x_values2arrow,
inner_insets.top + cd.height + marker_length,
inner_insets.left + cd.width + x_values2arrow + arrow_length,
inner_insets.top + cd.height );
g.drawLine( inner_insets.left + cd.width + x_values2arrow,
inner_insets.top + cd.height - marker_length,
inner_insets.left + cd.width + x_values2arrow,
inner_insets.top + cd.height + marker_length );
}
if( y_label != null ) {
Dimension yld = new Dimension(fm.getAscent()+fm.getDescent(), fm.stringWidth(y_label));
AffineTransform T = new AffineTransform(0, -1, 1, 0, 0, 0);
Font old = g.getFont(), f = old.deriveFont( T );
g.setFont( f );
g.drawString( y_label, y_label2border + fm.getAscent(), inner_insets.top + ( cd.height + yld.height )/ 2 );
g.setFont( old );
}
if( x_label != null )
g.drawString(
x_label, inner_insets.left + ( cd.width - fm.stringWidth( x_label ) ) / 2,
d.height - outer_insets.bottom - x_label2border - fm.getDescent() );
if( src_rect.x == 0 && src_rect.y == 0 ){
int v2m = fm.stringWidth("0") / y_values2marker;
g.drawString( "0", inner_insets.left - fm.stringWidth( "0" ) - v2m - marker_length,
inner_insets.top + cd.height + fontAsc );
g.drawLine( inner_insets.left, inner_insets.top + cd.height + fm.getAscent(),
inner_insets.left, inner_insets.top + cd.height);
g.drawLine( inner_insets.left, inner_insets.top + cd.height,
inner_insets.left - fm.stringWidth( "0" ) - v2m - marker_length,
inner_insets.top + cd.height );
}
drawYValues( g, inner_insets, cd );
drawXValues( g, inner_insets, cd );
g.setColor( old_color );
}
private void drawYValues( Graphics g, Insets insets, Dimension cd ){
if( under_construction ) System.out.println("ScaledBorder.drawYValues()");
FontMetrics fm = g.getFontMetrics();
int n, fontAsc = fm.getAscent(), v2m = fm.stringWidth("0") / y_values2marker;
n = (int)( src_rect.y / src_dY );
if( n * src_dY < src_rect.y || ( src_rect.x == 0 && src_rect.y == 0 ) ) n++;
double v, minx = src_rect.x;
if( x_scale != null ) minx = x_scale.getImageOf( minx );
for(; (v = n * src_dY) <= src_rect.y + src_rect.height; n++ ){
if( y_scale != null ) v = y_scale.getImageOf( v );
String text = format_y.format(v);
try{ v = format_y.parse(text).doubleValue(); }
catch( java.text.ParseException ex ){ }
Point p = m.getPoint( minx, v );
if( p != null ){
g.drawString( text,
insets.left - fm.stringWidth( text ) - v2m - marker_length,
p.y + fontAsc / 2 );
g.drawLine( insets.left - marker_length, p.y, insets.left, p.y );
}
}
}
public double getSrcdY( FontMetrics fm, Dimension cd ){
if( under_construction ) System.out.println("ScaledBorder.getSrcdY()");
if( (!do_refresh && src_dY != -1) || !auto_scale_y ) return src_dY;
int max = cd.height / fm.getHeight();
double minsrc_dY = 2 * src_rect.height / (double)max; // die 2 einfach mal so eingesetzt <--------------------------
src_dY = aBitBigger( minsrc_dY );
if( src_dY < minimal_increment ) src_dY = minimal_increment;
return src_dY;
}
private void drawXValues( Graphics g, Insets insets, Dimension cd ){
if( under_construction ) System.out.println("ScaledBorder.drawXValues()");
FontMetrics fm = g.getFontMetrics();
double mx = cd.width / src_rect.width;
int n, labelX,
xnull = insets.left + (int)( - src_rect.x * mx );
n = (int)( src_rect.x / src_dX );
if( n * src_dX < src_rect.x || ( src_rect.x == 0 && src_rect.y == 0 ) ) n++;
int fontAsc = fm.getAscent(), xLineY = insets.top + cd.height;
labelX = xnull + (int)(n * src_dX * mx);
while( n * src_dX <= src_rect.x + src_rect.width ){
double v = n * src_dX;
if( x_scale != null ) v = x_scale.getImageOf(v);
String text = format_x.format(v);
try{ v = format_x.parse(text).doubleValue(); }
catch( java.text.ParseException ex ){ }
int strW = fm.stringWidth( text );
g.drawString( text, labelX - strW / 2, xLineY + fontAsc );
g.drawLine( labelX, xLineY, labelX, xLineY + marker_length );
n++;
labelX = xnull + (int)( n * src_dX * mx);
}
}
public double getSrcdX( FontMetrics fm, Dimension cd ){
if( under_construction ) System.out.println("ScaledBorder.getSrcdX()");
if( (!do_refresh && src_dX != - 1) || !auto_scale_x ) return src_dX;
int digit_width = fm.stringWidth("0"),
max = cd.width / ( digit_width * ( x_value2value + 1 ) );
src_dX = src_rect.width / (double)max;
int n, labelX, olsrc_dX;
boolean ok = false;
while( !ok ){
src_dX = aBitBigger( src_dX );
n = (int)( src_rect.x / src_dX );
if( n * src_dX < src_rect.x ) n++;
olsrc_dX = 0;
boolean suits = true, first = true;
while( suits && n * src_dX <= src_rect.x + src_rect.width ){
double v = n * src_dX;
if( x_scale != null ) v = x_scale.getImageOf( v );
String text = format_x.format(v);
int strW = fm.stringWidth( text );
labelX = (int)((( n * src_dX - src_rect.x ) / src_rect.width ) * cd.width ) - strW / 2;
if( !first && labelX <= olsrc_dX + digit_width * x_value2value ) suits = false;
else{
olsrc_dX = labelX + strW;
n++;
}
first = false;
}
if( !suits ) ok = false;
else ok = true;
}
if( src_dX < minimal_increment ) src_dX = minimal_increment;
return src_dX;
}
/**
* method returns to a certain minimal value the next higher value which can be
* displayed, which looks a bit nicer
* it returns values like ... 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, ...
*
* @param the double value next to which the displayable value should be found
* @return the displayable value
*/
public static double aBitBigger( double min ){
if( min <= 0 ) return 1;
double d = 1;
if( min < d ){
while( d * .5 > min ) {
d *= .5;
if( d * .4 > min ) d *= .4;
if( d * .5 > min ) d *= .5;
}
}
else{
while( d <= min ) {
d *= 2;
if( d <= min ) d *= 2.5;
if( d <= min ) d *= 2;
}
}
return d;
}
public boolean isBorderOpaque(){
return outer_border.isBorderOpaque();
}
//
// private String stringOf( double v ){
// if( (int)v == v ) return String.valueOf( (int)v );
// return String.valueOf( v );
// }
public Insets getBorderInsets(Component c){
if( under_construction ) System.out.println("ScaledBorder.getBorderInsets()");
if( !do_refresh && old_insets != null ) return old_insets;
Graphics g = c.getGraphics();
Insets insets = new Insets(0, 0, 0, 0);
if( show_outer_border ) insets = outer_border.getBorderInsets( c );
if( g == null ) return insets;
FontMetrics fm = g.getFontMetrics();
// int fontAsc = fm.getAscent();
int fontHeight = fm.getHeight(),
digit_width = fm.stringWidth("0");
if( c instanceof DArea ){
DArea area = (DArea)c;
DMeasures m = area.getDMeasures();
DRectangle rect = m.getSourceOf( area.getDRectangle() );
src_rect = (DRectangle)rect.clone();
x_scale = area.getDMeasures().x_scale;
y_scale = area.getDMeasures().y_scale;
}
// left:
if( y_label != null ) insets.left += fm.getAscent() + fm.getDescent();
insets.left += y_label2values * digit_width;
getSrcdY( fm, c.getSize() );
int n, maxWidth = 0;
n = (int)( src_rect.y / src_dY );
if( n * src_dY < src_rect.y ) n++;
while( n * src_dY <= src_rect.y + src_rect.height ){
// TODO here might be a bug for mean values
double v = n * src_dY;
if( y_scale != null ) v = y_scale.getImageOf( v );
int w = fm.stringWidth( format_y.format(v) );
if( w > maxWidth ) maxWidth = w;
n++;
}
insets.left += 1 + y_label2border + maxWidth + digit_width / y_values2marker + marker_length;
// bottom:
insets.bottom += 1 + fontHeight + x_label2border;
if( x_label != null ) insets.bottom += fontHeight;
// top:
if( show_arrows ) insets.top += y_values2arrow + arrow_length;
insets.top += axis2border;
// right:
if( show_arrows ) insets.right += x_values2arrow + arrow_length;
insets.right += axis2border;
getSrcdX( fm, c.getSize() );
n = (int)( src_rect.x + src_rect.width / src_dX );
if( n < 0 ) n ++;
int w = fm.stringWidth( format_x.format(n * src_dX) );
if( w / 2 > insets.right ) insets.right = w / 2;
old_insets = insets;
return insets;
}
}
/****************************************************************************
* END OF FILE
****************************************************************************/