首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 网络编程-> JSP教程
一个Jsp初学者的学习过程(六)-JSP教程,Jsp/Servlet
作者:网友供稿 点击:16
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
一个jsp初学者的学习过程(六)

theunforgiven


第六章 画柱状统计图

在编码学习的过程中,我发现的问题越来越多了,有java方面的,sql方面的,html方面的,javascript方面的等等,对这些看似细小的问题的研究使我积累了实战的经验,起码不只是纸上谈兵了。
这个时候我的领导让我做一个东西,实现局域网内部网上计算机故障报修。这其实就是一个留言板的功能,我正好之前做过练习,所以很轻松的就做好了。之后我想我也许应该做一个统计——统计一年内每个月完成的报修任务量,如果用表格显示的话太简单了,不如做一个动态生成的柱状图吧,我突然有了这个想法。
马上开始动手,先是查资料,知道了java里和画图有关的是java.awt包,由于我构想的图只是由矩形组成,那么用到的方法也就这么几个:fillrect,drawrect,setcolor,setfont,drawstring。我很快发现一个问题:如何在页面显示这个图,这是个大问题,于是找例子。
在一个学过研究生java课程的同事的帮助下知道可以这样:写一个类(picture.class),这个类只负责画图,没有任何关于如何显示的语句,然后在一个页面文件(.htm文件就行)里<body>里写上这段代码:<applet code="picture" height="400" width="400"></applet>,运行这个文件就可以了。但是这个方法有这两个弊端:1、它是直接从服务器端下载picture.class,在客户端生成图片,所以客户端必须装有java环境,比如j2re等;2、现在大部分浏览器都或者迫于无奈或者被强行绑架(这里我严重鄙视一下3721和一个叫“天下搜索”的)安装了阻止小窗口、activex控件的插件——就连xp的sp2也集成了这个功能——而这个功能同样对<applet>有效。
放弃第一种方法后我在网上找到了第二个例子,第二个例子让我很奇怪,代码直接写在一个.jsp文件里,打开文件显示图片,一看这个图片的属性竟然就是这个.jsp文件的名。看了一阵子代码发现不是很理解,我开始看第三个例子。
第三个例子符合我的思维:写一个bean(或者说是一个类),把一个代表路径的字符串和一些数据传给它,它根据数据画图但是不返回(从这一点来说它不能叫做bean),而是生成一个如.jpg文件并按照传进来的路径名进行保存。然后显页面通过<img src="……">显示图片。我通过这种方式实现了工作,下面是这个类的代码:
----------------------------------picture.java------------------------------------
//该bean用于画柱状统计图
package ringz.javabeans;
import java.io.*;
import java.util.*;
import com.sun.image.codec.jpeg.*;
import java.awt.image.*;
import java.awt.*;

