疯狂java实战演义第6章 仿Windows画图.docx

上传人:b****4 文档编号:3698734 上传时间:2022-11-24 格式:DOCX 页数:38 大小:198.92KB
下载 相关 举报
疯狂java实战演义第6章 仿Windows画图.docx_第1页
第1页 / 共38页
疯狂java实战演义第6章 仿Windows画图.docx_第2页
第2页 / 共38页
疯狂java实战演义第6章 仿Windows画图.docx_第3页
第3页 / 共38页
疯狂java实战演义第6章 仿Windows画图.docx_第4页
第4页 / 共38页
疯狂java实战演义第6章 仿Windows画图.docx_第5页
第5页 / 共38页
点击查看更多>>
下载资源
资源描述

疯狂java实战演义第6章 仿Windows画图.docx

《疯狂java实战演义第6章 仿Windows画图.docx》由会员分享,可在线阅读,更多相关《疯狂java实战演义第6章 仿Windows画图.docx(38页珍藏版)》请在冰豆网上搜索。

疯狂java实战演义第6章 仿Windows画图.docx

疯狂java实战演义第6章仿Windows画图

第6章仿Windows画图

6.1画图软件概述

我们平时所使用的图形处理工具有PhotoShop、Windows画图工具等,其中PhotoShop是一款非常强大的图形处理工具,Windows画图工具则是一款较为简单的画图工具,功能较为简单,相信经常使用Windows系统的读者都比较熟悉,是一种比较简单与具有代表性的画图工具,虽然功能不够强大,但具有大多图片处理程序所必需的基本功能:

铅笔画图、各种数学函数图形、填色、取色、橡皮擦等等功能。

本文将使用Java语言去实现Windows的大部分功能,包括取色、各种数学函数图形、橡皮擦、喷枪、颜色编辑等功能,除了这些绘图功能,还会实现打开图片、保存图片等文件操作功能。

画图工具的最终效果如图6.1所示。

图6.1画图

6.2画图工具原理

我们可以考虑一下如何使用Java程序去实现这些功能,如果需要进行画图,那么我们当然就需要Graphics类来向界面画上相应的内容,如果需要进行文件操作,我们可以使用Java的IO来实现。

6.2.1画线

在Graphics中许多方法,其中有一个drawLine的方法,使用该方法我们可以将线画到界面中,该方法中有四个参数,分别是线的开始点坐标(x、y)与线的结束点的坐标(x、y),因此,如果需要调用该方法来画线的话,需要捕获用户在界面中按下鼠标的点坐标与放开鼠标时的点坐标。

当调用了drawLine方法后,我们再对界面的组件进行一次repaint就可以实现画线的功能。

6.2.2其他画图功能

画线我们可以调用drawLine方法,那么画椭圆的话可以调用Graphics类的drawOval方法,如果需要画矩形的话,可以调用drawRect方法。

如果需要实现橡皮擦的功能,可以将鼠标经过的区域画上白色的线。

实现喷涂的功能,可以在当前鼠标点击的区域中画上相应的点,Graphics类中提供了一个fillRect的方法,我们可以利用该方法去填充当前的区域。

除这些画图功能外,我们还需要提供一个刷子的功能,刷子功能可以看作是一个画笔功能,只是使用刷子画出来的线比画笔更粗而已。

6.2.3保存图片功能

我们可以在画图的界面中保存一个BufferedImage的对象,那么可以通过这个对象得到一个Graphics对象,得到该对象,就可以使用它的drawXXX的方法来进行画图,到最终需要进行保存的时候,我们可以将这个BufferedImage对象通过ImageIO的writer方法写到文件中。

只要知道使用Java程序来实现画图的原理,实现程序就十分的简单,关键是如何计算各个工具的有效范围。

6.3创建画图工具的各个对象

使用Windows的画图软件,发现在编辑图片的时候,有个相似的过程,首先是用鼠标选择需要使用的工具,然后就在画板中用鼠标进行拖动、点击等动作,画板会显示出相应工具的所产生的效果,所以在这里设计一个命名为Tool的接口,这个接口是所有工具的接口,里面定义了一系列的鼠标动作。

