/** * 时间:2019/03/23/15点00分 * 创建绘图主窗体 */ package com.mr.draw;//类所在的包 import javax.swing.ButtonGroup;//No.5边界布局 import javax.swing.JButton;//No.5按钮类 import javax.swing.JFrame;//引用包:窗体类 import javax.swing.JToggleButton;//No.5按钮组 import javax.swing.JToolBar;//No.5工具栏 import javax.swing.JColorChooser;//No.7 import javax.swing.JMenu;//No.11 import javax.swing.JMenuBar;//No.11 import javax.swing.JMenuItem;//No.11 import java.awt.BorderLayout;//No.5 import java.awt.Color;//No.3颜色类 import java.awt.Graphics;//No.3绘图工具类 import java.awt.Graphics2D;//No.3绘图工具类 import java.awt.image.BufferedImage;//No.3缓冲图片类 import java.awt.event.MouseAdapter;//No.4鼠标实现类 import java.awt.event.MouseEvent;//No.4鼠标事件类 import java.awt.event.MouseMotionAdapter;//No.4移动监听类 import java.awt.geom.Ellipse2D;//No.9圆形 import java.awt.geom.Rectangle2D;//No.9方形 import java.awt.BasicStroke;//No.6画笔类 import java.awt.event.ActionEvent;//No.6动作事件 import java.awt.event.ActionListener;//No.6动作监听 /*自定义的*/ import com.mr.util.FrameGetShape;//No.9接口实现类 import com.mr.util.ShapeWindow;//No.9图形界面类 import com.mr.util.Shapes;//No.9图形类 import com.mr.util.DrawImageUtil;//No.10 /** * NO.3绘图步骤: * 1、创建窗体对象 * 2、创建画布:Canvas类的两个方法:paint绘图方法、repaint重绘方法 * 3、调用Graphics对象或创建Graphics 2D绘图对象 * 4、调用绘图方法Graphics:draw_()、fill_() * NO.4鼠标监听事件: * 1、主窗体导入鼠标事件相应类 * 2、创建记录鼠标状态改变量 * 3、创建组件监听方法,并实现鼠标绘图事件 * NO.5添加工具栏: * 创建菜单栏对象(JMenuBar类)、创建菜单对象(JMenu类)、创建菜单项对象(JMenultem类) * 1、主窗体中导入工具栏相关类 * 2、创建工具栏和按钮对象 * 3、实例化工具栏和按钮对象 * No.6画笔粗细监听: * 1、添加画笔粗细按钮监听方法 * No.7前景色和背景色按钮监听: * 1、添加:前景色和背景色按钮监听方法,改变画板和画笔颜色 * No.8清除图像和橡皮监听: * 1、清除图像采用整个画板清除 * 2、橡皮采用局布清除 * No.9绘制图形方法 * 1、主窗体中导入工具类,并实现图形组件接口 * 2、创建记录图形的变量 * 3、实现图形组件接口抽象方法 * 4、在工具栏中添加图形按钮 * 5、实现图形按钮点击事件 * 6、实现鼠标的按下事件 * No.10 实现保存图片 * 1、添加保存按钮动作监听 * No.11-12 添加菜单栏 * 1、主窗体中导入菜单相应类 * 2、创建所有菜单项对象 * 3、实例化菜单项,并将菜单栏放到主窗体中 * */ /** * 画图主体 * * **/ public class DrawPictureFrame extends JFrame implements FrameGetShape{//继承窗体类//No.9接口 /*代码01开始*/ // /** // * 构造方法 // **/ // public DrawPictureFrame() { // setResizable(false);//窗体不能改变大小 // setTitle("画图程序");//设置标题 // setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//窗体关闭则停止程序 // setBounds(500,100,574,460);//设置窗口位置和高宽 // } // /** // * 主程序 // **/ // public static void main(String[] args) { // DrawPictureFrame frame = new DrawPictureFrame();//创建窗体对象 // frame.setVisible(true);//让窗体可见 // } /*代码01结束*/ /*代码03开始*/ //创建一个8位BGR颜色分量的图像 BufferedImage image = new BufferedImage(570,390,BufferedImage.TYPE_3BYTE_BGR);//No.3 Graphics gs = image.getGraphics();//No.3 获的图像的绘图对象 Graphics2D g = (Graphics2D)gs;//No.3 将绘图对象转换为Graphics2D类型 DrawPictureCanvas canvas = new DrawPictureCanvas();//No.3 创建画布对象 Color foreColor = Color.BLACK;//No.3定义前景色 Color backgroundColor = Color.WHITE;//No.3定义背景色 int x =-1;//No.4 上次鼠标绘制点的横坐标 int y =-1;//No.4 上次鼠标绘制点的纵坐标 boolean rubber = false ;//No.4 橡皮擦标识变量 private JToolBar toolbar;//No.5工具栏 private JButton eraserButton;//No.5橡皮按钮 private JToggleButton strokeButton1;//No.5细线按钮 private JToggleButton strokeButton2;//No.5粗线按钮 private JToggleButton strokeButton3;//No.5较粗线按钮 private JButton backgroundButton;//No.5背景按钮 private JButton foregroundButton;//No.5前景按钮 private JButton clearButton;//No.5清除按钮 private JButton saveButton;//No.5保存按钮 private JButton shapeButton;//No.5图形按钮 boolean drawShape = false;//No.9 Shapes shape;//No.9 private JMenuItem strokeMenuItem1;//No.10 private JMenuItem strokeMenuItem2;//No.10 private JMenuItem strokeMenuItem3;//No.10 private JMenuItem clearMenuItem;//No.10 private JMenuItem foregeroundMenuItem;//No.10 private JMenuItem backgroundMenuItem;//No.10 private JMenuItem eraserMenuItem;//No.10 private JMenuItem exitMenuItem;//No.10 private JMenuItem saveMenuItem;//No.10 /** * 构造方法 * No.3添加组件的初始化方法 * No.4添加组件监听 * */ public DrawPictureFrame() { setResizable(false);//No.3窗体不能改变大小 setTitle("画图程序");//No.3设置标题 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//No.3窗体关闭则停止程序 setBounds(500,100,574,460);//No.3设置窗体位置和高宽 init();//No.3组件初始化 addListener();//No.4 添加组件监听 } /** * @函数名:init * @功能:组件初始化 * @category:私有的 * @param:无 * @return:无 * */ private void init() { g.setColor(backgroundColor);//No.3用背景设置绘图对象的颜色 g.fillRect(0, 0, 570, 390);//No.3用背景色填充整个画布 g.setColor(foreColor);//No.3用前景色设置绘图对象的颜色 canvas.setImage(image);//No.3设置画布的图像 getContentPane().add(canvas);//No.3将画布添加到窗体容器默认布局的中部位置 JToolBar toolBar = new JToolBar();//No.5初始化工具栏 getContentPane().add(toolBar, BorderLayout.NORTH);//No.5工具栏添加到窗体最北位置 saveButton = new JButton("保存");//No.5初始化按钮对象,并添加文本内容 toolBar.add(saveButton);//No.5工具栏添加按钮 toolBar.addSeparator();//No.5添加分割条 strokeButton1 =new JToggleButton("细线");//No.5初始化按钮对象,并添加文本内容 strokeButton2 =new JToggleButton("粗线");//No.5 strokeButton3 =new JToggleButton("较粗");//No.5 strokeButton1.setSelected(true);//No.5细线处于被选中状态 toolBar.add(strokeButton1);//No.5工具栏添加按钮 toolBar.add(strokeButton2);//No.5 toolBar.add(strokeButton3);//No.5 ButtonGroup strokeGroup = new ButtonGroup();//No.5 //NO.5画笔粗细按钮组,保证同时只有一个按钮被选中 strokeGroup.add(strokeButton1);//No.5按钮组件添加按钮 strokeGroup.add(strokeButton2);//No.5 strokeGroup.add(strokeButton3);//No.5 toolBar.addSeparator();//No.5添加分割条 backgroundButton = new JButton("背景颜色");//No.5初始化按钮对象,并添加文本内容 foregroundButton = new JButton("前景颜色");//No.5 toolBar.add(backgroundButton);//No.5工具栏添加按钮 toolBar.add(foregroundButton);//No.5 toolBar.addSeparator();//No.5添加分割条 shapeButton =new JButton("图形");//No.9初始化按钮对象,并添加文本内容 toolBar.add(shapeButton);//No.9工具栏添加按钮 clearButton =new JButton("清除");//No.5初始化按钮对象,并添加文本内容 eraserButton = new JButton("橡皮");//No.5 toolBar.add(clearButton);//No.5工具栏添加按钮 toolBar.add(eraserButton);//No.5 JMenuBar menuBar = new JMenuBar();//No.11创建菜单栏 setJMenuBar(menuBar);//No.11窗体载入菜单栏 JMenu systeMenu = new JMenu("系统");//No.11初始化菜单栏对象,并添加文本内容 menuBar.add(systeMenu);//No.11菜单栏添加菜单对象 saveMenuItem = new JMenu("保存");//No.11初始化菜单项对象,并添加文本内容 exitMenuItem= new JMenu("退出");//No.11 systeMenu.add(saveMenuItem);//No.11菜单添加菜单项 systeMenu.addSeparator();//No.11添加分隔符 systeMenu.add(exitMenuItem);//No.11 JMenu strokeMenu = new JMenu("线型");//No.11初始化菜单栏对象,并添加文本内容 menuBar.add(strokeMenu);//No.11菜单栏添加菜单对象 strokeMenuItem1= new JMenu("细线");//No.11初始化菜单项对象,并添加文本内容 strokeMenuItem2= new JMenu("粗线");//No.11 strokeMenuItem3= new JMenu("较粗线");//No.11 strokeMenu.add(strokeMenuItem1);//No.11菜单添加菜单项 strokeMenu.add(strokeMenuItem2);//No.11 strokeMenu.add(strokeMenuItem3);//No.11 JMenu colorMenu = new JMenu("颜色");//No.11初始化菜单栏对象,并添加文本内容 menuBar.add(colorMenu);//No.11菜单栏添加菜单对象 foregeroundMenuItem= new JMenu("前景色");//No.11初始化菜单项对象,并添加文本内容 backgroundMenuItem= new JMenu("背景色");//No.11 colorMenu.add(foregeroundMenuItem);//No.11菜单添加菜单项 colorMenu.add(backgroundMenuItem);//No.11 JMenu editMenu = new JMenu("编辑");//No.11初始化菜单栏对象,并添加文本内容 menuBar.add(editMenu);//No.11菜单栏添加菜单对象 eraserMenuItem= new JMenu("橡皮");//No.11初始化菜单项对象,并添加文本内容 clearMenuItem= new JMenu("清除");//No.11 editMenu.add(eraserMenuItem);//No.11 editMenu.add(clearMenuItem);//No.11 } /** * @函数名:addListener * @功能:添加监听动作 * @category:私有的 * @param:无 * @return:无 * */ private void addListener() { canvas.addMouseMotionListener(new MouseMotionAdapter(){//No.4画板添加鼠标移动事件监听 public void mouseDragged(final MouseEvent e) {//No.4当鼠标拖拽时 if(x>0 && y>0) {//No.4 如果xy存在鼠标记录 if(rubber) {//No.4 如果橡皮擦标识为True ,表示使用橡皮 g.setColor(backgroundColor);//No.4绘图工具使用背景色 g.fillRect(x, y, 10, 10);//No.4在鼠标滑过的位置画填充的正方形//No.8橡皮功能 }else { g.drawLine(x, y, e.getX(), e.getY());//No.4在鼠标滑过的位置画直线 } } x = e.getX();//No.4上次鼠标绘制点的横坐标 y = e.getY();//No.4上次鼠标绘制点的纵坐标 canvas.repaint();//No.4更新画布 } }); canvas.addMouseListener(new MouseAdapter(){//No.4画板添加鼠标单击事件监听 public void mouseReleased(final MouseEvent arg0) {//No.4当按键抬起时 x = -1;//No.4将记录上一次鼠标绘制点的横坐标恢复成-1 y = -1;//No.4将记录上一次鼠标绘制点的纵坐标恢复成-1 } public void mousePressed(MouseEvent e) {//No.9鼠标按下时 if(drawShape) {//No.9如果此时鼠标画的是图形 switch(shape.getType()) {//No.9判断图形的种类 case Shapes.YUAN://No.9圆形 //No.9计算坐标,让鼠标处于图形的中心位置 int yuanX = e.getX()-shape.getWidth()/2;//No.9 int yuanY = e.getY()-shape.getHeigth()/2;//No.9 //No.9创建圆形,并指定坐标和宽高 Ellipse2D yuan = new Ellipse2D.Double(yuanX, yuanY, shape.getWidth(), shape.getHeigth()); g.draw(yuan); //No.9画图工具画此圆 break; case Shapes.FANG://No.9方形 //No.9计算坐标,让鼠标处于图形的中心位置 int fangX = e.getX()- shape.getWidth()/2;//No.9 int fangY = e.getY() - shape.getHeigth()/2;//No.9 //No.9创建方形图形,并指定坐标和宽高 Rectangle2D fang =new Rectangle2D.Double(fangX, fangY, shape.getWidth(), shape.getHeigth()); g.draw(fang);//No.9 画图工具画此方形 break; } canvas.repaint();//No.9更新画布 drawShape =false;//No.9画图形标识变量为false,说明现在鼠标画的是图形,而不是线条 } } }); strokeButton1.addActionListener(new ActionListener() {//No.6 细笔 public void actionPerformed(final ActionEvent arg0) { //No.6 声明画笔属性,1像素,线条末尾无修饰,折线处呈尖角 BasicStroke bs = new BasicStroke(1,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); g.setStroke(bs);//No.6 画图工具使用此画笔 } }); strokeButton2.addActionListener(new ActionListener() {//No.6 粗笔 public void actionPerformed(final ActionEvent arg0) { //No.6 声明画笔属性,3像素,线条末尾无修饰,折线处呈尖角 BasicStroke bs = new BasicStroke(3,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); g.setStroke(bs);//No.6 画图工具使用此画笔 } }); strokeButton3.addActionListener(new ActionListener() {//No.6 较粗笔 public void actionPerformed(final ActionEvent arg0) { //No.6 声明画笔属性,6像素,线条末尾无修饰,折线处呈尖角 BasicStroke bs = new BasicStroke(6,BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); g.setStroke(bs);g.setStroke(bs);//No.6 画图工具使用此画笔 } }); backgroundButton.addActionListener(new ActionListener() {//No.7背景颜色(画板) public void actionPerformed(final ActionEvent arg0) {//No.7单击 //No.7 打开颜色对话框,参数:父窗体、标题、默认选中的颜色(白色) Color bgColor =JColorChooser.showDialog(DrawPictureFrame.this, "选择颜色对话框", Color.WHITE); if(bgColor != null) {//No.7 如果选中的颜色背景空的 backgroundColor = bgColor ;//No.7将选中的颜色赋给背景变量 } backgroundButton.setBackground(backgroundColor);//No.7背景色按钮也更换为当前背景颜色 g.setColor(backgroundColor);//No.7绘图工具使用背景色 g.fillRect(0, 0, 570, 390);//No.7画一个背景颜色的方形填满整个画布 g.setColor(foreColor);//No.7绘画工具使用前景色 canvas.repaint();//No.7更新画布 } }); foregroundButton.addActionListener(new ActionListener() {//No.7前景颜色(画笔) public void actionPerformed(final ActionEvent arg0) {//No.7单击 //No.7 打开颜色对话框,参数:父窗体、标题、默认选中的颜色(黑色) Color fgColor =JColorChooser.showDialog(DrawPictureFrame.this, "选择颜色对话框", Color.BLACK); if(fgColor != null) {//No.7 如果选中的颜色前景空的 foreColor = fgColor ;//No.7将选中的颜色赋给前景变量 } foregroundButton.setForeground(foreColor);//No.7前景色文字变成当前选择的前景色 g.setColor(foreColor);//No.7绘图工具使用前景色 } }); clearButton.addActionListener(new ActionListener() {//No.8清除按钮 public void actionPerformed(final ActionEvent arg0) {//No.8单击 g.setColor(backgroundColor);//No.8 绘图工具使用背景色 g.fillRect(0, 0, 570, 390);//No.8画一个颜色的正方形填满整个画布 g.setColor(foreColor);//No.8绘图工具使用前景色 canvas.repaint();//No.8更新画布 } }); eraserButton.addActionListener(new ActionListener() {//No.8橡皮按钮 public void actionPerformed(final ActionEvent arg0) {//No.8单击 if(eraserButton.getText().equalsIgnoreCase("橡皮")) {//No.8点击工具栏上的橡皮按钮使用橡皮 rubber = true;//No.8橡皮标志flag=1 eraserButton.setText("画图");//No.8橡皮按钮文本变成画图 }else {//No.8点击工具栏上的绘图按钮使用画笔 rubber = false;//No.8橡皮标志flag=0 eraserButton.setText("橡皮");//No.8画图按钮文本变成橡皮 g.setColor(foreColor);//No.8设置绘图对象的前景色 } } }); shapeButton.addActionListener(new ActionListener(){//No.9 图形按钮添加动作监听 public void actionPerformed(ActionEvent e) {//No.9 单击时 ShapeWindow shapeWindow = new ShapeWindow(DrawPictureFrame.this);//No.9 创建图形选择组件 int shapeButtonWidth = shapeButton.getWidth();//No.9 获取图形按钮宽度 int shapeWindowWith = shapeWindow.getWidth();//No.9获取图形按钮高度 int shapeButtonX = shapeButton.getX();//No.9 获取图形按横坐标 int shapeButtonY = shapeButton.getY();//No.9 获取图形按钮纵坐标 //No.9计算图形组件纵坐标,让组件显示在“图形”按钮下方 int shapeWindowX = getX() + shapeButtonX - (shapeWindowWith -shapeButtonWidth );//No.9 int shapeWindowY =getY() + shapeButtonY + 80; shapeWindow.setLocation(shapeWindowX,shapeWindowY);//No.9 设置图形组件坐标位置 shapeWindow.setVisible(true);//No.9 图形组件可见 } }); saveButton.addActionListener(new ActionListener() {//No.10保存按钮添加动作监听 public void actionPerformed(final ActionEvent arg0) {//No.10单击时 DrawImageUtil.saveImage(DrawPictureFrame.this, image);//No.10打印图片 } }); // exitMenuItem.addActionListener(new ActionListener(){//No.12菜单栏编辑项退出按钮 // public void actionPerformed(final ActionEvent e){//No.12单击时 // System.exit(0);//No.12 // } // }); saveMenuItem.addActionListener(new ActionListener(){//No.12菜单栏系统项保存按钮 public void actionPerformed( ActionEvent e) {//No.12 DrawImageUtil.saveImage(DrawPictureFrame.this, image);//No.12打印图片 } }); // eraserMenuItem.addActionListener(new ActionListener(){//No.12菜单栏编辑项橡皮按钮 // public void actionPerformed(final ActionEvent e) {//No.12单击时 // if(eraserMenuItem.getText().equalsIgnoreCase("橡皮")) {//No.12点击菜单栏上的橡皮按钮使用橡皮 // rubber = true;//No.12橡皮标志flag=1 // eraserMenuItem.setText("画图");//No.12菜单栏橡皮按钮文本变成画图 // eraserButton.setText("画图");//No.12工具栏橡皮按钮文本变成画图 // }else {//No.12点击菜单栏上的绘图按钮使用画笔 // rubber = false;//No.12橡皮标志flag=0 // eraserMenuItem.setText("橡皮");//No.12菜单栏画图按钮文本变成橡皮 // eraserButton.setText("橡皮");//No.12工具栏画图按钮文本变成橡皮 // g.setColor(foreColor);//No.12设置绘图对象的前景色 // } // } // }); // clearMenuItem.addActionListener(new ActionListener(){//No.12菜单栏编辑项清除按钮 // public void actionPerformed(final ActionEvent e) {//No.12单击时 // g.setColor(backgroundColor);//No.12 绘图工具使用背景色 // g.fillRect(0, 0, 570, 390);//No.12画一个颜色的正方形填满整个画布 // g.setColor(foreColor);//No.12绘图工具使用前景色 // canvas.repaint();//No.12更新画布 // } // }); // strokeMenuItem1.addActionListener(new ActionListener(){//No.12菜单栏线型项细线按钮 // public void actionPerformed(final ActionEvent e) {//No.12单击时 // //No.12 声明画笔属性,1像素,线条末尾无修饰,折线处呈尖角 // BasicStroke bs = new BasicStroke(1,BasicStroke.CAP_BUTT, // BasicStroke.JOIN_MITER); // g.setStroke(bs);//No.12 画图工具使用此画笔 // strokeButton1.setSelected(true);//No.12细线按钮处于选中状态 // } // }); // strokeMenuItem2.addActionListener(new ActionListener(){//No.12菜单栏线型项粗线按钮 // public void actionPerformed(final ActionEvent e) {//No.12单击时 // //No.12 声明画笔属性,3像素,线条末尾无修饰,折线处呈尖角 // BasicStroke bs = new BasicStroke(3,BasicStroke.CAP_BUTT, // BasicStroke.JOIN_MITER); // g.setStroke(bs);//No.12 画图工具使用此画笔 // strokeButton2.setSelected(true);//No.12粗线按钮处于选中状态 // } // }); // strokeMenuItem3.addActionListener(new ActionListener(){//No.12菜单栏线型项较粗线按钮 // public void actionPerformed(final ActionEvent e) {//No.12 // //No.12 声明画笔属性,6像素,线条末尾无修饰,折线处呈尖角 // BasicStroke bs = new BasicStroke(6,BasicStroke.CAP_BUTT, // BasicStroke.JOIN_MITER); // g.setStroke(bs);//No.12 画图工具使用此画笔 // strokeButton2.setSelected(true);//No.12较粗线按钮处于选中状态 // } // }); // foregeroundMenuItem.addActionListener(new ActionListener(){//No.12菜单栏颜色项前景色按钮 // public void actionPerformed(final ActionEvent e) {//No.12单击时 // //No.12 打开颜色对话框,参数:父窗体、标题、默认选中的颜色(黑色) // Color fgColor =JColorChooser.showDialog(DrawPictureFrame.this, // "选择颜色对话框", Color.BLACK); // if(fgColor != null) {//No.12如果选中的颜色前景空的 // foreColor = fgColor ;//No.12将选中的颜色赋给前景变量 // } // foregroundButton.setForeground(foreColor);//No.12前景色文字变成当前选择的前景色 // g.setColor(foreColor);//No.12绘图工具使用前景色 // } // }); // backgroundMenuItem.addActionListener(new ActionListener(){//No.12菜单栏颜色项背景色按钮 // public void actionPerformed(final ActionEvent e) {//No.12 // //No.12打开颜色对话框,参数:父窗体、标题、默认选中的颜色(白色) // Color bgColor =JColorChooser.showDialog(DrawPictureFrame.this, // "选择颜色对话框", Color.WHITE); // if(bgColor != null) {//No.12 如果选中的颜色背景空的 // backgroundColor = bgColor ;//No.12将选中的颜色赋给背景变量 // } // backgroundMenuItem.setBackground(backgroundColor);//No.12背景色按钮也更换为当前背景颜色 // backgroundButton.setBackground(backgroundColor);//No.12背景色按钮也更换为当前背景颜色 // g.setColor(backgroundColor);//No.12绘图工具使用背景色 // g.fillRect(0, 0, 570, 390);//No.7画一个背景颜色的方形填满整个画布 // g.setColor(foreColor);//No.12绘画工具使用前景色 // canvas.repaint();//No.12更新画布 // } // }); } /** * main函数 * */ public static void main(String[] args) { DrawPictureFrame frame =new DrawPictureFrame();//No.3 创建窗体对象 frame.setVisible(true);//No.3 让窗体可见 } /** * @函数名:getShape * @功能:FrameGetshape接口实现类, * 用于获取图形空间返回的被选中的图形 * @category:公有的 * @param:shape * @return:无 * */ public void getShape(Shapes shape) { this.shape = shape ;//No.9 将返回的图形对象赋给类的全局变量 drawShape =true;//No.9 画图形标识变量为true, 说明现在鼠标画的是图形,而不是线条 } }