public class picturebean
{
bufferedimage image;
private string filelocation;

public void setfilelocation(string filelocation)//filelocation是图片的路径,如:“d:\\a\\b\\c.jpg”
{
this.filelocation=filelocation;
}

public void createimage(string filelocation)
{
try
{
fileoutputstream fos = new fileoutputstream(filelocation);
bufferedoutputstream bos = new bufferedoutputstream(fos);
jpegimageencoder encoder = jpegcodec.createjpegencoder(bos);
encoder.encode(image);
bos.close();
}
catch(exception e)
{
e.printstacktrace();
}
}

public void outgraphic(string titles,string sstr,string str[],int datas[])
{
string title=titles;
string sstr=sstr;

int imagewidth = 400;//图片的宽度 line
int imageheight;//不定长

int framefirstwidth=imagewidth-10;
int framefirstheight=25;

int framesecondwidth=imagewidth-10;
int framesecondheight;//不定长

int framespace=10;//两框间隔

int columnheight=18;//柱的粗
int columnmaxwidth=framesecondwidth-20;//柱的最大长度,也是代表数值最大的那个柱的长度

int sp=30;//柱的间隔

int num=datas.length;//数组的长度
int datas[]=new int[num];//得到数组的数值
string name[]=new string[num];
for (int i=0;i<num;i++)
{
datas[i]=datas[i];
name[i]=str[i];
}

//得此数组中的最大值
int max=datas[0];
for (int j=0;j<num;j++)
{
if(datas[j]>max)
max=datas[j];
}

//得到代表数值的柱的各自高度,实际数值*columnmaxheight/max
int columnwidth[]=new int[num];//不定长,柱的长度
for (int k=0;k<num;k++)
columnwidth[k]=(datas[k]*columnmaxwidth)/max;//取整

framesecondheight=(sp+columnheight)*num+10;//+10为了留出一块底边
imageheight=framesecondheight+framefirstheight+framespace+10;//多加10为了画阴影

picturebean chartgraphics = new picturebean();
chartgraphics.image = new bufferedimage(imagewidth, imageheight, bufferedimage.type_int_rgb);
graphics g = chartgraphics.image.getgraphics();
g.setcolor(color.white);
g.fillrect(0,0,imagewidth,imageheight);//用白色涂整个图
color framefirstcolor = new color(20,50,100);
color columncolor = new color(153,19,19);
color shadowcolor = new color(200,200,200);
g.setcolor(shadowcolor);
g.fillrect(0+7,0+7,framefirstwidth,framefirstheight);//阴影在原框基础上移7
g.setcolor(color.white);
g.drawrect(0,0,framefirstwidth,framefirstheight);//画第一个框
g.setcolor(framefirstcolor);
g.fillrect(0+1,0+1,framefirstwidth-1,framefirstheight-1);
g.setfont(new font("仿体", 0 , 14));
g.setcolor(color.white);
g.drawstring(title,10,18);//写字
g.drawstring(sstr,300,18);

int framesecondy=1+framefirstheight+framespace;
g.setcolor(shadowcolor);
g.fillrect(0+7,framesecondy+7,framesecondwidth,framesecondheight);//阴影在原框基础上移7
g.setcolor(color.black);
g.drawrect(0,framesecondy,framesecondwidth,framesecondheight);//画第二个框
g.setcolor(color.yellow);
g.fillrect(0+1,framesecondy+1,framesecondwidth-1,framesecondheight-1);//填充第二个框

for(int l=0;l<num;l++)
{
g.setcolor(color.black);
int texty=framesecondy+20+(sp+columnheight)*l;
g.drawstring(name[l]+"("+datas[l]+")",0+10,texty);//写文字
if (columnwidth[l]!=0)
{
g.setcolor(columncolor);
g.drawrect(10,texty+5,columnwidth[l],columnheight);//画柱的外框//框的上边离文字的底边为5
g.fillrect(10+2,texty+5+2,columnwidth[l]-3,columnheight-3);//画柱
}
}
chartgraphics.createimage(filelocation);
}
}
--------------------------------------------------------------------------------
但是接下来出现了一个让我难以忍受的事:自做聪明的浏览器缓存使得页面无法在短时间内更新图片——输入2004,显示了2004的图片,马上再输入2005,可是显示的仍然是2004的图片,但这时硬盘目录下的图片已经是2005的图片了,一般来说两次操作时间间隔大约少于3秒,则总是显示缓存里的那张图。这个问题困扰我很长时间,问了很多人试了很多方法都没有解决了。
很显然上面提到的第二个方法不存在此问题,我决定采用这种方法,所以我不得不回头研究它的代码,之后我发现这几句代码是显示图片的关键,而最下面的三句是和显示图有关的:
---------------------------------------------------------
response.setcontenttype("image/jpeg");
bufferedimage bi = new bufferedimage(width, height, bufferedimage.type_int_rgb);
graphics2d bicontext = bi.creategraphics();

……

outputstream output = response.getoutputstream();
jpegimageencoder encoder = jpegcodec.createjpegencoder(output);
encoder.encode(bi);
---------------------------------------------------------
我手头仅有一本电子版的《java2参考大全》,而令我苦恼的是在里边我竟然找不到bufferedimage、graphics2d、jpegimageencoder这些字样;另外,上一个例子里是graphics,它和graphics2d有什么差别呢?这也让我很困惑。但是我终于决定要试一试,把两个例子综合一下,最终得到了下面这个worklord.jsp文件:
-----------------------------------worklord.jsp----------------------------------
<%@ include file="include.inc"%>
<%@ page contenttype="text/html;charset=gb2312"%>
<%@ page import="java.io.outputstream" %>
<%@ page import="java.util.*"%>
<%@ page import="java.awt.image.bufferedimage" %>
<%@ page import="java.awt.*" %>
<%@ page import="com.sun.image.codec.jpeg.*" %>
<!doctype html public "-//w3c//dtd html 4.01 transitional//en" "http://www.w3.org/tr/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=gb2312">
<title>工作量统计</title>
<style type="text/css">
<!--
body {
margin-left: 10%;
margin-right: 10%;
}
.style2 {font-size: 24px}
-->
</style></head>

