Java-绘图软件(Windows画板)

Java画板实现

任务分析

功能需求
. 绘制基本图形(曲线,直线,矩形,椭圆,圆,圆角矩形,填充图形,文字)
. 图形文件操作(保存,新建,打开)
. 图形操作(填充,撤回,擦除)
. 图像编辑(拉伸,扭曲,旋转,翻转,放大,缩小)
. 颜色设定(自定义设定)
.设置笔画粗细
.设置字体
技术路线
开发工具及环境:jdk1.12 intelliJ IDEA StarUML
用到的主要技术:
Swing框架,
事件监听机制(ActionEvent,MouseEvent,ItemEvent)
图形界面设计:AWT+Swing
Graphics2D绘图(多态)

分析与设计

用况图
用况图
类图
类图
详细设计
Draw
主动类,用来程序的执行,main方法中new了一个JFrame对象。

public class Draw {
    public static void main(String[] args) {
       new DrawPad("画图");
    }
}

DrawArea
画板类,用来绘制图形区域,支持重绘,注册鼠标事件监听器,实例化两个接口,实现绘图。
属性:

public class DrawArea extends JPanel {
    DrawPad drawPad;
    Shape[] list = new Shape[50000];//图形数组
    int index = 0;//绘制图形数目索引
    int R,G,B;//彩色值
    float stroke = 1.0f;//默认笔画粗细
    int bold,italic;//字体风格
    BufferedImage image;//背景图像存储
    private int currentchoice = 4;//当前状态pan。铅笔
    private Color col=Color.BLACK;//默认笔画颜色

方法:
方法
DrawPad
界面类,包含工具栏(JTooBar)和菜单栏(JMenuBar)以及状态栏(JLabel)的初始化,注册actionlistener,itemstatechanged监听器,实例化actionPerformed,itemStateChanged方法。实现画板保存,打开,新建的方法。
属性:

public class DrawPad extends JFrame implements ActionListener,ItemListener {
    private JToolBar button_panel;// 按钮面板
    private JMenuBar menuBar;// 菜单条
    private JMenu file, color, stroke;// 菜单(文件,颜色,编辑)
    private JMenuItem newfile, openfile, savefile, exit;//文件 菜单项
    private JMenuItem colorchoice, cancel,narrow,enlarge;//颜色,编辑,菜单项
    private JLabel startbar;// 状态栏
    private DrawArea drawArea;// 画布
    private JComboBox<String> combox;//字体选择下拉框
    String[] fontname;//字体

    private String[] icon_path = { "src/icons/newfile.png", "src/icons/openfile.png", "src/icons/savefile.png", "src/icons/eraser.png",
            "src/icons/pan.png", "src/icons/line.png", "src/icons/rect.png", "src/icons/frect.png", "src/icons/oval.png",
            "src/icons/foval.png", "src/icons/circle.png", "src/icons/fcircle.png", "src/icons/roundrect.png",
            "src/icons/froundrect.png", "src/icons/color.png", "src/icons/stroke.png", "src/icons/word.png" };
    private Icon[] icons;

    private String Prompt_message[] = { "新建图片", "打开图片", "保存图片", "橡皮擦", "铅笔", "直线", "空心矩形", "实心矩形", "空心椭圆", "实心椭圆",
            "空心圆", "实心圆", "空心圆角矩形", "实心圆角矩形", "颜色", "线条粗细", "文字输入" };
    JButton[] button;// 工具条中的按钮组
    private JButton bold, italic, plain;// 字体格式

方法:
在这里插入图片描述
文件过滤类

class JpgFilter extends FileFilter {//jpg图片过滤
    public boolean accept(File f) {
        if (f.isDirectory())
            return true;
        return f.getName().endsWith(".jpg");
    }
    public String getDescription() {
        return ".jpg";
    }
}
class BmpFilter extends FileFilter {//bmp图片过滤
    public boolean accept(File f) {
        if (f.isDirectory())
            return true;
        return f.getName().endsWith(".bmp");
    }
    public String getDescription() {
        return ".bmp";
    }
}
class PngFilter extends FileFilter {//png图片过滤
    public boolean accept(File f) {
        if (f.isDirectory())
            return true;
        return f.getName().endsWith(".png");
    }
    public String getDescription() {
        return ".png";
    }
}

shape
绘制图形的父类,实例化Serializable(序列化)接口,其属性保存绘图必要的坐标,色彩,粗细,字体等信息。有一个绘图方法,由子类重写该方法,调用时实现多态。

public class Shape implements Serializable {
    int x1, x2, y1, y2;//定义坐标
    int R, G, B;//定义色彩
    float stroke;//粗细
    String font_familyName;
    String word;//文字
    int bold,italic;