实际上在这个画图工具中,所有的工具都必须遵守一定的规范,即使用鼠标进行拖动、点击等动作,当需要定义某些规范的时候,我们可以将这些规范写到一个接口中,那么这个接口所有的实现类都要遵守这个规范,这也是本章将工具作为一个接口的原因。

在本章中,画图软件的主界面使用ImageFrame,该类继承于JFrame,该类会初始化画图软件的各种组件。

由于我们有选择打开图片文件的操作,所以会有一个扩展javax.swing.JFileChooser类(为选择文件提供一种简单的窗口选择机制)的ImageFileChooser类,用于处理选择文件时的过滤等操作。

因为绘图的功能已经全部由Tool的实现类去实现,所以除了绘图外的其它功能的逻辑实现,就全部放到ImageService类中,本章中的类图如图6.2所示。

图6.2画图软件类图

6.3.1工具接口Tool

从图6.2中可以看到,工具接口Tool定义了鼠标动作的四个方法,分别是拖动mouseDrapped()、移动mouseMoved()、松开mouseReleased()、按下mousePressed()、点击mouseClicked()五个动作,并用String类型的常量属性来定义工具的类型。

这个接口只有一个实现类AbstractTool,而每个工具类都是去扩展AbstractTool类,在图中表现为Tool1、Tool2…….ToolN。

以下是此接口定义的属性与方法:

❑staticfinalStringARROW_TOOL,箭头工具类型。

❑staticfinalStringPENCIL_TOOL,铅笔工具类型。

❑staticfinalStringBRUSH_TOOL,刷子工具类型。

❑staticfinalStringCUT_TOOL,剪切工具类型。

❑staticfinalStringERASER_TOOL,橡皮擦工具类型。

❑staticfinalStringLINE_TOOL,直线工具类型。

❑staticfinalStringRECT_TOOL,矩形工具类型。

❑staticfinalStringPOLYGON_TOOL,多边形工具类型。

❑staticfinalStringROUND_TOOL,椭圆形工具类型。

❑staticfinalStringROUNDRECT_TOOL,圆角矩形工具类型。

❑staticfinalStringATOMIZER_TOOL,喷墨工具类型。

❑staticfinalStringCOLORPICKED_TOOL,颜色选择工具类型。

❑voidmouseDragged(MouseEvente),当捕捉到鼠标拖动时调用的方法定义。

❑voidmouseMovedMouseEvente),当捕捉到鼠标移动时调用的方法定义。

❑voidmouseReleasedMouseEvente),当捕捉到鼠标松开时调用的方法定义。

❑voidmousePressedMouseEvente),当捕捉到鼠标按下时调用的方法定义。

❑voidmouseClickedMouseEvente),当捕捉到鼠标点击时调用的方法定义。

从接口中定义的属性与方法可以看出,在接口中只定义工具的类型,还有定义工具鼠标动作的方法,就不再做任何的事情,这些方法由它的实现类去具体实现。

在某个对象中需要使用到Tool的实现类时,我们可以使用一个ToolFactor的类来得到具体的某个Tool实现类,ToolFactory返回的都是Tool接口,因此使用者根本不需要关心使用的是哪一个实现类,当代码发生改变的时候,也可以减少代码的修改。

换言之,使用者只与ToolFactory耦合。

6.3.2Tool的实现类AbstractTool

AbstractTool是Tool的实现类,也是一个抽像类,所以并不能被创建,只能被继承。

此类实现Tool中定义的所有方法,并扩展了其它方法,让其子类继承或者重写。

该类中为其他的工具类提供了大部分的实现,那么它的子类就可以不必再做重复的实现,只关心与本类相关的逻辑,AbstractTool所定义的方法如下:

❑AbstractTool(ImageFrameframe),让子类调用的构造器,以ImagerFrame为参数,用于获取画板的属性。