<body>
<%
//得到当前的年
java.text.simpledateformat formatter = new java.text.simpledateformat("yyyy");
java.util.date currenttime_1 = new java.util.date();//得到当前系统时间
string yearnow = formatter.format(currenttime_1);

string year=null;
try
{
year=request.getparameter("select");
}
catch(exception e){}

if (year==null)
year=yearnow;

//string y=integer.tostring(year);
int sum=0;
string mon[]=new string[12];
mon[0]=year+"-01";
mon[1]=year+"-02";
mon[2]=year+"-03";
mon[3]=year+"-04";
mon[4]=year+"-05";
mon[5]=year+"-06";
mon[6]=year+"-07";
mon[7]=year+"-08";
mon[8]=year+"-09";
mon[9]=year+"-10";
mon[10]=year+"-11";
mon[11]=year+"-12";

int datas[]=new int[12];

connection con = null;
statement stmt = null;
resultset rs = null;
try
{
class.forname(classforname);//载入驱动程式类别
con=drivermanager.getconnection(servanddb);//建立数据库连接
stmt=con.createstatement();
string sql="select count(*) from record where com_time like "+year+"%"+"";
rs=stmt.executequery(sql);
if (rs.next())
sum=rs.getint("count(*)");
for (int i=0;i<12;i++)
{
sql="select count(*) from record where com_time like "+mon[i]+"%"+"";
rs=stmt.executequery(sql);
if (rs.next())
datas[i]=rs.getint("count(*)");
else
datas[i]=0;
}
rs.close();
stmt.close();
con.close();
}
catch(exception e)
{
out.print(e);
}
if (sum!=0)
{
string title=year+"年度工作量统计图";
string sstr="总和:"+sum;
string name[]={"一月份","二月份","三月份","四月份","五月份","六月份","七月份","八月份","九月份","十月份","十一月份","十二月份"};

int num=datas.length;//数组的长度
//得此数组中的最大值
int max=datas[0];
for (int j=0;j<num;j++)
{
if(datas[j]>max)
max=datas[j];
}

int imagewidth = 400;//图片的宽度 line
int imageheight;//不定长

int framefirstwidth=imagewidth-10;
int framefirstheight=25;

int framesecondwidth=imagewidth-10;
int framesecondheight;//不定长

int framespace=10;//两框间隔

int columnheight=18;//柱的粗
int columnmaxwidth=framesecondwidth-20;//柱的最大长度,也是代表数值最大的那个柱的长度

int sp=30;//柱的间隔

//得到代表数值的柱的各自高度,实际数值*columnmaxheight/max
int columnwidth[]=new int[num];//不定长,柱的长度
for (int k=0;k<num;k++)
columnwidth[k]=(datas[k]*columnmaxwidth)/max;//取整

framesecondheight=(sp+columnheight)*num+10;//+10为了留出一块底边
imageheight=framesecondheight+framefirstheight+framespace+10;//多加10为了画阴影

//开始画图
response.setcontenttype("image/jpeg");
bufferedimage image = new bufferedimage(imagewidth,imageheight,bufferedimage.type_int_rgb);
graphics g = image.creategraphics();

g.setcolor(color.white);
g.fillrect(0,0,imagewidth,imageheight);//用白色涂整个图
color framefirstcolor = new color(20,50,100);
color columncolor = new color(153,19,19);
color shadowcolor = new color(200,200,200);
g.setcolor(shadowcolor);
g.fillrect(0+7,0+7,framefirstwidth,framefirstheight);//阴影在原框基础上移7
g.setcolor(color.white);
g.drawrect(0,0,framefirstwidth,framefirstheight);//画第一个框
g.setcolor(framefirstcolor);
g.fillrect(0+1,0+1,framefirstwidth-1,framefirstheight-1);
g.setfont(new font("仿体", 0 , 14));
g.setcolor(color.white);
g.drawstring(title,10,18);//写字
g.drawstring(sstr,300,18);

int framesecondy=1+framefirstheight+framespace;
g.setcolor(shadowcolor);
g.fillrect(0+7,framesecondy+7,framesecondwidth,framesecondheight);//阴影在原框基础上移7
g.setcolor(color.black);
g.drawrect(0,framesecondy,framesecondwidth,framesecondheight);//画第二个框
g.setcolor(color.yellow);
g.fillrect(0+1,framesecondy+1,framesecondwidth-1,framesecondheight-1);//填充第二个框

for(int l=0;l<num;l++)
{
g.setcolor(color.black);
int texty=framesecondy+20+(sp+columnheight)*l;
g.drawstring(name[l]+"("+datas[l]+")",0+10,texty);//写文字
if (columnwidth[l]!=0)
{
g.setcolor(columncolor);
g.drawrect(10,texty+5,columnwidth[l],columnheight);//画柱的外框//框的上边离文字的底边为5
g.fillrect(10+2,texty+5+2,columnwidth[l]-3,columnheight-3);//画柱
}
}
try
{
//输出图
outputstream output = response.getoutputstream();
jpegimageencoder encoder = jpegcodec.createjpegencoder(output);
encoder.encode(image);
output.close();
}
catch(exception e)
{
e.printstacktrace();
}
}//if
else
{%>
<table width="100%">
<tr>
<td width="407">
<span class="style2"><font color="#ff0000">没有<%=year%>年的记录!</font></span>
</td>
</tr>
</table>
<%
}
%>
</body>
</html>
----------------------------------------------------------------------------------
现在任务是完成了,其中的最关键的部分代码是实现什么功能的也大概知道了,可是还是没有掌握其中的知识,不能不说是遗憾。

