有什么javabean实现二维与三维图表的

wujj 2001-09-03 08:42:19
或在jsp中实现也行
...全文
164 点赞 收藏 5
写回复
5 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
chenyun2000 2001-09-06
可以创建可视化的JavaBeans来实现二维与三维图表,但无法在JSP中使用,原因是运行JSP的WEB容器是不支持AWT或SWING的,目前多数是用APPLET实现的
回复
cqzhangq 2001-09-06
使用applet速度会很慢,并且不通用。
最好的办法是用servlet来实现,只要将img的scr=一个servlet就行了,不过要将servlet的输出模式设置为image流,如:src=/servlet/imag.drawP?bm=2&...。

import java.io.*;
import java.io.StringWriter;
import javax.servlet.http.*;
import javax.servlet.*;
/**
* 在这里QueryString 是一个实现ImageProducer接口的一个类
*/
public class ImageServlet extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
try
{
Project project = new Project();//用来画图的bean
String type = project.createImage(response.getOutputStream());
response.setContentType(type);
}
catch (Exception e)
{
throw new ServletException(e);
}
}
}

在project这个bean中:
public String createImage(OutputStream stream) throws IOException{
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(stream);
BufferedImage bi = new BufferedImage(iImageWidth ,
iImageHeight,
BufferedImage.TYPE_BYTE_INDEXED);
graphics = bi.createGraphics() ;
if(!initSuccessed ){
graphics.drawString(new String("初始化日期出错,请使用xxxx-xx-xx格式"),50,60);
encoder.encode(bi);
return "image/jpg";
}
drawPhase();//画图的函数
encoder.encode(bi);
return "image/jpg";
}

