版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、目 录1 课题介绍11.1 课程设计目的11.2 课程设计要求11.3 课程设计主要知识点12 总体设计22.1 画板界面设计图22.2 模块概述22.2.1 文件操作22.2.2 图形绘制23 详细设计与实现43.1 框架类DrawGraphic43.1.1菜单43.1.2工具栏63.1.3画图区域73.2 基本图形类103.2.1 父类Drawings103.2.2 子类(只列出部分)104 设计中的难点124.1多态与动态绑定124.2重绘的理解124.3文件的新建、打开和保存125 运行测试136 总结15参考文献16模拟画图161 课题介绍1.1 课程设计目的课程设计题目:模拟画图要
2、求设计一个程序,模拟Windows中的画图程序,实现图形图像的编辑,修改,保存等功能。1.2 课程设计要求(1)程序中必须包括“新建”、“打开”、“保存”,用户可以选择,实现对文件的操作;(2) 画图板的绘图按钮用来画出不同的图形,包括实心图形和空心的图形;(3)可以对线条的颜色和粗细进行设置,也可以对填充图形的颜色进行设置和更改。1.3 课程设计主要知识点(1) 框架类DrawGraphic继承了Swing类库中JFrame,并且用到JButton,JLabel,JPanel,等Swing类库中的组件进行窗体设计;(2)选择一个文件,用到组件JFileChooser;(3)选择颜色,用到组件
3、JColorChooser;(4)弹出标准对话框,用到组件JOptionPane;(5)在单击绘图按钮时,所触发的动作通过方法addActionListener和ActionListener接口的actionPerformed方法共同实现;(6)MouseAdapter和MouseMotionAdapter用来完成鼠标各种事件的相应操作,包括单击、移动、拖拽等;(7)在界面设计的时候结合BorderLayout和GridLayout两种布局格式;(8)在添加监听器的时候有用到内部匿名类和内部类,所以要熟悉它们的构造方法和使用方法,从中体会持有对方引用的这一设计思想。(9)在图形绘制的时候,用到
4、Graphics类,其揭示了所有图形系统几乎都采用的一种机制,就是如何在窗口上画出一些图形来,当窗口构造出来的时候里面有一支画笔,即Graphics的一个对象,当窗口调用paint方法的时候,系统会把画笔自动传递给它,拿到画笔,重写paint方法就实现了在窗口上绘制基本图形。2 总体设计2.1 画板界面设计图定义框架类DrawGraphic,然后在框架上直接添加菜单栏,整个框架采用 BorderLayout的布局格式。工具栏、显示鼠标位置的标签、主要的画图区域分别在框架的west,south,center三块区域。而浮动式工具栏采用的是GridLayout布局格式,其初始方向设定为VERTIC
5、AL,如下图所示:2.2 模块概述2.2.1 文件操作文件的新建,打开,保存可以添加内部匿名类的方式实现,new一个事件监听器ActionListener,里面调用actionPerformed的方法,被监听的按钮一旦被触发就调用函数执行相应的操作。2.2.2 图形绘制在工具栏里面实现了基本图形的绘制,图形属性的设置,如画笔粗细和画笔颜色的设置,以及橡皮擦,文字输入等功能,而这些功能的实现都是通过添加内部事件监听器类来实现的。一个类用来监听绘制基本图形以及橡皮擦按钮;另一个类用来监听的是选择颜色按钮、选择画笔粗细按钮、和输入文字按钮,里面都用if语句和e.getSource来判断事件源,从而在
6、触发时,调用不同的函数,当事件源为输入文字时,用JOptionPane.showMessageDialog来弹出一个提示操作的对话框。画图区域的功能主要是通过添加鼠标监听器来实现的:一个鼠标监听器监听的是:单击鼠标,释放鼠标,鼠标进入绘图区域,鼠标离开绘图区域这四个鼠标的动作事件;另一个监听的是:鼠标拖拽和鼠标移动。而且,两个监听器之间是存在着密不可分的关系的,它们同时监听画图区域。铅笔作画和橡皮擦的使用是画图板设计的核心也是难点,而且两者的实现原理是一样的,我们通常画图的时候,一定是先单击鼠标然后拖拽鼠标最后释放鼠标的,所以,在画图的过程中,只要鼠标单击一下就获得(x1,y1),紧接着用if
7、语句判断画的基本图形是哪一个,如果是铅笔或者橡皮擦,则获得(x2,y2),说明在铅笔或橡皮擦的时候,鼠标单击一下,就获得一个点,x1=x2,y1=y2,且这个点的坐标就是鼠标单击的位置,而且这个点是算作第一个基本图形的,此时index=1;拖拽的过程中动态获得鼠标所在位置的横纵坐标且始终x1=x2,y1=y2,并且等于第一个基本图形也就是index=1的那个点的x2,y2,即,在铅笔作画的过程中,在鼠标不断拖拽的过程中,index=1时的那个点在以点的点的长度不断增加,这就是铅笔作画过程的实现;鼠标释放的时候,在铅笔或橡皮的状态下,也是得到一个点。所以,可以总结,铅笔和橡皮都是通过设置画直线方
8、法中的点的坐标相等来实现的。其它图形的绘制,可以直接调用Graphics2D中的方法实现,相对比较简单。3 详细设计与实现3.1 框架类DrawGraphic3.1.1菜单菜单栏有两个按钮“画图板”、“帮助”,通过添加内部匿名类来实现,一旦下拉菜单中的“新建”、“打开”、“保存”、“退出”四个键被触发,就调用相关的函数,具体代码如下:(1)“新建”执行时,调用的函数代码如下:public void newFile()index = 0;currentChoice = 3;color = Color.BLUE;stroke = 1.0f;createNewItem();repaint();(2)
9、“打开”执行时,调用的函数代码如下:public void openFile()JFileChooser fileChooser = new JFileChooser();/为用户选择文件提供了一种简单的机制fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);int result = fileChooser.showOpenDialog(this);/弹出一个 "Open File" 文件选择器对话框,父组件if(result = JFileChooser.CANCEL_OPTION) return;File
10、fileName = fileChooser.getSelectedFile();fileName.canRead();/测试应用程序是否可以读取此抽象路径名表示的文件if(fileName = null|fileName.getName().equals("")JOptionPane.showMessageDialog(fileChooser, "这个名字不可以用的"," ",JOptionPane.ERROR_MESSAGE);elsetryFileInputStream fis = new FileInputStream(fil
11、eName);input = new ObjectInputStream(fis);int countNumber=0;countNumber = input.readInt();for(index=0;index<countNumber;index+)Drawings inputRecord = (Drawings)input.readObject();itemListindex = inputRecord;createNewItem();input.close();repaint();catch(EOFException endofFileException)/当输入过程中意外到达文
12、件或流的末尾时,抛出此异常JOptionPane.showMessageDialog(this, "no more record in file","end of file",JOptionPane.ERROR_MESSAGE);catch(ClassNotFoundException classNotFoundException)JOptionPane.showMessageDialog(this, "unable to create object","class not found",JOptionPane.E
13、RROR_MESSAGE);catch(IOException ioException)JOptionPane.showMessageDialog(this, "error during read from file","read error",JOptionPane.ERROR_MESSAGE);(3)“保存”执行时,调用的代码如下:public void saveFile()JFileChooser fileChooser = new JFileChooser();fileChooser.setFileSelectionMode(JFileChoos
14、er.FILES_ONLY);/允许用户只选择文件int result = fileChooser.showSaveDialog(this);/弹出一个 "Save File" 文件选择器对话框if(result = JFileChooser.CANCEL_OPTION) return;File fileName = fileChooser.getSelectedFile();fileName.canWrite();if(fileName = null|fileName.getName().equals("")JOptionPane.showMessag
15、eDialog(fileChooser, "这个名字不可以用的"," ",JOptionPane.ERROR_MESSAGE);elsetryfileName.delete();FileOutputStream fos = new FileOutputStream(fileName);output = new ObjectOutputStream(fos);output.writeInt(index);/写入一个32位的int值for(int i= 0;i<index;i+)Drawings outputRecord = itemListi;out
16、put.writeObject(outputRecord);/将指定的对象写入 ObjectOutputStreamoutput.flush();/此操作将写入所有已缓冲的输出字节,并将它们刷新到底层流中output.close();fos.close();catch(IOException ioe)ioe.printStackTrace();3.1.2工具栏工具栏按钮功能的实现,是通过添加两个内部事件监听类ButtonHandler1、ButtonHandler2来达到目的的。(1)ButtonHandler1监听绘制基本图形的按钮,if语句判断事件源,具体代码如下:public class
17、 ButtonHandler1 implements ActionListenerpublic void actionPerformed(ActionEvent e)for(int j=3;j<choices.length-3;j+)if(e.getSource()=choicesj)currentChoice = j;createNewItem();repaint();(2)ButtonHandler2监听颜色选色器、画笔粗细、添加文字按钮,if语句判断事件源,相应的按钮被触发,就执行相应的函数,具体代码如下:public class ButtonHandler2 implements
18、 ActionListenerpublic void actionPerformed(ActionEvent e)if(e.getSource()=choiceschoices.length-3)chooseColor();if(e.getSource()=choiceschoices.length-2)setStroke();icon = new ImageIcon(getClass().getResource("/images/smile.png");if(e.getSource()=choiceschoices.length-1)JOptionPane.showMes
19、sageDialog(null, "想在哪里添加文字呢?鼠标先点一下那里吧!"," ",JOptionPane.INFORMATION_MESSAGE,icon);currentChoice = 14;createNewItem();repaint();3.1.3画图区域(1)createNewItem()用来new各种基本图形,在函数的一开始,我设置了一下光标的样子,然后用switch函数接收currentChoice来判断用户要new的是哪一个基本图形,关键代码如下:void createNewItem()if(currentChoice = 14)
20、drawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR);elsedrawingArea.setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR);switch(currentChoice)case 3:itemListindex = new Pencil();break;case 4:itemListindex = new Line();break;case 5:itemListindex = new Rect();break;case 6:ite
21、mListindex = new fillRect();break;case 7:itemListindex = new Oval();break;case 8:itemListindex = new fillOval();break;case 9:itemListindex = new Circle();break;case 10:itemListindex = new fillCircle();break;case 11:itemListindex = new RoundRect();break;case 12:itemListindex = new fillRoundRect();bre
22、ak;case 13:itemListindex = new Rubber();break;case 14:itemListindex = new Word();break;itemListindex.type = currentChoice;itemListindex.R = R;itemListindex.G = G;itemListindex.B = B;itemListindex.stroke = stroke;(2)chooseColor()用来选择各种颜色,具体代码如下:public void chooseColor()color = JColorChooser.showDialo
23、g(null, "在这里选择自己喜欢的颜色", color);R = color.getRed();G = color.getGreen();B = color.getBlue();(3)setStroke()用来设置画笔粗细,具体代码如下:public void setStroke()String input;input = JOptionPane.showInputDialog(null,"在这里重新输入画笔的粗细值(一个0的实数)","1.0");stroke = Float.parseFloat(input); /将字符串参数
24、转换为一个 float 值itemListindex.stroke = stroke;(4)mouseA监听鼠标单击、释放、进入、离开四个事件,当鼠标单击的时候,用e.getSource()先得到一个点的坐标初始化(x1,y1),再判断单击的是哪一个按钮,如果是绘制其它图形的按钮,那就光得到一个点(x1,y1);如果是铅笔或者橡皮擦,则继续初始化第二个点的坐标(x2,y2),此时x1=x2,y1=y2,即鼠标单击绘出一个点,而这个点是用绘直线方式画出的,表示已绘制的图形个数的index+;如果是添加文字按钮,则弹出一个可以输入文字的对话框。当鼠标释放的时候,如果是铅笔或橡皮,同样得到一个点,如
25、果是绘制其它图形的基本按钮,那就光得到(x2,y2),关键代码如下:class mouseA extends MouseAdapterpublic void mousePressed(MouseEvent e)statusBar.setText("Mouse Pressed:"+e.getX()+","+e.getY()+"");itemListindex.x1 =e.getX();itemListindex.y1 =e.getY();if(currentChoice = 3|currentChoice = 13)itemListin
26、dex.x2= e.getX();itemListindex.y2= e.getY();index+;createNewItem();repaint();if(currentChoice = 14)itemListindex.x1 = e.getX();itemListindex.y1 = e.getY();String input;input = JOptionPane.showInputDialog("可以添加你想写的文字咯!");/可以输入内容的对话框itemListindex.s1 = input;itemListindex.x2 = f1;itemListinde
27、x.y2 = f2;/f1,f2用来存放当前字体风格itemListindex.s2 = stylel;index+;currentChoice = 14;createNewItem();drawingArea.repaint();public void mouseReleased(MouseEvent e)statusBar.setText("Mouse Released:"+e.getX()+","+e.getY()+"");if(currentChoice = 3|currentChoice = 13)itemListindex
28、.x1 = e.getX();itemListindex.y1 = e.getY();itemListindex.x2 = e.getX();itemListindex.y2 = e.getY();index+;createNewItem();repaint();(5)mouseB监听鼠标拖拽和移动,在鼠标拖拽的时候,由于鼠标的拖拽一定是在单击之后的,所以mouseA和mouseB的监听功能必须连在一起来分析,上面得知,如果事件源是铅笔或橡皮,鼠标单击就得到了第一个点,紧接着鼠标开始拖拽,拖拽的过程中,也一直在动态的得到点,只是第一个点的x2,y2一直在以点的长度动态增加,index+;如果事
29、件源是绘制其它图形的按钮,则鼠标在动态拖拽的过程中只需要,得到点(x2,y2)就好:class mouseB extends MouseMotionAdapterpublic void mouseDragged(MouseEvent e)statusBar.setText("Mouse Dragged:"+e.getX()+","+e.getY()+"");if(currentChoice = 3|currentChoice = 13)itemListindex-1.x2= itemListindex.x2= itemListinde
30、x.x1=e.getX();itemListindex-1.y2= itemListindex.y2= itemListindex.y1=e.getY();index+;createNewItem();elseitemListindex.x2 = e.getX();itemListindex.y2 = e.getY();repaint();public void mouseMoved(MouseEvent e)statusBar.setText("Mouse Moved:"+e.getX()+","+e.getY()+"");3.2
31、基本图形类3.2.1 父类Drawingsclass Drawings implements Serializableint x1,y1,x2,y2;int R,G,B;float stroke;int type;String s1,s2;void draw(Graphics2D g2d);3.2.2 子类(只列出部分)(1)铅笔:class Pencil extends Drawingsvoid draw(Graphics2D g2d)g2d.setPaint(new Color(R,G,B);g2d.setStroke(new BasicStroke(stroke);g2d.drawLin
32、e(x1, y1, x2, y2); (2)空心圆class Circle extends Drawingsvoid draw(Graphics2D g2d)g2d.setPaint(new Color(R,G,B);g2d.setStroke(new BasicStroke(stroke);g2d.drawOval(Math.min(x1, x2),Math.min(y1, y2),Math.max(Math.abs(x1-x2),Math.abs(y1-y2),Math.max(Math.abs(x1-x2),Math.abs(y1-y2);(3)实心圆class fillCircle e
33、xtends Drawingsvoid draw(Graphics2D g2d)g2d.setPaint(new Color(R,G,B);g2d.setStroke(new BasicStroke(stroke);g2d.fillOval(Math.min(x1, x2),Math.min(y1, y2),Math.max(Math.abs(x1-x2),Math.abs(y1-y2),Math.max(Math.abs(x1-x2),Math.abs(y1-y2);(4)橡皮擦:class Rubber extends Drawingsvoid draw(Graphics2D g2d)g2
34、d.setPaint(new Color(255,255,255);g2d.setStroke(new BasicStroke(stroke+7);g2d.drawLine(x1, y1, x2, y2);(5)文字class Word extends Drawingsvoid draw(Graphics2D g2d)g2d.setPaint(new Color(R,G,B);g2d.setFont(new Font(s2,x2+y2,(int)stroke)*30);if(s1!=null)g2d.drawString(s1, x1, y1);4 设计中的难点4.1多态与动态绑定绑定指的是一
35、个方法的调用与方法所在的类(方法主体)关联起来。对java来说,绑定分为静态绑定和动态绑定;或者叫做前期绑定和后期绑定。动态绑定:在运行时根据具体对象的类型进行绑定。若一种语言实现了后期绑定,同时必须提供一些机制,可在运行期间判断实际对象的类型,并分别调用相应的方法。JAVA中的多态就是借助动态绑定来实现的。先定义一个父类Drawings实现接口Serializable,里面定义一个draw(),然后所有的基本图形类都从父类继承,作为子类,它们都重写了父类的draw方法,但是每个draw()都不一样,在绘制任何形状的时候,只需要简单的调用父类的draw()即可,然后让程序动态的根据对象的类型,
36、决定使用哪个子类的draw方法,为了使画出的图形更加的美观,我在draw方法中使用了Graphics2D对象的引用。这样,有了多态的存在,就可以在不改变原程序的情况下,对其可以画出的图形进行扩展,丰富程序的功能。4.2重绘的理解当一个窗口被构造出来的时候,里面就有一支画笔,在这个窗口出现再次显示、或大小改变等情况的时候,窗口就需要被重画,只要窗口需要被重画,paint就会被自动调用。repaint的作用是让窗口进行强制重画,其内部调用了paint方法,所以整个窗口在调用repaint的时候,也会被重画。从而,我们可以理解图形系统共同采用的机制,它里面一定会有一个类似repaint()的方法,在窗口调用这个方法的时候,整个屏幕进行重画,而这个方法的调用
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- GB/T 3102.7-2026量和单位第7部分:光和辐射
- 2025~2026学年河北省保定市涞水县人教版六年级上册11月期中数学试卷【附答案】
- 2027届四川省绵阳市游仙区数学八上期末综合测试模拟试题含解析
- 2026年康复治疗考试题库及答案
- 成品设备检验员安全操作规程
- 托育机构食品安全操作规程
- 浙江省绍兴市越城区2027届九年级数学第一学期期末检测模拟试题含解析
- OWLS英语等级测试全真模拟试题(含详细答案解析)
- OpenStack 高频面试题库及详细答案(实战版)
- 小儿先天性消化道畸形诊疗中国专家共识(2026版)
- 自考 08257 舆论学・重点精简版(速记 + 考点)
- 2026年校招:太平洋保险笔试题及答案
- 2026国企招聘考试公共基础知识考试题(含答案)
- 2025年银行考试-银行间本币市场交易员资格笔试考试历年典型考题及考点
- 安徽省2026年中考数学试题(解析版)
- 【万科集团财务风险防范措施研究8400字(论文)】
- 2026年度中国建设银行吉林省春季校园招聘(194人)笔试参考题库及答案解析
- 2026秋招:中国联通题库及答案
- 农业机械操作与维护规范(标准版)
- 面部大拉皮课件
- 【低空经济】低空监控平台设计方案
评论
0/150
提交评论