另外,worklord.jsp这样的页面很特殊,就是因为这部分代码引起的:
outputstream output = response.getoutputstream();
jpegimageencoder encoder = jpegcodec.createjpegencoder(output);
encoder.encode(image);
这导致了这个页面没法再干别的了,也就是说,假如你要在<body>里干点别的,像写几个字,放一个<form>什么的,页面显示不出来。

本章最后,感谢那两个例子的作者,而且图的风格都是抄袭第二个例子那位仁兄的:),但是没有记住你们的名字很遗憾。


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·利用 Java Web Start发布你用java程序-JSP教程,Java技巧及代码
·用正则表达式得到网页上的链接-.NET教程,评论及其它
·MSMQ,Enterprise Service, DotNet Remoting,Web Service 的优缺点-.NET教程,Web Service开发
·用vb编一个计算器,需要用到数组,看看下面的代码,欢迎来找碴!-.NET教程,VB.Net语言
·jsp页面中的下载功能实现-JSP教程,Jsp/Servlet
·利用Java 创建和读取Excel文档-JSP教程,Java技巧及代码
·JSP语法(8)——<jsp:forward>-JSP教程,Jsp/Servlet
·Hibernate 配置!-JSP教程,资料/其它
·java、J2EE基础问题汇总-JSP教程,Java技巧及代码
·Java手机程序设计入门 电子书开放下载(转自CSDN)-JSP教程,J2ME开发
最新文章
·photoshop制作重彩风格非主流照片效果_photoshop教程
·google补充材料没消失,内链优化很重要_seo网站优化
·个人网站建设到底怎样赚钱_网赚技巧
·英文垃圾站全功略ip日100月赚50刀_网赚技巧
·清客讲网赚思路_网赚技巧
·windear与渡虎谷密谋_站长访谈
·口碑网ceo李治国专访:独特的平衡之道_站长访谈
·密密麻麻圈网邵晨:我从“互动”中赚钱_站长访谈
·蔡文胜:站长的乐趣是享受建站的过程_站长访谈
·“鹰”之路—访著名linux内核程序员大鹰_站长访谈
相关主题
  • 一个Jsp初学者的学习过程(八)-JSP教程,Jsp/Servlet
  • 一个Jsp初学者的学习过程(七)-JSP教程,Jsp/Servlet
  • 一个Jsp初学者的学习过程(五)-JSP教程,Jsp/Servlet
  • 一个Jsp初学者的学习过程(四)-JSP教程,Jsp/Servlet
  • 一个Jsp初学者的学习过程(三)-JSP教程,Jsp/Servlet
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