    void draw(Graphics2D g) { }
}

Line,Rect,fillrect,Oval,fillOval,Circle,fillCircle,RoundRect,fillRounRect,pencil,Eraser,word
具体图形类,继承自shape类,重写方法
在这里插入图片描述
类之间的联系
Draw类是主动类与DrawPad类是1比1组合关系,每一个用户只有一个界面对象。
DrawPad类和DrawArea类是1比1的关联关系,一个界面中只有一个画板,一个画板只属于一个界面。
DrawArea类和shape类是1比*的单项关联关系,多个shape对象组成了DrawArea对象的一个数组成员。
Shape类有多个子类(Line,Rect …),他们都重写绘图方法。
FileFilter抽象类有三个子类,本身有两个抽象方法,他与DrawPad是依赖关系,当界面中有文件操作,会调用文件过滤类进行文件读写。

程序框架

(1)Swing基本框架
Swing是在AWT基础上构建的新的图形界面系统,对AWT进行了扩充。两者的区别:AWT基于c/c++,速度较快;Swing基于AWT的java程序,速度慢一些。基本框架如下图:
在这里插入图片描述
(2)图形化设计步骤
创建顶层容器
程序的初始显现窗口,窗口中放入其它菜单、工具栏、文本框、按钮等组件
其它所有的组件(控件)都是直接或间接显示在顶层容器中的。
在java中顶层容器有三种,分别是JFrame(框架窗口,即通常的窗口)、JDialog(对话框)、JApplet(用于设计嵌入在网页中的java小程序)。
本例中顶层容器是DrawPad(继承自JFrame):
在这里插入图片描述创建中间容器,组件
对应于程序中出现的菜单、工具栏(中间容器)、文本框、按钮、单选框、复选框等控件。
本例中Swing UI组件列表如下
━━━━━━━━━━━━━━━━━━━━━━━
  组件类         描述
─────────────────────────────────
JButton 能显示文本和图形的按钮,它是AWT按钮组件的替代组件
JComboBox 带下拉列表的文本框,它是AWT选择组件的替代组件
JLabel 可显示文本和图标的标签,它是AWT标签组件的替代组件
JMenu 菜单条中显示的一个菜单,它是AWT菜单组件的替代组件
JMenuBar 用于显示菜单的菜单条,它是AWT菜单条组件的替代组件
JMenuItem 菜单项,它是AWT菜单项组件的替代组件
JOptionPane 显示标准的对话框,如:消息和问题对话框
JPanel 通用容器,它是AWT面板和画布组件的替代组件
JToolBar 工具条
JToolTip 当光标停留在一个组件上时,该组件上显示的一行文字
在这里插入图片描述
将组件加入容器
java中创建组件后,将组件放入相应的容器,才能在顶层容器,如窗口中显示出组件。
本例中将工具栏button_panel(JToolBar),画板drawArea(DrawArea),坐标标签Startbar(JLabel)加入到顶层容器DrawPad中
还将许多小型控件加入到中型容器工具栏中
在这里插入图片描述
设置容器内组件位置
组件添加到容器中,还必须设置好组件的显示位置,一般有两种方法来设置组建的显示位置,一是按照与容器的相对距离(以像素为单位),精确固定控件的位置;二是用布局管理器来管理组件在容器内的位置。
本例中对顶层容器的组件位置管理用的是第二种方法
在这里插入图片描述
处理组件所产生的事件
用户执行选择菜单、单击按钮等操作时,就要执行相应的命令,进行相关的程序处理,需要设置组件的事件。
本例中工具栏主要发生的是ActionEvent和ItemEvent事件,用户通过点击相应的按钮,触发该事件,事件处理方式是:使用接口在类内重写actionPerformed()方法和itemStateChanged()方法
在这里插入图片描述
菜单条menuBar(JMenuBar)发生的是ActionEvent事件
在这里插入图片描述
(3)特殊说明的方法

public void paintComponent(Graphics g)

AWT 和 Swing 中组件的绘制方式不同,绘制方法的实现也有区别。
AWT 中组件重绘时先调用 update(Graphics g) 清除以前绘制的,再调用 paint() 方法里进行绘制,所以在 AWT 组件里重绘时,只要简单的覆写 paint() 方法就可以了。
而在Swing 中,组件绘制 paint() 方法会依次调用 paintComponent(),paintBorder(),paintChildren() 三个方法。paintComponent() 绘制组件本身,paintBorder() 绘制组件的边框,paintChildren() 绘制组件的子组件, Swing 编程时,如果继承 JComponent 或者其子类需要重绘的话,只要覆写 paintComponent() 而不是 paint(),方法 paintBorder(),paintChildren()一般默认即可

void draw(Graphics2D g2b,Shape i){
    i.draw(g2b);
}

将画笔传到每个图形类,用它们自己重写的draw()方法绘制图形,实现了多态绘图。

public BufferedImage createImage(DrawArea panel) {
    int width = DrawPad.this.getWidth();
    int height = DrawPad.this.getHeight();
    BufferedImage panelImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics2D g2D = panelImage.createGraphics();
    g2D.setColor(Color.white);// 填充背景色
    g2D.fillRect(0, 0, width, height);
    g2D.translate(0, 0);//画笔坐标定义为原点
    panel.paintComponent(g2D);
    g2D.dispose();// 释放部分资源
    return panelImage;
}//将画板保存成bufferimage

画板的图像转换后可以进行传输存储了。

调试与测试

(1)难点
不同图形绘制之间的共性抽象,以及绘图对象的绘图过程,及存储问题。
在设计之初,不是很清楚计算机是如何作图的,经过资料的查阅,发现简单Graphics2D绘图机制,通过多个坐标点,用Graphics2D对象的不同方法绘图。于是抽象出一个共有的shape类,其子类重写绘图方法。在同一个画板上多个图形存储,是在一个图形数组中,每次有新的变化后,进行重绘,呈现不同样式。
画板图像的存储
当绘制完成时,如何将图片保存起来,重新绘图时想把上次绘制好的图像加载成底图。
为实现该功能,我用BufferImage 存储画板图像。加载时将读入的图片绘制在索引号为0的图形数组中重绘。
(2)主要功能运行展示
绘制基本图形
在这里插入图片描述
图形文件操作
在这里插入图片描述
在这里插入图片描述
图像编辑
在这里插入图片描述
在这里插入图片描述
颜色设定
在这里插入图片描述
设置粗细
在这里插入图片描述
写字
在这里插入图片描述

总结

本次面向对象程序设计过程,其分为四部分,OOA面向对象分析,OOD面向对象设计,面向对象编程,面向对象测试。
面向对象的基本原则有
(1)抽象:面向对象分析阶段,先定义类的属性和操作,而与实现有关的的因素在设计阶段再考虑
(2)分类:把具有相同属性和相同操作的对象划分为一类,用类作为这些对象的抽象描述
(3)封装:把事物的性质与行为结合,信息隐藏,设置属性公开性。
(4)消息通信:不允许在对象之外直接访问它的内部属性,如set,get方法。
(5)多态性:一般类和特殊类可以有相同格式的属性或操作,但这些属性或操作具有不同的含义,这样的好处是针对同一消息,不同对象可对其进行响应,但体现出来的行为不同,
(6)行为分析:通过状态图可以分析对象的状态变迁情况,关系机制提供了用关联,继承和聚合等组织类的方法。
(7)复杂性控制:引入包的概念,由于我的系统比较简单,只有一个包。
画图软件的实现充分使用了面向对象的方法,设计之初,先做需求分析,再做类图抽象(定义类的属性与操作,分析类之间的关系),使用Swing基本框架设计(由于本例只有一个视图,数据存储不频繁,存储在一个图形数组中,未使用MVC模式,以及其他23种设计模式中,未找到适合的设计模式),利用事件监听机制进行消息通信。利用Graphics2D绘图(多态)。进行文件读写存储。实现其他预留功能。

GitHub链接

画板

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr.Ma.01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值