❑AbstractTool(ImageFrameframe,Stringpath),让子类调用的构造器,以ImagerFrame为参数,path是工具的图标路径。

❑CursorgetDefaultCursor(),此方法获取默认鼠标指针的形状。

❑voidsetDefaultCursor(Cursorcursor),设置鼠标指针指针,以Cursor为参数。

❑voidsetPressX(intx),设置鼠标按下的x坐标,int类型的x为鼠标的x坐标。

❑voidsetPressY(inty),设置鼠标按下的y坐标,int类型的y为鼠标的y坐标。

❑intgetPressX(),返回上次鼠标按下的x坐标。

❑intgetPressY(),返回上次鼠标按下的y坐标。

❑voidmouseDragged(MouseEvente),实现当捕捉到鼠标拖动时调用的方法。

❑voidmouseMovedMouseEvente),实现当捕捉到鼠标移动时调用的方法。

❑voidmouseReleasedMouseEvente),实现当捕捉到鼠标松开时调用的方法。

❑voidmousePressedMouseEvente),实现当捕捉到鼠标按下时调用的方法。

❑voidmouseClickedMouseEvente),实现当捕捉到鼠标点击时调用的方法。

❑voidcreateShape(MouseEvente,Graphicsg),画图形,通过参数e去获取鼠标的轨迹,并用Graphics类型的对象g去画图形。

❑voiddraw(Graphicsg,intx1,inty1,intx2,inty2),画图形,g是用来画图形的对象,(x1,y1)是起点坐标,(x2,y2)是终点坐标。

这个方法是一个空的方法,主要是由其子类实现。

❑voiddragBorder(MouseEvente),拖动边界,也就是改变画布的大小。

接口用于定义规范,那么抽象类就是用于实现部分的规范。

当我们在编写程序的过程中发现,有一类对象都必须遵守某些行为,那么我们可以将这些行为都当作规范,写到接口中;如果有些对象实现了部分的行为,其他的行为更希望让它的子类去实现,那么我们可以将这些对象作为一个抽象类。

6.3.3AbstractTool的子类

AbstractTool一共有ArrowTool(箭头)、PencilTool(铅笔)、BrushTool(刷子)、EraserTool(橡皮擦)、LineTool(直线)、RectTool(矩形)、PolygonTool(多边形)、RoundTool(椭圆形)、RoundRectTool(圆矩形)、AtomizerTool(喷墨)、ColorPickedTool(颜色选择)11个子类,这些子类都是根据自己的情况重写AbstractTool的部分或者全部方法。

由于在本设计中,想这些类在外表现为Tool接口,不希望被直接实例化,所以此类的构造器私有,并提供一个静态的方法获取Tool类型的此类实现,如下:

❑staticToolgetInstance(ImageFrameframe),获取Tool类型的本类实例。

由于我们并不希望外界可以直接使用new关键字来创建这些类的实例,因此在这里使用了单态模式,所有的子类都提供了getInstance的方法来返回本类的实例,并且所有的构造器都是私有的。

在下面的章节中,将会讲解如何实现这11个子类。

6.3.4界面类ImageFrame

这个画图工具的界面的主要放在这个类中实现,此类有以下方法:

❑voidinit(),设置化主界面。

❑JPanelgetDrawSpace(),获取画布。

❑JPanelgetColorPanel(),获取颜色面板。

❑MyImagegetBufferedImage(),获取画板中的图片。

❑voidsetBufferedImage(MyImagebufferedImage),设置画板图片,MyImage是BufferedImage的一个扩展类。

❑voidsetTool(Tooltool),设置正在使用的工具。

❑ToolgetTool(),获取正在使用的工具。

❑JColorChoosergetColorChooser(),获取颜色选择器。

❑JPanelcreateColorPanel(),创建一个简单的颜色选择面板。

❑JPanelgetCurrentColorPanel(),获取颜色选择面板。

❑DimensiongetScreenSize(),获取Dimension类形screenSize,screenSize主要用于获取画板的高与宽等属性。

❑voidcreateMenuBar(),创建文件、查看、颜色、帮助等菜单栏。

