面的讨论我们已经知道构成图表的基本的元素和它们的特性了。由此我们可以为这几个图表元素设计几个接口类。在设计之前,要首先说明一下,我们不打算实现类似于商业化图表组件的强大交互功能,我们所有的设计,只是为了能阐明问题。
图表元素接口(ChartWidget)
因为所有的图表可视元素都有一些共同的属性:位置,宽度和高度,它们还要负责绘制自己本身。所以我们设计一个ChartWidget接口,其它所有可视元素都要继承于这个接口。这个接口的类图如图2-4:
图2-4
由这个类图,我们可以很容易的写出它的代码:
public interface ChartWidget{
public int getX();
public int getY();
public int getWidth();
public int getHeight();
public void draw(Graphics g);
}
坐标轴(Axis)
接下来的一个类是坐标轴Axis。坐标轴主要任务是绘制轴及其刻度(Tick)和刻度值,因为它绘制时是按一定的比例绘制的,所以它需要有一个比例尺将实际坐标值转换值成屏幕坐标值。这就引出了Scale这个类。Scale类主要完成实际坐标值到屏幕坐标值以及屏幕坐标值到实际坐标值的相互转化。由此,Axis与Scale是一对相互依赖的类。从设计模式的角度来看,Axis是视图(View),负责界面绘制,Scale就是它的模型(Model),负责提供相应的数据。它们的类图见图2-5:
图2-5
构建可扩展的Java图表组件(5)
时间:2010-09-13
下面来分别看看Axis类与Scale类的代码:
public abstract class Axis implements ChartWidget
{
protected Scale scale;
protected int x;
protected int y;
protected int width;
protected int height;
protected Axis peerAxis;
protected boolean drawGrid;
protected Color gridColor;
protected Color axisColor;
protected int tickLength;
protected int tickCount;
public Axis()
{
gridColor = Color.LIGHT_GRAY;
axisColor = Color.BLACK;
tickLength = 5;
drawGrid = false;
}
public int getTickCount(){ return tickCount;}
public void setTickCount(int tickCount){this.tickCount=tickCount;}
public Scale getScale(){ return scale;}
public void setScale(Scale scale){ this.scale = scale;}
public int getX(){ return x;}
public void setX(int x){this.x = x;}
public int getY(){ return y;}
public void setY(int y){this.y = y;}
public int getHeight(){ return height;}
public void setHeight(int height){this.height = height;}
public int getWidth(){ return width;}
public void setWidth(int width){this.width = width;}
public boolean isDrawGrid(){return drawGrid;}
public void setDrawGrid(boolean drawGrid){this.drawGrid=drawGrid;}
public Color getAxisColor(){return axisColor;}
public void setAxisColor(Color axisColor){ this.axisColor=axisColor;}
public Color getGridColor(){return gridColor;}
public void setGridColor(Color gridColor){this.gridColor=gridColor;}
public int getTickLength(){return tickLength;}
public void setTickLength(int tickLength){this.tickLength=tickLength;}
public Axis getPeerAxis(){return peerAxis;}
public void setPeerAxis(Axis peerAxis){this.peerAxis = peerAxis;}protected abstract int calculateTickLabelSize(Graphics g);}
public abstract class Scale{
protected double min;
protected double max;
protected int screenMin;
protected int screenMax;
public abstract int getScreenCoordinate(double value);
public double getActualValue(int value)
{
double vrange = max - min;
if(min <
|