用Java设计面向对象的打印程序
张来东 (zhangld@mail.hf.ah.cn)
打印程序的编写通常采用结构化的编程的方法,按特定的位置和一定顺序将打印内容送往打印机。在采用JAVA设计打印程序时仍然可采用结构化的方法,但是编写较为麻烦且代码不能重用,不是一种好的方法,给人一种"新瓶老酒"的感觉。目前为数不少的JAVA书籍在介绍打印时,侧重介绍打印功能的实现,而打印用例的主要代码却是结构化的。java网站在介绍java打印功能时,实现打印的代码也是结构化的。
假如将打印内容进行对象化分析,设计出面向对象的打印程序,则会更出色地完成打印要求,并且代码很轻易重用,事半功倍。(本文假定你已经了解java的打印功能)
一、打印对象的分析
打印通常包含以下基本内容:文字、线条、线框、图像等。比如一个表格是由若干文字、线条和线框对象其组成。为叙述简单,本文仅涉及以下三种对象。
文字对象的属性:文字内容,坐标,颜色,字体,对齐方式。
线条对象的属性:起点坐标,终点坐标,颜色,线宽。
线框对象的属性:左上角坐标,宽度,高度,线宽,颜色。
这些打印对象必须能根据属性将自己绘制出来。从另一个层面,可将打印的一页内容,理解为这些打印对象的容器。设计打印程序,只需将打印内容分解成适当的对象,由这些打印对象的集合来完成打印的要求。例如:打印普通表格。只需将表格分解成若开线框对象,线条对象,和文字对象。
二、打印对象的设计
设计思路:根据打印对象的分析,可以将打印的内容看成这些打印对象的集合。实际的打印就是将打印对象集合中的打印对象遍历,调用其print方法,因此这几类打印对象就需要封装相同的打印接口。
1、对象打印接口设计如下:
package lilidb;
import java.awt.Graphics;
/**
*打印对象接口;
*一、文字对象。二、线条对象。三、线框对象。每
*种对象各有其属性,但都必须有print方法。
*/
public interface PrintObject{
/**
*打印或预览实际内容
*@param g 打印或预览的图形对象,根据是预览还是打印传入具体的Graphics对象
*/
public void print(Graphics g);
}
2、 文字打印对象的设计
为了叙述的简单,文中的打印对象,未加居中等处理。
package lilidb;
import java.awt.*;
import java.util.*;
/**
*打印文字对象
**/
public class PrintLabel implements PrintObject{
String label;
int px;
int py;
Color color = Color.black;
FontMetrics fm;
/**
*构造PrintLabel 对象,
*@param ls 标签内容。
*@param x 标签的X坐标
*@param y 标签的Y坐标
*/
public PrintLabel(String ls,int x,int y){
label = ls;
px = x;
py = y;
range = 1;
}
/**
* 设置颜色
* @para colr 颜色值
*/
public void setRange(Color colr){
color = colr;
}
/**
*设置标签字体
*@param fontn 字体名称
*@param type 字体类型 可选值为 Font.BOLD,Font.ITALIC,Font.PLAIN
*@param size 字体象素尺寸
*/
public void setFont(String fontn,int type,int size){
font = new Font(fontn,type,size);
}
/**
*设置标签位置
*@param x x坐标
*@param y y坐标
*/
public void setLabelPosition(int x,int y){
px = x;
py = y;
}
/**
*设置标签内容
*@param ls 标签内容
*/
public void setLabelString(String ls){
label = ls;
}
/**
*打印或预览实际内容
*@param g 打印或预览的图形对象
*/
public void print(Graphics gg){
Graphics2D g = (Graphics2D)gg;
g.setFont(font);
g.drawString(label, px, py)
}
}
}
3、 线条打印对象的设计
package lilidb;
import java.awt.*;
import java.util.*;
import java.awt.Graphics2D;
import java.awt.Graphics;
/**
*线打印对象
*主要打印线条,其打印位置、和线形可以设置
*/
public class PrintLine implements PrintObject{
/**
*线的起点
*/
int startX;
int startY;
/**
*线的终点
*/
int endX;
int endY;
/**
*线长
*/
int lineLong;
/**
*线宽
*/
float lineWidth;
BasicStroke bs;
/**
*构造线对象,确定位置
*@param sx 线起点X坐标
*@param sy 线起点Y坐标
*@param ex 线终点X坐标
*@param ey 线终点Y坐标
*/
public PrintLine(int sx,int sy,int ex,int ey){
startX = sx;
startY = sy;
endX = ex;
endY = ey;
}
/**
*设置线宽
*@param w 线的宽度
*/
public void setWidth(float w){
lineWidth = w;
bs = new BasicStroke(lineWidth);
}
/**
*@see PrintObject#print
*/
public void print(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.setStroke(bs);
g2d.drawLine(startX, startY, endX, endY);
}
}
4、线框打印对象的设计
package lilidb;
import java.awt.*;
import java.awt.print.*;
import java.util.*;
/**
*打印矩形对象,矩形对象一般用来组成表格,
*/
public class PrintRectangle implements PrintObject{
float lineWidth;
BasicStroke bs;
/**
*3D矩形
*/
public final static int REC3D = 0;
/**
*普通矩形
*/
public final static int RECNORMAL = 1;
/**
*圆角矩形
*/
public final static int RECROUND = 2;
int px;
int py;
int w;
int h;
/**
* x 方向圆倒角直径
*/
int ax;
/**
* y 方向圆倒角直径
*/
int ay;
int type;
boolean raised;
/**
*设置线宽
*@param w 线的宽度
*/
public void setWidth(float w){
lineWidth = w;
bs = new BasicStroke(lineWidth);
}
/**
*构造矩形打印对象
*@param x 矩形左上角 X 坐标
*@param y 矩形左上角 y 坐标
*@param width 矩形宽
*@param height 矩形高
*/
public PrintRectangle(int x,int y,int width ,int height){
px = x;
py = y;
w = width;
h = height;
}
/**
*设置矩形类型
*@param t 矩形类型
*/
public void setType(int t){
type = t;
}
/**
*设置3D矩形类型
*@param r 是否升起
*/
public void set3DType(boolean r){
raised =r;
}
/**
*设置圆角矩形的圆角
*@param xd x方向圆角直径
*@param yd y方向圆角直径
*/
public void setRound(int xd,int yd){
ax = xd;
ay = yd;
}
/**
*@see PrintObject#print
*/
public void print(Graphics gg){
Graphics2D g = (Graphics2D)gg;
g.setStroke(bs);
switch (type){
case REC3D:{
g.draw3DRect(px, py, w, h, raised);
break;
}
case RECNORMAL:{
g.drawRect(px, py, w, h);
break;
}
case RECROUND:{
g.drawRoundRect(px, py, w, h, ax, ay);
break;
}
}
}
}
5、 打印内容的基类的设计
基类必须具有要有一个打印对象的容器,程序中使用了Vector对象。