在这里graphics是这个bean中的全局变量:private Graphics2D graphics,在drawPhase中还要用到。
没有时间了,这里就不列出详细的代码了,而且代码也没有整理只是从以前的代码中截下来的,相信能够给你启发了。
回复
tengyong 2001-09-06
这是我的一个APPLET程序,参考一下吧。传入参数就能显示出来柱状图了——

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class TableList extends Applet implements KeyListener, MouseListener, MouseMotionListener, WindowListener {
private int intMemberCount; //输入数据的每组的数量 需要输入
private int intGroupCount ; //输入的组数 需要输入
private double dblXMax ; //所有数据中的最大值
private double dblXMin ; //所有数据中的最小值
private double dblYMax ; //所有数据中的最大值 需要输入
private double dblYMin ; //所有数据中的最小值 需要输入
private double dblData[][]; //输入的实际数据 需要输入
private int intWidth ; //显示界面的宽度 需要输入
private int intHeight; //显示界面的高度 需要输入
private String strTitle = ""; //数据图的标题 需要输入
private int intOriginX; //原点坐标
private int intOriginY;
private int intXLineLong; //坐标轴长度
private int intYLineLong;
private double dblRatioX; //坐标轴比值
private double dblRatioY;
private String strXTitle[]; //x轴标题 需要输入
private String strGroupName[]; //数据分组名称,也就是图例名称 需要输入
private Rectangle HotArea[][];
private Rectangle ShowMode[] = new Rectangle[2];
private Cursor handCursor;
private Cursor normalCursor;
private int intShowMode;//0表示线图,1表示柱状图,2表示都显示
private Color finalColor[]={Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray, Color.green, Color.lightGray, Color.magenta, Color.orange, Color.pink, Color.red, Color.yellow, Color.white};;
private Color colorData[];
private Color colorBackColor=Color.white;
private Color colorForeColor=Color.black;
private Color colorDashedColor=Color.lightGray;
private int intModeShow;
/**
* 在此处插入方法说明。
* 创建日期:(2001-8-1 9:47:43)
*/
public void buildCoordinate() {
intOriginX = (int) (intWidth / 16); //得到原点坐标
intOriginY = (int) (intHeight * 13 / 16);
intXLineLong = (int) (intWidth * 3 / 4); //坐标轴长度
intYLineLong = (int) (intHeight * 3 / 4);
dblRatioX = intXLineLong / (dblXMax - dblXMin); //坐标与实际数据的转换比例
dblRatioY = intYLineLong / (dblYMax - dblYMin);

}
/**
* 在此处插入方法说明。
* 创建日期:(2001-8-1 9:55:04)
* @return double
* @param dblXData double
*/
public int dataChangetoXPoint(double dblXData) {
int intReturn;
Double obj=new Double(dblXData * dblRatioX);
intReturn = obj.intValue() + intOriginX;
return intReturn;
}
/**
* 在此处插入方法说明。
* 创建日期:(2001-8-1 9:56:34)
* @return double
* @param dblYData double
*/
public int dataChangetoYPoint(double dblYData) {
int intReturn;
Double obj = new Double(dblYData * dblRatioY);
intReturn = intOriginY - obj.intValue();
return intReturn;
}
/**
* 清理挂起的资源。如果 applet 是活动的,
* 它将被停止。
*
* @see #init
* @see #start
* @see #stop
*/
public void destroy() {
super.destroy();

// 在此处插入用来发行资源的代码
}
/**
* 返回关于此 applet 的信息。
* @return 返回关于此 applet 信息的字符串。
*/
public String getAppletInfo() {
return "TableList\n" +
"\n" +
"在此处插入类型说明。\n" +
"创建日期:(2001-7-30 15:15:57)\n" +
"@author:Administrator\n" +
"";
}
/**
* 返回此 applet 定义的参数。
* @return 接收器的参数说明数组
*/
public java.lang.String[][] getParameterInfo() {
String[][] info = {
{"strDouble", "String", "String strDouble"},
{"strTableName", "String", "String strTableName"},
{"strXPosName", "String", "String strXPosName"},
{"strYPosName", "String", "String strYPosName"}
};
return info;
}
/**
* 每当部件抛出异常时被调用
* @param exception java.lang.Throwable
*/
private void handleException(java.lang.Throwable exception) {

/* 除去下列各行的注释,以将未捕捉到的异常打印至 stdout。 */
// System.out.println("--------- 未捕捉到的异常 ---------");
// exception.printStackTrace(System.out);
}
/**
* 初始化 applet。

*/
public void init() {
try {
usePageParams();
setBackground(colorBackColor);
setForeground(colorForeColor);
setFont(new Font("\u6977\u4F53_GB2312", 0, 12));
setSize(intWidth, intHeight);
buildCoordinate();
handCursor = new Cursor(12);
normalCursor = new Cursor(0);
addMouseMotionListener(this);
addMouseListener(this);
} catch (java.lang.Throwable ivjExc) {
System.out.println("this is an error");
handleException(ivjExc);
}
}
/**
* 在此处插入方法说明。
* 创建日期:(2001-7-30 15:37:02)
*/
public void initForm() {


}
/**
* 在按键时调用。
* @param e 接收到的事件
*/
public void keyPressed(KeyEvent e) {
//System.out.println("keyPressed");
}
/**
* 在放开键时调用。
* @param e 接收到的事件
*/
public void keyReleased(KeyEvent e) {
//System.out.println("keyReleased");
}
/**
* 在按键时调用。
* @param e 接收到的事件
*/
public void keyTyped(KeyEvent e) {
//System.out.println("keyTyped");
}
/**
* 当作为应用程序运行时,启动 applet。
* @param args 命令行自变量数组
*/
public static void main(java.lang.String[] args) {
TableList applet = new TableList();
java.awt.Frame frame = new java.awt.Frame("Applet");

frame.addWindowListener(applet);
frame.add("Center", applet);
frame.setSize(350, 250);
frame.show();

applet.init();
applet.start();
}
public void mouseClicked(MouseEvent e) {
int i;
int x;
int y;
x = e.getX();
y = e.getY();
for (i = 0; i < 2; i++) {
if (ShowMode[i] != null && ShowMode[i].contains(x, y) && intShowMode != i) {
intShowMode = i; //显示曲线图还是折线图
repaint();
break;
}
}
}
/**
* 在拖动鼠标时调用。
* @param e 接收到的事件
*/
public void mouseDragged(MouseEvent e) {
//System.out.println("mouseDragged");
}
/**
* 在鼠标进入窗口时调用。
* @param e 接收到的事件
*/
public void mouseEntered(MouseEvent e) {
//System.out.println("mouseEntered");
}
/**
* 在鼠标退出窗口时调用。
* @param e 接收到的事件
*/
public void mouseExited(MouseEvent e) {
//System.out.println("mouseExited");
}
/**
* 在移动鼠标时调用。
* @param e 接收到的事件
*/
public void mouseMoved(MouseEvent e) {
//System.out.println("mouseMoved");
setCursor(normalCursor);
int x = e.getX();
int y = e.getY();
int i = 0;
int j = 0;
boolean isExit = false;
try {
printData();//把具体数据显示的地方用背景色填充
for (i = 0; i < intGroupCount && isExit == false; i++) {
for (j = 0; j < intMemberCount && isExit == false; j++) {
if (HotArea[i][j] != null && HotArea[i][j].contains(x, y)) {
setCursor(handCursor);
isExit = true;
printData(x, y, j);//显示具体的数据
break;
}
}
}
for (i = 0; i < 2 && isExit == false; i++) {
if (ShowMode[i]!= null && ShowMode[i].contains(x, y)) {
setCursor(handCursor);
//intShowMode = i;
//repaint();
break;
}
}
} catch (Exception ex) {
System.out.println("This is an error ");
}
}
/**
* 在按下鼠标按钮时调用。
* @param e 接收到的事件
*/
public void mousePressed(MouseEvent e) {
//System.out.println("mousePressed");

}
/**
* 在释放鼠标按钮时调用。
* @param e 接收到的事件
*/
public void mouseReleased(MouseEvent e) {
//System.out.println("mouseReleased");
}
/**
* 绘制 applet。
* 如果此 applet 不需要绘制(例如,如果它只是其它
* awt 部件的一个容器),则可以安全地除去此方法。
*
* @param g 指定的“图形”窗口
* @see #update
*/
public void paint(Graphics g) {
//super.paint(g);
//画坐标轴
int i;
int j;
int intX1 = 0;
int intX2 = 0;
int intY1 = 0;
int intY2 = 0;
int intDashed = 0;
int intDashedCount = 0;
try {
g.drawString(strTitle, (int) (intWidth / 3), (int) (intHeight / 16)); //画标题
if (intModeShow == 1) {
g.drawString("折线图", (int) (intWidth / 6), (int) (intHeight / 10)); //画标题
g.drawString("柱状图", (int) (intWidth / 2), (int) (intHeight / 10)); //画标题

ShowMode[0] = new Rectangle((int) (intWidth / 6), (int) (intHeight / 12), (int) (intWidth / 16), (int) (intHeight / 16)); //热区
ShowMode[1] = new Rectangle((int) (intWidth / 2), (int) (intHeight / 12), (int) (intWidth / 16), (int) (intHeight / 16)); //热区

}
switch (intShowMode) {
case 0 :
{
intX1 = dataChangetoXPoint(dblXMin);
intY1 = dataChangetoYPoint(dblYMin);
intX2 = dataChangetoXPoint(dblXMax - 1);
intY2 = dataChangetoYPoint(dblYMax);
intDashed = (int) (intHeight / 128);
intDashedCount = (int) (intYLineLong / intDashed);
for (i = 0; i < intMemberCount; i++) {
if (strXTitle[i] == "") {
} else {
int intXPos;
intXPos = intX1 + (int) (intXLineLong * i / intMemberCount);
for (j = 0; j < intDashedCount; j += 2) {
g.setColor(colorDashedColor);
g.drawLine(intXPos, (intY1 - intDashed * j), intXPos, (intY1 - intDashed * (j + 1))); //画平行于y轴虚线
g.setColor(colorDashedColor);
g.drawLine(intXPos, (intY1 - intDashed * (j + 1)) - intDashed, intXPos, (intY1 - intDashed * (j + 2))); //画平行于y轴虚线
}
g.setColor(colorForeColor);
g.drawString(strXTitle[i], (intXPos - (int) (intWidth / 64)), intY1 + (int) (intHeight / 16)); //x轴标题
}
}
double dblYValue;
final int intYCount = 10;
intDashed = (int) (intWidth / 128);
intDashedCount = (int) (intXLineLong * (intMemberCount - 1) / ((intDashed) * intMemberCount));
for (i = 0; i < intYCount + 1; i++) {
dblYValue = (dblYMax - dblYMin) * ((double) i / (double) intYCount) + dblYMin;
int intYPos = intY1 - (int) (intYLineLong * i / intYCount); //(int)dataChangetoYPoint(dblYValue);
for (j = 0; j < intDashedCount; j += 2) {
g.setColor(colorDashedColor);
g.drawLine(intX1 + intDashed * j, intYPos, (intX1 + intDashed * (j + 1)), intYPos); //画平行于x轴虚线
g.setColor(colorBackColor);
g.drawLine((intX1 + intDashed * (j + 1)), intYPos, (intX1 + intDashed * (j + 2)), intYPos); ////画平行于x轴虚线
}
g.setColor(colorForeColor);
g.drawString("" + (int) dblYValue, intX1 - (int) (intWidth / 24), intYPos + (int) (intHeight / 64)); //写y轴标题
}
g.setColor(colorForeColor);
g.drawLine(intX1, intY1, intX2, intY1); //x轴
g.drawLine(intX1, intY1, intX1, intY2); //y轴
g.drawLine(intX2, intY1, (intX2 - (int) (intWidth / 64)), (intY1 + (int) (intHeight / 128))); //x轴箭头
g.drawLine(intX2, intY1, (intX2 - (int) (intWidth / 64)), (intY1 - (int) (intHeight / 128))); //x轴箭头
g.drawLine(intX1, intY2, (intX1 + (int) (intWidth / 256)), (intY2 + (int) (intHeight / 32))); //y轴箭头
g.drawLine(intX1, intY2, (intX1 - (int) (intWidth / 256)), (intY2 + (int) (intHeight / 32))); //y轴箭头

//g.setColor(Color.blue);
//g.drawString("+", (intX2 - (int) (intWidth / 32)), (intY1 + (int) (intHeight / 32))); //x轴"+"
//g.drawString("+", (intX1 - (int) (intWidth / 64)), (intY2 + (int) (intHeight / 16))); //y轴"+"
//g.setColor(Color.red);
//g.drawString("-", (intX1 - (int) (intWidth / 64)), (intY1 + (int) (intHeight / 32)));
//图形
for (i = 0; i < intGroupCount; i++) {
for (j = 0; j < intMemberCount; j++) {
if (colorData[i] == null) {
g.setColor(finalColor[i]);
} else {
g.setColor(colorData[i]);
}
if (j < 1) {
intX1 = dataChangetoXPoint((double) j);
intY1 = dataChangetoYPoint(dblData[i][j]);
HotArea[i][j] = new Rectangle(intX1 - (int) (intWidth / 64), intY1 - (int) (intHeight / 64), (int) (intWidth / 32), (int) (intHeight / 32)); //热区
} else {
intX2 = intX1;
intY2 = intY1;
intX1 = dataChangetoXPoint((double) j);
intY1 = dataChangetoYPoint(dblData[i][j]);
HotArea[i][j] = new Rectangle(intX1 - (int) (intWidth / 64), intY1 - (int) (intHeight / 64), (int) (intWidth / 32), (int) (intHeight / 32)); //热区
g.drawLine(intX1, intY1, intX2, intY2);
}
}
}
break;
}
case 1 :
{
intX1 = dataChangetoXPoint(dblXMin);
intY1 = dataChangetoYPoint(dblYMin);
intX2 = dataChangetoXPoint(dblXMax) + (int) (intWidth / 32);
intY2 = dataChangetoYPoint(dblYMax);
intDashed = (int) (intHeight / 128);
intDashedCount = (int) (intYLineLong / intDashed);
for (i = 1; i < intMemberCount + 1; i++) {
if (strXTitle[i - 1] == "") {
} else {
int intXPos;
intXPos = intX1 + (int) (intXLineLong * i / intMemberCount);
for (j = 0; j < intDashedCount; j += 2) {
g.setColor(colorDashedColor);
g.drawLine(intXPos, (intY1 - intDashed * j), intXPos, (intY1 - intDashed * (j + 1))); //画平行于y轴虚线
g.setColor(colorDashedColor);
g.drawLine(intXPos, (intY1 - intDashed * (j + 1)) - intDashed, intXPos, (intY1 - intDashed * (j + 2))); //画平行于y轴虚线
}
g.setColor(colorForeColor);
g.drawString(strXTitle[i - 1], (intXPos - (int) (intWidth / 20)), intY1 + (int) (intHeight / 16)); //x轴标题
}
}
double dblYValue;
final int intYCount = 10;
intDashed = (int) (intWidth / 128);
intDashedCount = (int) (intXLineLong / intDashed);
for (i = 0; i < intYCount + 1; i++) {
dblYValue = (dblYMax - dblYMin) * ((double) i / (double) intYCount) + dblYMin;
int intYPos = intY1 - (int) (intYLineLong * i / intYCount); //
for (j = 0; j < intDashedCount; j += 2) {
g.setColor(colorDashedColor);
g.drawLine(intX1 + intDashed * j, intYPos, (intX1 + intDashed * (j + 1)), intYPos); //画平行于x轴虚线
g.setColor(colorBackColor);
g.drawLine((intX1 + intDashed * (j + 1)), intYPos, (intX1 + intDashed * (j + 2)), intYPos); ////画平行于x轴虚线
}
g.setColor(colorForeColor);
g.drawString("" + (int) dblYValue, intX1 - (int) (intWidth / 24), intYPos + (int) (intHeight / 64)); //写y轴标题
}
g.setColor(colorForeColor);
//intX2 = intX2 + (int) (intWidth / 32);
g.drawLine(intX1, intY1, intX2, intY1); //x轴
g.drawLine(intX1, intY1, intX1, intY2); //y轴
g.drawLine(intX2, intY1, (intX2 - (int) (intWidth / 64)), (intY1 + (int) (intHeight / 128))); //x轴箭头
g.drawLine(intX2, intY1, (intX2 - (int) (intWidth / 64)), (intY1 - (int) (intHeight / 128))); //x轴箭头
g.drawLine(intX1, intY2, (intX1 + (int) (intWidth / 256)), (intY2 + (int) (intHeight / 32))); //y轴箭头
g.drawLine(intX1, intY2, (intX1 - (int) (intWidth / 256)), (intY2 + (int) (intHeight / 32))); //y轴箭头

//g.setColor(Color.blue);
//g.drawString("+", (intX2 - (int) (intWidth / 32)), (intY1 + (int) (intHeight / 32))); //x轴"+"
//g.drawString("+", (intX1 - (int) (intWidth / 64)), (intY2 + (int) (intHeight / 16))); //y轴"+"
//g.setColor(Color.red);
//g.drawString("-", (intX1 - (int) (intWidth / 64)), (intY1 + (int) (intHeight / 32)));

//图形
int intRectWidth = (int) (intXLineLong * 63 / (64 * intGroupCount * intMemberCount));
for (i = 0; i < intGroupCount; i++) {
for (j = 0; j < intMemberCount; j++) {
if (colorData[i] == null) {
g.setColor(finalColor[i]);
} else {
g.setColor(colorData[i]);
}
intX2 = dataChangetoXPoint((double) j);
intY2 = dataChangetoYPoint(dblData[i][j]);
g.fillRect(intX2 + intRectWidth * i + (int) (intRectWidth / 4), intY2, intRectWidth, intY1 - intY2);
HotArea[i][j] = new Rectangle(intX2 + intRectWidth * i + (int) (intRectWidth / 4), intY2, intRectWidth, intY1 - intY2); //热区
//if (j < 1) {

// HotArea[i][j] = new Rectangle(intX1 - (int) (intWidth / 64), intY1 - (int) (intHeight / 64), (int) (intWidth / 32), (int) (intHeight / 32)); //热区
//} else {
// intX2 = intX1;
// intY2 = intY1;
// intX1 = dataChangetoXPoint((double) j);
// intY1 = dataChangetoYPoint(dblData[i][j]);

// g.drawLine(intX1, intY1, intX2, intY2);
//}
}
}
break;
}
}

//图例
g.setColor(colorForeColor);
//g.drawRect(dataChangetoXPoint(dblXMax) + (int) (intWidth / 128), dataChangetoYPoint(dblYMax), (int) (intWidth * 3 / 16), intYLineLong);
intX2 = dataChangetoXPoint(dblXMax);
intY2 = dataChangetoYPoint(dblYMax);
for (i = 0; i < intGroupCount; i++) {
if (colorData[i] == null) {
g.setColor(finalColor[i]);
} else {
g.setColor(colorData[i]);
}
g.drawRect(intX2 + ((int) (intWidth / 128) * 2), (intY2 + ((int) (intHeight / 32) * i * 4)), (int) (intWidth / 32), (int) (intHeight / 32));
g.fillRect(intX2 + ((int) (intWidth / 128) * 2), (intY2 + ((int) (intHeight / 32) * i * 4)), (int) (intWidth / 32), (int) (intHeight / 32));
g.setColor(colorForeColor);
g.drawString(strGroupName[i], (intX2 + ((int) (intWidth / 128) * 2) + (int) (intWidth / 24)), (intY2 + ((int) (intHeight / 32) * i * 4) + (intHeight / 32)));
}
} catch (Exception e) {
System.out.println("this is an error at paint!");
}

//在此处插入用来绘制 applet 的代码。
}
/**
* 在此处插入方法说明。
* 创建日期:(2001-8-3 9:27:20)
* @param x int
* @param y int
* @param j int
*/
public void printData() {
int i;
int intX2;
int intY2;
Graphics g;
g = getGraphics();
intX2 = dataChangetoXPoint(dblXMax - 1);
intY2 = dataChangetoYPoint(dblYMax);
for (i = 0; i < intGroupCount; i++) {
g.setColor(colorBackColor);
g.fillRect((intX2 + ((int) (intWidth / 128) * 2) + (int) (intWidth / 12)), (intY2 + ((int) (intHeight / 32) * i * 4) + (intHeight / 24)), (int) (intWidth / 8), (int) (intHeight / 24));
}
}
/**
* 在此处插入方法说明。
* 创建日期:(2001-8-3 9:27:20)
* @param x int
* @param y int
* @param j int
*/
public void printData(int x, int y, int j) {
int i;
int intX2;
int intY2;
Graphics g;
g=getGraphics();
intX2=dataChangetoXPoint(dblXMax - 1);
intY2 = dataChangetoYPoint(dblYMax);
for (i = 0; i < intGroupCount; i++) {
if (HotArea[i][j] != null && HotArea[i][j].contains(x, y)) {
g.drawString(""+dblData[i][j], (intX2 + ((int) (intWidth / 128) * 2) + (int) (intWidth / 10)), (intY2 + ((int) (intHeight / 32) * i * 4) + (intHeight / 16)));
}
}
}
/**
* 调用此方法的作用是启动 applet。您无需直接调用此方法,
* 它在访问 applet 的文档时被调用。
* @see #init
* @see #stop
* @see #destroy
*/
public void start() {
super.start();
setCursor(normalCursor);
// 在此处插入 applet 启动时要运行的代码
}
/**
* 调用此方法的作用是停止 applet。当 applet 的文档
* 不再位于屏幕上时,将调用此方法。它保证在调用 destroy() 之前
* 被调用。用户无需直接调用此方法。
* @see #init
* @see #start
* @see #destroy
*/
public void stop() {
super.stop();

// 在此处插入要在 applet 停止时运行的任何代码
}
/**
* 在此处插入方法说明。
* 创建日期:(2001-7-30 16:20:43)
* @return int
*/

public void usePageParams() {
try {
String param = getParameter("wWidth");
if (param != null)
intWidth = Integer.parseInt(param);
param = getParameter("wHeight");
if (param != null)
intHeight = Integer.parseInt(param);
param = getParameter("Title");
if (param != null)
strTitle = param;
param = getParameter("GroupCount");
if (param != null)
intGroupCount = Integer.parseInt(param);
param = getParameter("MemberCount");
if (param != null) {
intMemberCount = Integer.parseInt(param);
dblXMax = (double) (intMemberCount);
dblXMin = 0;
}
param = getParameter("DataMax");
if (param != null)
dblYMax = Double.valueOf(param).doubleValue();
param = getParameter("DataMin");
if (param != null)
dblYMin = Double.valueOf(param).doubleValue();
param = getParameter("ShowMode");
if (param != null)
intShowMode = Integer.parseInt(param);
param = getParameter("ForeColor");
if (param != null)
colorForeColor = finalColor[Integer.parseInt(param)];

param = getParameter("BackColor");
if (param != null)
colorBackColor = finalColor[Integer.parseInt(param)];
param = getParameter("DashedColor");
if (param != null)
colorDashedColor = finalColor[Integer.parseInt(param)];
param = getParameter("ModeShow");
if (param != null)
intModeShow = Integer.parseInt(param);

//处理实际输入数据
int i;
int j;
int intStringIndex;
String strString;
dblData = new double[intGroupCount][intMemberCount];

for (i = 0; i < intGroupCount; i++) {
param = getParameter("Data" + (i + 1));
for (j = 0; j < intMemberCount; j++) {
intStringIndex = param.indexOf(";;");
if (intStringIndex >= 0) {
strString = param.substring(0, intStringIndex);
param = param.substring(intStringIndex + 2);
} else {
strString = param;
param = null;
}
if (strString != null && strString.length() > 0)
dblData[i][j] = Double.valueOf(strString).doubleValue();
else
dblData[i][j] = 0;
}
}

strGroupName = new String[intGroupCount];
param = getParameter("DataName");
for (i = 0; i < intGroupCount; i++) {
intStringIndex = param.indexOf(";;");
if (intStringIndex >= 0) {
strString = param.substring(0, intStringIndex);
param = param.substring(intStringIndex + 2);
} else {
strString = param;
param = null;
}
if (strString != null && strString.length() > 0)
strGroupName[i] = strString;
else
strGroupName[i] = "";
}

//处理x轴坐标标题
//int intStep = 1;

strXTitle = new String[intMemberCount];
//for (intStep = 1;(int) (intMemberCount / intStep) > 12; intStep *= 2);
param = getParameter("XTitle");
//System.out.println("intstep:" + intStep);
for (i = 0; i < intMemberCount; i++) {
intStringIndex = param.indexOf(";;");
if (intStringIndex >= 0) {
//if ((int) (i / intStep) == (i / intStep))

// System.out.println("(int) (i / intStep)"+(int) (i / intStep));
// System.out.println("(int) (i / intStep)"+(int) (i / intStep));

//如果x轴坐标数大于12则:
strString = param.substring(0, intStringIndex);
//else
// strString = "";
param = param.substring(intStringIndex + 2);
} else {
strString = param;
param = null;
}
if (strString != null && strString.length() > 0)
strXTitle[i] = strString;
else
strXTitle[i] = "";
}
HotArea = new Rectangle[intGroupCount][intMemberCount];

colorData = new Color[intGroupCount];
param = getParameter("ColorData");
for (i = 0; i < intGroupCount; i++) {
intStringIndex = param.indexOf(";;");
if (intStringIndex >= 0) {
strString = param.substring(0, intStringIndex);
param = param.substring(intStringIndex + 2);
} else {
strString = param;
param = null;
}
if (strString != null && strString.length() > 0) {
//System.out.println("ok" + Integer.valueOf(strString).intValue());
colorData[i] = finalColor[Integer.valueOf(strString).intValue()];

} else{
//System.out.println("ok" + Integer.valueOf(strString).intValue());
colorData[i] = finalColor[i];}
}

} catch (Exception e) {
System.out.println("this is an error at usePageparames");
}
}
/**
* 在窗口激活时调用。
* @param e 接收到的事件
*/
public void windowActivated(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口关闭时调用。
* @param e 接收到的事件
*/
public void windowClosed(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口正在关闭时调用。
* 可以在此处覆盖关闭操作。
* @param e 接收到的事件
*/
public void windowClosing(WindowEvent e) {
// 窗口正在关闭。关闭系统。
System.exit(0);
}
/**
* 在窗口不活动时调用。
* @param e 接收到的事件
*/
public void windowDeactivated(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口还原时调用。
* @param e 接收到的事件
*/
public void windowDeiconified(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口图标化时调用。
* @param e 接收到的事件
*/
public void windowIconified(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口打开时调用。
* @param e 接收到的事件
*/
public void windowOpened(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
}

————————————————————HTML文件————————————

<HTML>
<HEAD>
<TITLE>TableList</TITLE>
</HEAD>
<BODY>
<H1>TableList</H1>
<p>
<A HREF=TableList.java>TableList 的源文件</A>
<p>
<APPLET CODE=TableList.class WIDTH=610 HEIGHT=410>
<param name=wWidth value=600>
<param name=wHeight value=400>
<param name=Title value=数据演示图>
<param name=GroupCount value=5>
<param name=MemberCount value=12>
<param name=DataMax value=298>
<param name=DataMin value="-38">
<param name=DataName value="实例数据一;;实例数据二;;实例数据三;;实例数据四;;实例数据五">
<param name=Data1 value="35.1;;67.8;;10.9;;42.4;;109.7;;12.4;;38.4;;143.1;;5.6;;39.9;;190;;10.6;;39.2;;229.4;;16.8;;12;;;;29.3;;13.4;;">
<param name=Data2 value="4.7;;85.1;;60.5;;55.9;;140.5;;7.4;;51.9;;187.4;;7.1;;53.9;;246.1;;8.3;;52;;298;;18.5;;15.6;;;;19.4;;16.5;;;;">
<param name=Data3 value="18.2;;36.6;;12.8;;21.4;;-38;;4.3;;18.9;;70.3;;-8.2;;20.9;;96.9;;-0.4;;23;;119.8;;35.1;;67.8;;10.9;;42.4;;109.7;;12.4;;">
<param name=Data4 value="180.2;;36.6;;12.8;;210.4;;-28;;4.3;;18.9;;70.3;;-8.2;;20.9;;96.9;;-0.4;;23;;119.8;;35.1;;67.8;;10.9;;42.4;;109.7;;12.4;;">
<param name=Data5 value="40.7;;85.1;;6.5;;5.9;;140.5;;7.4;;1.9;;87.4;;7.1;;53.9;;246.1;;8.3;;52;;298;;18.5;;15.6;;;;19.4;;16.5;;;;">
<param name=XTitle value="一月;;二月;;三月;;四月;;五月;;六月;;七月;;八月;;九月;;十月;;十一月;;十二月;;一月;;二月;;三月;;四月;;五月;;六月;;七月;;八月;;">
<param name=ShowMode value=0>
<param name=BackColor value=12>
<param name=ForeColor value=0>
<param name=DashedColor value=9>
<param name=ColorData value="4;;5;;6;;7;;8">
<param name=ModeShow value=1>
</APPLET>
</BODY>
</HTML>

——————————————饼图的————————————————
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.Math;
import java.text.*;
/**
* 在此处插入类型说明。
* 创建日期:(2001-8-4 14:59:19)
* @author:Administrator
*/
public class CakeList extends Applet implements MouseListener, MouseMotionListener, WindowListener {
private int intMemberCount;
private double dblData[];
private String strTitle;
private String strName[];
private int intHeight;
private int intWidth;
private Color finalColor[]={Color.black, Color.blue, Color.cyan, Color.darkGray, Color.gray, Color.green, Color.lightGray, Color.magenta, Color.orange, Color.pink, Color.red, Color.yellow, Color.white};;
private Color colorData[];
private Color colorBackColor=Color.white;
private Color colorForeColor=Color.black;


/**
* 在此处插入方法说明。
* 创建日期:(2001-8-5 17:16:28)
* @return double
* @param intAngle int
* @param intAngleCount int
*/
public double cos(int intAngle, int intAngleCount) {
final double dblPI = (Math.PI * 2 / 360);
return (Math.cos(((double) intAngle + (double) (intAngleCount) / 2) * dblPI));
}
/**
* 清理挂起的资源。如果 applet 是活动的,
* 它将被停止。
*
* @see #init
* @see #start
* @see #stop
*/
public void destroy() {
super.destroy();

// 在此处插入用来发行资源的代码
}
/**
* 返回关于此 applet 的信息。
* @return 返回关于此 applet 信息的字符串。
*/
public String getAppletInfo() {
return "CakeList\n" +
"\n" +
"在此处插入类型说明。\n" +
"创建日期:(2001-8-4 14:58:43)\n" +
"@author:Administrator\n" +
"";
}
/**
* 返回此 applet 定义的参数。
* @return 接收器的参数说明数组
*/
public java.lang.String[][] getParameterInfo() {
String[][] info = {
{"CakeData", "String", ""},
{"MemberCount", "Number", ""},
{"BackColor", "Color", ""},
{"ForeColor", "Color", ""},
{"ColorData", "String", ""},
{"Title", "String", ""},
{"NameData", "String", ""}
};
return info;
}
/**
* 初始化 applet。
*/
public void init() {
//super.init();

//addMouseListener(this);
//addMouseMotionListener(this);
useParameter();

setBackground(colorBackColor);
setForeground(colorForeColor);
setFont(new Font("\u6977\u4F53_GB2312", 0, 12));



}
/**
* 当作为应用程序运行时,启动 applet。
* @param args 命令行自变量数组
*/
public static void main(java.lang.String[] args) {
CakeList applet = new CakeList();
java.awt.Frame frame = new java.awt.Frame("Applet");

frame.addWindowListener(applet);
frame.add("Center", applet);
frame.setSize(350, 250);
frame.show();

applet.init();
applet.start();
}
/**
* 在单击鼠标时调用。
* @param e 接收到的事件
*/
public void mouseClicked(MouseEvent e) {
System.out.println("mouseClicked");
}
/**
* 在拖动鼠标时调用。
* @param e 接收到的事件
*/
public void mouseDragged(MouseEvent e) {
System.out.println("mouseDragged");
}
/**
* 在鼠标进入窗口时调用。
* @param e 接收到的事件
*/
public void mouseEntered(MouseEvent e) {
System.out.println("mouseEntered");
}
/**
* 在鼠标退出窗口时调用。
* @param e 接收到的事件
*/
public void mouseExited(MouseEvent e) {
System.out.println("mouseExited");
}
/**
* 在移动鼠标时调用。
* @param e 接收到的事件
*/
public void mouseMoved(MouseEvent e) {
System.out.println("mouseMoved");
}
/**
* 在按下鼠标按钮时调用。
* @param e 接收到的事件
*/
public void mousePressed(MouseEvent e) {
System.out.println("mousePressed");
}
/**
* 在释放鼠标按钮时调用。
* @param e 接收到的事件
*/
public void mouseReleased(MouseEvent e) {
System.out.println("mouseReleased");
}
/**
* 绘制 applet。
* 如果此 applet 不需要绘制(例如,如果它只是其它
* awt 部件的一个容器),则可以安全地除去此方法。
*
* @param g 指定的“图形”窗口
* @see #update
*/
public void paint(Graphics g) {
//super.paint(g);
int i;
double dblCount = 0;
int intAngle = 0;
int intPercent[];
intPercent = new int[intMemberCount];
int intAngleCount;
int intX1;
int intX2;
int intY1;
int intY2;
double dblXY;
double dblCos;
double dblSin;
NumberFormat nf = NumberFormat.getPercentInstance();
String strString;
dblXY = ((double) (intHeight + intWidth)) / 8;
try {
g.drawString(strTitle, (int) (intWidth / 2), (int) (intHeight / 16));
for (i = 0; i < intMemberCount; i++) {
dblCount = dblCount + dblData[i];
}
for (i = 0; i < intMemberCount; i++) {
intPercent[i] = (int) (360 * (dblData[i] / dblCount));
if (intPercent[i] == 0) {
intAngleCount = 1;
} else {
intAngleCount = intPercent[i];
}
g.setColor(colorData[i]);
g.fillArc((int) (intWidth / 4), (int) (intHeight / 4), (int) (intWidth / 2), (int) (intHeight / 2), intAngle, intAngleCount);
g.setColor(colorForeColor);
dblCos = cos(intAngle, intAngleCount);
dblSin = sin(intAngle, intAngleCount);
intX1 = ((int) (dblCos * dblXY / 2)) + (intWidth / 2);
intX2 = ((int) (dblCos * dblXY * 1.2)) + (intWidth / 2);
intY1 = (int) (intHeight / 2) - ((int) (dblSin * dblXY / 2));
intY2 = (int) (intHeight / 2) - ((int) (dblSin * dblXY * 1.2));
g.drawLine(intX1, intY1, intX2, intY2);
strString = nf.format(dblData[i] / dblCount);
if (intX2 < (int) (intWidth / 2)) {
g.drawLine((intX2 - (int) (dblXY / 8)), intY2, intX2, intY2);
g.drawString(strName[i], (intX2 - (int) (dblXY / 2)), intY2);
g.drawString(dblData[i] + "(" + strString + ")", (intX2 - (int) (dblXY / 2)), intY2 + (int) (intHeight / 32));
} else {
g.drawLine((intX2 + (int) (dblXY / 8)), intY2, intX2, intY2);
g.drawString(strName[i], (intX2 + (int) (dblXY / 4)), intY2);
g.drawString(dblData[i] + "(" + strString + ")", (intX2 + (int) (dblXY / 4)), intY2 + (int) (intHeight / 32));
}
intAngle += intAngleCount;
}
} catch (Exception e) {
System.out.println("this is an error");
}
}
/**
* 在此处插入方法说明。
* 创建日期:(2001-8-5 17:16:28)
* @return double
* @param intAngle int
* @param intAngleCount int
*/
public double sin(int intAngle, int intAngleCount) {
final double dblPI = (Math.PI * 2 / 360);
return (Math.sin(((double) intAngle + (double) (intAngleCount) / 2) * dblPI));
}
/**
* 调用此方法的作用是启动 applet。您无需直接调用此方法,
* 它在访问 applet 的文档时被调用。
* @see #init
* @see #stop
* @see #destroy
*/
public void start() {
super.start();

// 在此处插入 applet 启动时要运行的代码
}
/**
* 调用此方法的作用是停止 applet。当 applet 的文档
* 不再位于屏幕上时,将调用此方法。它保证在调用 destroy() 之前
* 被调用。用户无需直接调用此方法。
* @see #init
* @see #start
* @see #destroy
*/
public void stop() {
super.stop();

// 在此处插入要在 applet 停止时运行的任何代码
}
/**
* 在此处插入方法说明。
* 创建日期:(2001-8-4 15:00:43)
*/
/*< param name = CakeData value = "" > < param name = BackColor value = "" > < param name = ForeColor value = "" > < param name = ColorData value = "" > < param name = NameData value = "" > */
public void useParameter() {
try {
String param = getParameter("wWidth");
if (param != null)
intWidth = Integer.parseInt(param);
param = getParameter("wHeight");
if (param != null)
intHeight = Integer.parseInt(param);
param = getParameter("Title");
if (param != null)
strTitle = param;
param = getParameter("MemberCount");
if (param != null)
intMemberCount = Integer.parseInt(param);

param = getParameter("ForeColor");
if (param != null) {

colorForeColor = finalColor[Integer.parseInt(param)];
}
param = getParameter("BackColor");
if (param != null) {

colorBackColor = finalColor[Integer.parseInt(param)];
}

int i;
int j;
int intStringIndex;
String strString;
dblData = new double[intMemberCount];
param = getParameter("CakeData");
for (i = 0; i < intMemberCount; i++) {
intStringIndex = param.indexOf(";;");
if (intStringIndex >= 0) {
strString = param.substring(0, intStringIndex);
param = param.substring(intStringIndex + 2);
} else {
strString = param;
param = null;
}
if (strString != null && strString.length() > 0)
dblData[i] = Double.valueOf(strString).doubleValue();
else
dblData[i] = 0;
}
colorData = new Color[intMemberCount];
param = getParameter("ColorData");
for (i = 0; i < intMemberCount; i++) {
intStringIndex = param.indexOf(";;");
if (intStringIndex >= 0) {
strString = param.substring(0, intStringIndex);
param = param.substring(intStringIndex + 2);
} else {
strString = param;
param = null;
}
if (strString != null && strString.length() > 0) {
//System.out.println("ok" + Integer.valueOf(strString).intValue());
colorData[i] = finalColor[Integer.valueOf(strString).intValue()];
} else
colorData[i] = finalColor[i];
}

strName= new String[intMemberCount];
param = getParameter("NameData");
for (i = 0; i < intMemberCount; i++) {
intStringIndex = param.indexOf(";;");
if (intStringIndex >= 0) {
strString = param.substring(0, intStringIndex);
param = param.substring(intStringIndex + 2);
} else {
strString = param;
param = null;
}
if (strString != null && strString.length() > 0)
strName[i] = strString;
else
strName[i] = "";
}
} catch (Exception e) {
System.out.println("this is an error appear in userParameter");
}
}
/**
* 在窗口激活时调用。
* @param e 接收到的事件
*/
public void windowActivated(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口关闭时调用。
* @param e 接收到的事件
*/
public void windowClosed(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口正在关闭时调用。
* 可以在此处覆盖关闭操作。
* @param e 接收到的事件
*/
public void windowClosing(WindowEvent e) {
// 窗口正在关闭。关闭系统。
System.exit(0);
}
/**
* 在窗口不活动时调用。
* @param e 接收到的事件
*/
public void windowDeactivated(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口还原时调用。
* @param e 接收到的事件
*/
public void windowDeiconified(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口图标化时调用。
* @param e 接收到的事件
*/
public void windowIconified(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
/**
* 在窗口打开时调用。
* @param e 接收到的事件
*/
public void windowOpened(WindowEvent e) {
// 不做任何事情。
// 此方法要求符合 WindowListener 接口。
}
}
---------------------------------HTML————————————————

<HTML>
<HEAD>
<TITLE>CakeList</TITLE>
</HEAD>
<BODY>
<H1>CakeList</H1>
<p>
<A HREF=CakeList.java>CakeList 的源文件</A>
<p>
<APPLET CODE=CakeList.class WIDTH=400 HEIGHT=400>
<param name=CakeData value="20;;30;;40;;10;;20;;30;;40;;10">
<param name=MemberCount value=8>
<param name=BackColor value=12>
<param name=ForeColor value=0>
<param name=ColorData value="1;;2;;3;;4;;5;;6;;7;;8">
<param name=Title value=饼图示例一>
<param name=NameData value="名称一;;名称二;;名称三;;名称四;;名称五;;名称六;;名称七;;名称八">
<param name=wWidth value=400>
<param name=wHeight value=400>
</APPLET>
</BODY>
</HTML>

回复
tengyong 2001-09-06
在网页上发布统计曲线


一、引言

  在熙熙攘攘的Internet上制作极富个性化的主页、及时发布令人心动的信息
,以便吸引全世界不同肤色、不同职业的人们驻"足"观看,以致流连忘返,甚者慷慨
解囊,是Internet冲浪者心中的梦想。通过合理运用HTML脚本语言提供的表格、列
表、字体和段落的格式化、多媒体支持等,能使网页内容清晰、层次分明、可读性
强,这些已有众多文献论述,在此不再赘述。

  我们知道,在各种信息中,统计信息堪称是用得较多、具有相当说服力的信息
,而表达统计数据最直观的方式是根据这些数据绘制曲线。文献[1]用相当的篇幅
介绍了如何在Windows操作系统中编写一个具有OLE服务器能力的统计曲线绘制工
具,而本文的主题则是:如何利用Java对绘图的支持,编写一个根据统计数据绘制曲
线的小程序(Applet)Plot,通过把Plot编译生成的字节码文件Plot.class嵌入到H
TML脚本中,从而实现在网页上发布统计曲线的目的。

  二、Java编程概述

  1.Java语言规范

  Java继承了C++的基本语法,摒弃了一些过时的特征,比如预编译的头文件、宏
、条件编译,数据结构的结构体、枚举体和联合体,容易导致安全性问题的指针,以
及晦涩难懂的多重继承等,借鉴了Objective C的接口和Ada的包(package),以及内
置了Internet网络所需要的基本特征:结构中立(任何芯片、任何操作系统可以运
行同一版本的Java程序)、安全性(避免感染病毒和防止非法访问)、多线程和网络
通信等。事实上,上述被Java抛弃的特征,如指针和类的多重继承,都是由于太复杂
而遭C++程序员诅咒的;而新发展的特征,如结构中立、安全性、多线程和网络通信
等,是C++程序员极想实现而又非常难实现的特征。

  2.JDK

  Windows程序员一定都知道做Windows开发要用Windows SDK(软件开发工具),
现在,做Ja va开发的程序员也都知道编写Java小程序要用JDK(Java开发工具)了。
然而,与SDK主要采用结构体和函数等面向过程的方式提供Windows编程接口不同,
JDK采用包、界面和类等面向对象的方式提供Java编程接口。从这种意义上说,JD
K与Microsoft Visual C++的MFC,或者Bor land C++的OWL相似:它是一个类库,一
个应用框架,一个无缝集成的解决方案。

  最先发布的JDK应该算JDK 1.0.3α,它是1995年Sun公司在全球范围内进行Ja
va程序设计大奖赛时随HotJava 1.0.3α发放的。在该版本中,通用包实现得比较
少,只有java.lang、j ava.util和java.io,而其他有关用户界面和网络通信的包
都在HotJava中提供。尔后发行了1.0版,这是提供给各Java平台开发公司的,其中
,包全部独立出来,共八个:java.applet、ja va.awt 、java.awt.image 、java.
awt.peer 、java.io、java.lang、java.net 和java. util 以及一个sun.tools
.debug。本文的程序基于1.0版本编写。由于1.0.3α和1.0两个版本的包安排差别
很大,因而用前一个版本编写的程序在后一个版本的编译工具中编译有可能通不过
,要作修改。在1996年8月底,Sun公司在Internet上发布了1.1版,1.1版在1.0版基
础上稍有改进,两个版本保持完全的兼容。

  三、设计目标和程序构思

  现在我们回到本文的主题上。首先,考虑编写一个Java小程序,它的界面和功
能可以这样来描述:

  统计标题和统计数据由HTML的param标注提供,统计数据的个数没有限制;
  根据数据的取值画出带刻度的X、Y轴;
  在用线连接每个数据点的同时标出该点的坐标值;
  提供绘制三组曲线的选择。

  针对上述要求,考虑构造两个类来完成:Curve类用于实现绘制统计曲线的各个
方面;Plo t类则派生于Applet,它是本程序的小程序类,通过使用Curve类来完成统
计曲线的绘制。鉴于篇幅,下面给出实现要点及其程序。如需要全部源代码的读者
,请与笔者联系。

  1.Curve类

  Curve类构造主要基于以下几点考虑。

  (1)基类。Curve从Java所有类的基类Object派生,那么就可以不显式声明了。


class Curve {
......
}

  (2)绘图环境。根据Windows等窗口操作系统的编程经验,向显示器、打印机等
输出设备绘图是通过绘图环境来实现的。由于Java要面向所有平台,包括Windows
、Unix和Macintosh 等,它们的绘图环境(如显示器)概念很不一样。那么,Java如
何来实现绘图呢?原来,Java在java.awt包中通过Graphics类来提供了对各种绘图
设备的设备环境的抽象类封装。用Window s编程来作对照,Graphics所代表的概念
就是Windows GDI的设备环境(Device Context),也就是MFC中CDC类或OWL的TDc类
。有了这样的比较,对Graphics就比较好理解了。也就是,所有绘制直线、矩形、
椭圆、多边形、设置字体、绘制文本等操作,调用Graphics类中的相应方法即可。
下面代码是通过Curve构造器将小程序类Plot的设备环境对象g传递给Curve,以被
其他各个绘制方法使用:

public Curve(Graphics g)
{
myGC = g;
......
}

  (3)绘制算法。绘制算法就是绘制统计曲线的实现方法,包括绘制标题、坐标
轴、数据联线、标出数据点坐标等,以及其逆过程:清除这些绘制(因为当绘制其他
曲线时,得保证刷新前一次绘制的所有内容)。鉴于篇幅,下面仅给出显示数据的方
法实现showData.

public synchronized void showData(Vector v)
{
float maxY=0;
myGC.setColor(Color.red);
int xPoint;
int yPoint;
//确定Vector中的最大值。
for(int i = 0; i < v.size(); i++)
{
float temp = ((Float)v.elementAt(i)).floatValue();
if(temp > maxY)
{
maxY = temp;
}
}
//确定第一个数据点的X坐标。
xPoint = xOrigin + (xSpacing/2);
int oldX = 0;
int oldY = 0;
//在数据点处绘制一个小圆圈。
for(int j = 0; j < v.size(); j++)
{
yPoint = yOrigin(int)((axisH/maxY) *
((Float)v.elementAt(j)).floatValue());
myGC.fillRect(xPoint, yPoint, 3, 3);
//在数据点之间联线。
if((oldX != 0) && (oldY != 0))
{
myGC.drawLine(oldX-xSpacing, oldY, xPoint, yPoint)
;
}
myGC.setColor(Color.blue);
//在数据点边上写出数据值。
String coordString =
Float.toString(((Float)v.elementAt(j)).floatValue(
));
myGC.drawString(coordString, xPoint+5, yPoint - 4);
myGC.setColor(Color.red);
xPoint += xSpacing;
oldX = xPoint;
oldY = yPoint;
}
}

  2.Plot类

  Plot类构造主要基于以下几点考虑。

  (1)派生于Applet

  一个Java小程序有且只有一个类派生于Applet,这就好像在MFC中,必须有且只
有一个类派生于CWinApp一样。另外,与MFC程序不一样的是,不管包含派生于Appl
et类的源程序文件( .java)命名为什么,生成的供网页使用的字节码文件(.class
)只与该派生类同名,而与源文件名无关,这一点容易引起混淆。打个比方,如果包
含Plot类的文件为PlotTest.java,而编译生成的字节码文件名为Plot.class,而不
是PlotTest.class。最后,Plot必须声明为public,这是由于一个编辑单元必须有
且只有一个类声明为public。

public class Plot extends Applet
{
......
}

  (2)用户界面

  目前,Java在java.awt中提供小程序的用户界面所需要的接口和类(共42个类
和2个接口),其中实现了我们在Windows中见到的各种用户界面,比如,菜单、对话
框,以及各种控件,如按钮、列表框、复选框、单选框、编辑框、组合框等。鉴于
本程序要求从3组数据中选择一组进行绘制,需要选用单选框控件。单选框在java
.awt中用Checkbox和CheckboxGroup两个类联合实现:当Checkbox单独使用时,它是
复选框;而把它添加到CheckboxGroup中则变成了单选框。

public void init()
{
......
cbg = new CheckboxGroup();
//单选按钮。
cb1 = new Checkbox("数据1", cbg, false);
cb2 = new Checkbox("数据2", cbg, false);
cb3 = new Checkbox("数据3", cbg, false);
}

  (3)布局管理器

  在Java中,为了使得小程序在各种操作系统中的用户界面具有一致的外观,采
用布局管理器(Layout Manager)对用户界面的相对位置进行管理。Java在java.a
wt包中包含了流布局管理器(FlowLayout)、边界布局管理器(BorderLayout)、卡
片布局管理器(CardLayout)、网格布局管理器(GridLayout)和网格包布局管理器
(GridBagLayout)5个布局管理器。如果希望3 个单选框按钮放在绘制图形的下面
按一行排列,该如何编写代码呢?可以这样来实现:首先设置Plot小程序为边界布局
,然后为3个单选框按钮创建一个Panel对象cbPanel,用于组织3个控件,并设置cbP
anel为网格布局,最后将cbPanel添加到Plot类中,并设置其方向为南(South)。

public void init()
{
......
//设置Plot为边界布局。
setLayout(new BorderLayout());
//为3个控件申请面板对象cbPanel。
cbPanel = new Panel();
//设置网格布局管理器,并按1×3方式排列。
cbPanel.setLayout(new GridLayout(1, 3));
//为各按钮申请1个面板。
cb1Panel = new Panel();
cb1Panel.add(cb1);
cb2Panel = new Panel();
cb2Panel.add(cb2);
cb3Panel = new Panel();
cb3Panel.add(cb3);
//添加到统一的1个面板cbPanel中。
cbPanel.add(cb1Panel);
cbPanel.add(cb2Panel);
cbPanel.add(cb3Panel);
//添加cbPanel到Plot中,方向为:图形在北,按钮在南。
add("South", cbPanel);
}

  (4)读取HTML参数

  因为本程序要用到统计数据和统计标题作为小程序的参数存放在HTML文档中
,所以在开始绘制图形之前,需要从HTML读取这些参数,然后才开始显示标题和绘制
统计曲线。其中,读取统计标题和统计数据分别实现。

  ①统计标题,其格式可以是:
    <param value="1-DESC" value="每月访问者统计">
  1-DESC表示第一组数据的统计标题,"每月访问者统计"是标题内容。

public String readStringData(String s)
{
String tempString = null;
Integer param;
boolean datapresent = true;
int i = 0;
try
{
tempString = getParameter(s + "-DESC");
} catch (Exception e)
{
System.out.println(e);
}
return tempString;
}

  ②统计数据,格式可以是:
    <param value="1-2" value="14">
  1-2表示第一组数据的第二个数据点,14表示该数据点的值。

public Vector readData(String s)
{
Vector tempVector = new Vector();
Float param;
String tempData = null;
boolean datapresent = true;
int i = 0;
while(datapresent)
{
try {
tempData = getParameter(s + "-" + (i+1));
}
catch(Exception e)
{
System.out.println(e);
}
if(tempData == null)
{
datapresent = false;
} else {
param = Float.valueOf(tempData);
tempVector.addElement(param);
i += 1;
}
}
return tempVector;
}

  (5)消息循环

根据Windows编程经验,有用户界面就有消息循环,以组织消息处理函数句柄对用户
界面发出的消息进行响应。遗憾的是,在JDK 1.0中,尚没有类似MFC中的消息映射
表之类的东西组织消息循环。不过,Java发展势头迅猛,不久的将来就会有公司将
它实现!现在,我们需要自己来组织它:Applet类有一个action方法,在其中可以通
过if...then语句来对不同的消息进行响应。

public boolean action(Event e, Object o)
{
Vector actionVector = new Vector();
String actionString = new String();
if(e.target instanceof Checkbox)
{
//"数据1"发出的消息
if(cbg.getCurrent() == cb1)
{
actionVector = readData("1");
actionString = readStringData("1");
System.out.println("1");
}
//数据2发出的消息
if(cbg.getCurrent() == cb2)
{
actionVector = readData("2");
actionString = readStringData("2");
}
//数据3发出的消息
if(cbg.getCurrent() == cb3)
{
actionVector = readData("3");
actionString = readStringData("3");
}
int count = actionVector.size();
c.clearHashMarks();
c.clearScreen();
c.drawAxes(curveWidth, curveHeight);
c.makeHashMarks(count);
c.showData(actionVector);
c.makeTitle(actionString);
repaint();
return true;
}
return false;
}

  3.HTML文档和程序演示

  下面列出了一个HTML实例,用于观察上述编制的小程序,结果参见附图。

<html><body><center>
<applet code="Plot.class" width = 350 height = 200>
<param name="1-DESC" value="每月访问者统计">
<param name="1-1" value="10">
<param name="1-2" value="4">
<param name="1-3" value="17">
<param name="1-4" value="24">
<param name="1-5" value="9">
<param name="1-6" value="7">
<param name="1-7" value="30">
<param name="2-DESC" value="每年访问者统计">
<param name="2-1" value="17">
<param name="2-2" value="13">
<param name="3-DESC" value="一次购买税统计">
<param name="3-1" value="10000">
<param name="3-2" value="130000">
<param name="3-3" value="16100">
<param name="3-4" value="14000">
</applet></center></body>
<address><IMG SRC="\image\Li Zhenwen.jpg">
Li Zhenwen, Zhenwen@Websoft.com
</address></html>

回复
olvest4000 2001-09-05
很多啊,要道入ui!
回复
相关推荐
发帖
Web 开发
创建于2007-09-28

8.0w+

社区成员

Java Web 开发
申请成为版主
帖子事件
创建了帖子
2001-09-03 08:42
社区公告
暂无公告