❑JPanelcreateDrawSpace(),创建画板。

❑JPanelcreateToolPanel(),创建用于画图的工具栏。

另外,此类有一个继承JPanel的内部类DrawSpace,用于充当画图工具的画板,此内部类只有一个方法,就是一个用于绘图的方法,如下:

❑voidpaint(Graphicsg),画图。

界面类类似于我们MVC模式中的V(视图),该类并不负责处理任何的逻辑,主要负责从界面接收数据,再传递给具体的业务类,让其进行相关的处理。

在本章,负责处理画图功能的主要是Tool的实现类。

6.3.5业务逻辑类ImageService

除鼠标的画图功能外(画图功能由Tool的实现类完成),初始化画板、图片的新建打开与保存、各种面板的显示与隐藏、颜色的编辑、整个界面的刷新、菜单等业务逻辑都放在这个类中实现,该类包含了以下的方法:

❑initDrawSpace(ImageFrameframe),初始化画板。

❑DimensiongetScreenSize(),获取屏幕的分辨率。

❑repaint(Graphicsg,BufferedImagebufferedImage),刷新界面。

❑staticCursorcreateCursor(Stringpath),创建鼠标图形。

Path是鼠标图形的路径。

❑voidsave(booleanb,ImageFrameframe),保存图片。

❑voidopen(ImageFrameframe),打开图片。

❑voidcreateGraphics(ImageFrameframe),创建新图片并初始化。

❑voideditColor(ImageFrameframe),编辑颜色。

❑voidexit(ImageFrameframe),退出画图软件。

❑voidmenuDo(ImageFrameframe,Stringcmd),处理菜单事件。

除了画图功能外,ImageService负责了整个画图工具的其他功能,在本章中,该类是无状态的Java对象,它并没有保存一些状态属性。

6.3.6文件选择类ImageFileChooser

ImageFileChooser类继承了JFleChooser类,JFleChooser是Java提供的一个简单的文件选择机制,我们这里扩展这个类,是为了增加我们自己的文件过滤器。

见以下方法:

❑StringgetSuf(),获取文件的后缀名。

❑voidaddFilter(),增加文件过滤器,这里只选择图片类形的文件。

这个类中有一个继承FileFilter类的内部类MyFileFilter,这个内部类主要是重写FileFilter的accept方法,判断是否是合法的文件类型,如下:

❑booleanaccept(Filef),判断是否是合法的文件类型。

在本小节中,我们主要确定了画图工具所涉及的几个对象,并定义了他们的行为与属性,在下面章节中,我们只要按照这些定义好的方法,逐步去实现我们的画图工具。

6.4主界面实现

在这个软件中,主界面主要由左边的工具栏、下面的颜色选择板、占大部分区域的画图区、菜单等几部分组成,用BorderLayou的排板方式,左边工具栏在BorderLayou.WEST位置,画图区在BorderLayout.CENTER位置,颜色选择面板在BorderLayout.SOUTH位置。

先看主界面的初始化:

6.4.1初始化界面(init()方法)

首先,设置JFrame窗口的标题,接下来初始化画图区域,初始化为白色,然后再获取PENCIL_TOOL(铅笔)类型的Tool,创建各种鼠标监听器,并在监听的执行方法中调用Tool的相应方法,最后获取左边工具栏面板、下面菜单栏面板、菜单,并把这些面板与画图获取加到JFrame中。

见以下代码。

代码清单:

code\image\src\org\crazyit\image\ImageFrame.java

publicvoidinit(){

//设置标题

this.setTitle("未命名-画图");

//初始化画图

service.initDrawSpace(this);

//设置标题

//获取正在使用的工具

tool=ToolFactory.getToolInstance(this,PENCIL_TOOL);

//创建鼠标运动监听器

MouseMotionListenermotionListener=newMouseMotionAdapter(){

//拖动鼠标

publicvoidmouseDragged(MouseEvente){

tool.mouseDragged(e);

}

//移动鼠标

publicvoidmouseMoved(MouseEvente){

tool.mouseMoved(e);

}

};

//创建鼠标监听器

MouseListenermouseListener=newMouseAdapter(){

//松开鼠标

publicvoidmouseReleased(MouseEvente){

tool.mouseReleased(e);

}

//按下鼠标

publicvoidmousePressed(MouseEvente){

tool.mousePressed(e);

}

//点击鼠标

publicvoidmouseClicked(MouseEvente){

tool.mouseClicked(e);

}

};

drawSpace.addMouseMotionListener(motionListener);

drawSpace.addMouseListener(mouseListener);

createMenuBar();

//以drawSpace为viewport去创建一个JScrollPane

scroll=newJScrollPane(drawSpace);

//设置viewport

ImageService.setViewport(scroll,drawSpace

bufferedImage.getWidth(),bufferedImage.getHeight());

//将panel加到本Frame上面

this.add(scroll,BorderLayout.CENTER);

//this.add(toolPanel,BorderLayout.WEST);

//this.add(colorPanel,BorderLayout.SOUTH);

}

可以看到,这里有两种鼠标监听器,MouseMotionListener和MouseListener,MouseMotionListener主要是监听鼠标的运动动作,我们实现了它的mouseDragger(鼠标拖动)与mouseMoved(鼠标移动)方法,MouseListener负责监听鼠标的其它动作,我们实现了它的mouseReleased(松开鼠标)、mousePressed(按下鼠标)和mouseClicked(点击鼠标)三个方法。

以上代码的黑体部分,这三行代码分别创建菜单、画图工具栏与颜色选择面板,如何创建我们将在6.4.3、6.4.4和6.4.5中详细描述。

现在运行画图工具,可以看到效果如图6.3所示。

图6.3主界面

6.4.2获取画板

这是一个画图工具,所以需要一个可以绘图的区域,在这里我们用继承JPanel的内部类DrawSpace去充当这个绘图区域,见以下代码。

代码清单:

code\image\src\org\crazyit\image\ImageFrame.java

//画图区域

publicclassDrawSpaceextendsJPanel{

/**

*重写voidpaint(Graphicsg)方法

*

*@paramgGraphics

*@returnvoid

*/

publicvoidpaint(Graphicsg){

//draw

service.repaint(g,bufferedImage);

}

}

从上面代码可以看到,这个内部类比较简单,只是继承JPanel,并重写JPanel的paint方法,这里需要注意的是,要调用此方法,并不是直接调用paint方法,而是调用ImageService的repaint方法。

而获取这个画板就是去创建一个这个画板类的实例,由于我们的画图软件是每次都只编辑一张图片,所以这个创建画板的方法在本类中只被调用一次。

首先是new一个DrawSpace实例,再设置这个drwaSpace的大小,并且返回,见以下代码。

代码清单:

code\image\src\org\crazyit\image\ImageFrame.java

//创建画板

publicJPanelcreateDrawSpace(){

JPaneldrawSpace=newDrawSpace();

//设置drawSpace的大小

drawSpace.setPreferredSize(

newDimension((int)screenSize.getWidth()

(int)screenSize.getHeight()-150));

returndrawSpace;

}

6.4.3创建菜单

这个软件的菜单组织形式如下:

-文件(F)

-新建(N)

-打开(O)

-保存(S)

-退出(X)

-查看(V)

-工具箱(T)

-颜料盒(C)

-颜色(C)

编辑颜色

-帮助(H)

-帮助主题

-关于

由于菜单比较简单,我们把文件、查看、颜色、帮助四个菜单文字放在一个String类型的数组menuArr里面,并迭代这个数组去创建一个JMenu,JMenu就是指菜单。

同样,把他们下面的各个菜单项文字也放在一个String类型的二维数组里面,去迭代创建每个JmenuItem(菜单项),每创建完一个,就为它加上一个动作监听器,去监听这个菜单项是否被点击。

请看以下代码。

代码清单:

code\image\src\org\crazyit\image\ImageFrame.java

//创建菜单

publicvoidcre

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1