#用JAVA做一个简单的画图软件

写在前面

第一次用Java写东西,未免有疏漏之处,请多多指正。

首先 建立画布。

这里利用JFrame窗体界面创建一个DrawerFrame类,在主函数中实例化DrawerFrame类,并调用showUI方法,画出程序的基本框架。

public class DrawerFrame {public static void main(String[] args){DrawerFrame df= new DrawerFrame();df.showUI();}
public void showUI(){//窗体MyFrame jf=new MyFrame();jf.setSize(900,900);jf.setTitle("画图界面");//居中显示jf.setLocationRelativeTo(null);//退出进程jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置可见jf.setVisible(true);
}

现在效果如下

第二步 往画板上面增加画图功能

这是目标

  1. 从最简单的画直线开始 由于画板的画图功能是通过鼠标出发,所以要增加一个MouseListener,实现对鼠标信息的获取。
             //监听方法      DrawerMouse m=new DrawerMouse();jf.addMouseListener(m);
  1. 这里的DrawerMouse是由MouseListener(抽象类,每个接口都必须实现)重写而来。(tips:

    如果不知道这些接口的作用,可以像这样做,然后一边操控鼠标一边在控制面板查看输出)
    画直线段需要知道起始点(X1,Y1)和终点(X2,Y2)的坐标,在鼠标按下的时候,此时光标的位置即为起点。松开时,则得到终点。
public void mousePressed (MouseEvent e){x1 = e.getX();y1 = e.getY();
}
public void mouseReleased (MouseEvent e){x2 = e.getX();y2 = e.getY();     //画图gr.drawLine(x1, y1, x2, y2);
}
  1. 画矩形十分简单,但是要考虑矩形的方向。
  2. 下面讲讲怎么画曲线和喷枪。画曲线要检测到鼠标的拖动动作,这里还是用到现成的ActionListener,同MouseListener一样,需要对其接口重写。画曲线可以理解为画无数很短的直线,这样的话,如果我们不断更新直线的起点和终点,就能通过画直线的方式画出曲线。
public void mouseDragged(MouseEvent e){x2 = e.getX();y2 = e.getY();if( ActionCommand.equals("曲线")){gr.drawLine(x1, y1, x2, y2);x1=x2;y1=y2;}
  1. 喷枪功能与画直线类似,只不过画的是点而不是直线,并且这些点是不连续的、随机的。

  2. 喷枪功能与画直线类似,只不过画笔的颜色要与画板背景颜色一致。
    按照以上步骤实现DrawerMouse类大致如下:

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Random;import javax.swing.JButton;
import javax.swing.UIManager;public class DrawerMouse implements MouseListener,ActionListener,MouseMotionListener  {public Graphics2D gr;public int x1=0,y1=0,x2=0,y2=0;public int pre_x1,pre_y1,pre_x2,pre_y2,source_x,source_y;//pre_x1,pre_y1,pre_x2,pre_y2记录上一次的(x1.y1) (x2,y2);(source_x,source_y)是多边形的第一个点public String ActionCommand,Colorcommand; public boolean FirstEdgeDone;//判断多边形第一条边是否画出public ArrayList <Shape> date=new ArrayList <Shape> ();public void mouseClicked (MouseEvent e){//画图if(ActionCommand=="三角形"){//三角形if(pre_x1!=pre_x2&&pre_y1!=pre_y2){gr.drawLine(x1, y1, pre_x1, pre_y1);Shape s1=new Shape(x1, y1,pre_x1, pre_y1,gr.getColor(),"直线");date.add(s1);gr.drawLine(x2, y2, pre_x2, pre_y2);Shape s2=new Shape(x1, y1,pre_x2, pre_y2,gr.getColor(),"直线");date.add(s2);}}else ;}public void mousePressed (MouseEvent e){pre_x1=x1;pre_y1=y1;x1 = e.getX();y1 = e.getY();}public void mouseReleased (MouseEvent e){pre_x2=x2;pre_y2=y2;x2 = e.getX();y2 = e.getY();//画图if(ActionCommand.equals("矩形")){//矩形  gr.drawRect(Math.min(x1,x2), Math.min(y1,y2), Math.abs(x2-x1),Math.abs(y2-y1));Shape s=new Shape(x1, y1, x2, y2,gr.getColor(),"矩形");date.add(s);}else if(ActionCommand.equals("直线")||ActionCommand=="三角形") {//画直线,或者画三角形的第一条边gr.drawLine(x1, y1, x2, y2);Shape s=new Shape(x1, y1, x2, y2,gr.getColor(),"直线");date.add(s);}else if(ActionCommand=="多边形"&&!FirstEdgeDone){//画多边形的第一条边source_x=x1;source_y=y1;gr.drawLine(x1, y1, x2, y2);Shape s=new Shape(x1, y1, x2, y2,gr.getColor(),"直线");date.add(s);FirstEdgeDone=true;}else if(ActionCommand=="多边形"){//多边形if(e.getClickCount()==2){gr.drawLine(x1, y1, source_x, source_y);Shape s=new Shape(x1, y1,source_x, source_y,gr.getColor(),"直线");date.add(s);FirstEdgeDone=false;}else {gr.drawLine(x1, y1, pre_x2, pre_y2);Shape s=new Shape(x1, y1,pre_x2, pre_y2,gr.getColor(),"直线");date.add(s);}}else ;}public void mouseEntered (MouseEvent e){}public void mouseExited (MouseEvent e){}//实现MouseMotionListener的方法public void mouseMoved(MouseEvent e){}public void mouseDragged(MouseEvent e){x2 = e.getX();y2 = e.getY();if( ActionCommand.equals("曲线")){gr.drawLine(x1, y1, x2, y2);x1=x2;y1=y2;}else if( ActionCommand.equals("橡皮擦")){gr.setColor(UIManager.getColor("control"));gr.drawLine(x1, y1, x2, y2);x1=x2;y1=y2;}else if( ActionCommand.equals("喷枪")){Random r=new Random();for(int i=0;i<20;i++){int a=r.nextInt(20),b=r.nextInt(20);gr.drawLine(x1+a, y1+b,x1+a, y1+b);}x1=x2;y1=y2;}}public void actionPerformed(ActionEvent e){String command=e.getActionCommand();if(command.equals("")){JButton button = (JButton) e.getSource();  gr.setColor(button.getBackground());}else{ActionCommand=command;if(ActionCommand=="多边形")FirstEdgeDone=false;}}}
}

#第三步,考虑增加按钮,便于画图。

在showUI里增加面板panel,方便我们管理按钮。

//增加面板JPanel panelAct=new JPanel();jf.add(panelAct);

通过循环来增加按钮,节省编码时间。

 //自定义面板private static void placeComponetsAct(JPanel panel,DrawerMouse m) {//创建按钮String [] Type={"直线","矩形","三角形","多边形","曲线","喷枪","橡皮擦"    //自定义面板private static void placeComponetsAct(JPanel panel,DrawerMouse m) {//创建功能按钮String [] Type={"直线","矩形","三角形","多边形","曲线","喷枪","橡皮擦"};for(int i=0;i<Type.length;i++){JButton Button=new JButton(Type[i]);Button.setBounds(10, 80, 80, 25);Button.addActionListener(m);panel.add(Button);}//创建颜色按钮Color [] color={Color.BLACK,Color.BLUE,Color.WHITE,Color.GRAY,Color.RED,Color.CYAN,Color.GREEN,Color.darkGray,Color.PINK} ;for(int i=0;i<color.length;i++){JButton Button=new JButton();Button.setPreferredSize(new Dimension( 25, 25));Button.setBounds(10, 80, 80, 25);//大小??Button.setBackground(color[i]);Button.addActionListener(m);panel.add(Button);}};for(int i=0;i<Type.length;i++){JButton Button=new JButton(Type[i]);Button.setBounds(10, 80, 80, 25);Button.addActionListener(m);panel.add(Button);}Color [] color={Color.BLACK,Color.BLUE,Color.WHITE,Color.GRAY,Color.RED,Color.CYAN,Color.GREEN,Color.darkGray,Color.PINK} ;for(int i=0;i<color.length;i++){JButton Button=new JButton();Button.setPreferredSize(new Dimension( 25, 25));//改变按钮大小Button.setBounds(10, 80, 80, 25);//不能通过此词语句改变按钮大小Button.setBackground(color[i]);Button.addActionListener(m);panel.add(Button);}

#第四步,重绘(数组、重写paint()方法)

当窗体发生变化时(最小化,改变窗体大小,拖动窗体等等),画在窗体上的图像会消失。
原因:每当窗体发生变化时,窗体需要重新再画一次。之前画的图形是画在窗体上,重画窗体的时候,图形没有存储,并不会重画一次。
所以要将图形重画就要把图形存储起来。
每一个图形都是由多个数据组成,并且图形不同,数据的个数也不同,定义shape类实现这个对象,把每一个图形对象使用数组或者队列存储起来。

public class Shape {public int FirstX,FirstY,SecondX,SecondY;//public int panSize;//先不实现public Color c;public String label;public String GetLabel(){return label;}public int GetFirstX(){return FirstX;}public int GetFirstY(){return FirstY;}public int GetSecondX(){return SecondX;}public int GetSecondY(){return SecondY;}public Color GetColor(){return c;}Shape(int FirstX,int FirstY,int SecondX,int SecondY,Color c,String label){this.FirstX=FirstX;this.FirstY=FirstY;this.SecondX=SecondX;this.SecondY=SecondY;this.c=c;this.label=label;}}

#接下介绍重写的方法
定义一个新的类MyFrame继承JFrame。首先定义一个记录图形的shape[]数组。然后重写paint (Graphics g)方法。
重写时,要继承父类的方法。
同时,加上重绘我们已有图形的方法。

import java.awt.Graphics;
import java.util.ArrayList;import javax.swing.JFrame;public class MyFrame extends JFrame{public ArrayList <Shape> date;public void paint (Graphics g){super.paint(g);//继承父类的方法//overwritefor(int i=0;i<date.size();i++){if((date.get(i)).GetLabel()=="直线"){g.setColor(date.get(i).GetColor());g.drawLine(date.get(i).GetFirstX(), (date.get(i)).GetFirstY(), (date.get(i)).GetSecondX(), (date.get(i)).GetSecondY());}else if((date.get(i)).GetLabel()=="矩形"){g.setColor(date.get(i).GetColor());g.drawRect(Math.min( date.get(i).GetFirstX(),  date.get(i).GetSecondX() ), Math.min( date.get(i).GetFirstY(),  date.get(i).GetSecondY() ), Math.abs( date.get(i).GetSecondX()- date.get(i).GetFirstX()  ),Math.abs( date.get(i).GetSecondY()- date.get(i).GetFirstY()  ));}else ;}}
}

#最后效果

用JAVA做一个简单的画图软件相关推荐

  1. 如何复制java卡,使用java做一个简单的集卡程序

    使用java做一个简单的集卡程序 本次设想的是要集齐4张卡,每张卡的概率都是25%,如果每个用户集齐需要多少次才能集合完毕 public class Test { public static void ...

  2. 用opengl编写一个简单的画图软件示例代码

    //用opengl编写一个简单的画图软件示例代码(存在闪烁问题) //本代码,抄写自一本教授opengl的书,可惜,里面的代码存在一些问题,导致不能正常显示,现在是增加了一些语句的代码 #includ ...

  3. 用python做一个简单GUI小软件

    用python做一个简单软件 前言 这是一个课设,用python做一个扫描王软件 我主要做的GUI部分,记录分享一下.也是第一次用python做小软件,python的方便果然是名不虚传 遇到问题 1. ...

  4. 用java实现一个简单远程监控软件_利用java实现一个简单的远程监控程序

    一般的远程监控软件都是用c或者c++等语言开发的,而使用java如何来实现相同的功能呢. 首先我们先介绍一下一个简单的远程监控程序的实现原理. 功能一,远程屏幕监视 (1) 必须要有监控端与被监控端, ...

  5. java做一个简单的数据库,哪个嵌入式数据库用Java写成一个简单的键/值存储?

    我最近问了一个关于Neo4j的问题,我有工作,似乎很好.它是可嵌入的,它是用Java编写的,没有(太)许多依赖. 然而,它是一个图形数据库,我不知道这是一个好主意或不使用它作为一个简单的键/值存储. ...

  6. 用java做一个简单的打字游戏

    Java也是可以做桌面程序的.只不过需要运行在装有JDK的电脑环境上,所以应用不是很广泛,但是用来提高自身的代码逻辑还是可以的!偶有一天看到金山的打字通,就想起何不做个简单的打字游戏用来练练手.于是就 ...

  7. 用java做一个简单记事本_用记事本写一个简单的java程序

    用记事本写一个简单的java程序 第一步: 安装好jdk,并设置好环境变量. 桌面-计算机(右键)-属性-高级系统设置-环境变量-path-在变量值后加上:和jdk安装路径加上(路径即为C:\Prog ...

  8. 用java做一个简单的万年历

    一个简单的万年历制作 简单介绍万年历的各功能实现: 1.首先键盘输入查询的年份和月份 Scanner sc = new Scanner(System.in); System.out.println(& ...

  9. java做一个简单的文件管理器

    前言 马上大四了,在大三结束后进入一家国企的研发组工作,短短的两个月实习大部分时间都是在自己学习.最近几天突然有点困倦,决定把之前做的一些东西分享出来. 目的与内容 运用面向对象程序设计思想,基于Ja ...

  10. 利用java做一个简单的计算器

    共两个类.还只是完成+.-.×.÷运算而已. GUI只是用了AWT,很简单,相信一看就能懂了. Calculator.java public class Calculator{ private Str ...

最新文章

  1. JSP九大内置对象...
  2. A*B Problem
  3. 详述白盒测试的逻辑覆盖的路径覆盖及其优缺点
  4. java serializeutils_java序列化 SerializeUtil
  5. 并发编程-concurrent指南-原子操作类-AtomicInteger
  6. python h5s文件 压缩_如何用python解压zip压缩文件
  7. mysql directx repair_[MySQL]快速解决is marked as crashed and should be repaired故障
  8. php递归函数原理,实例助你理解php递归函数原理及调用方法
  9. 哔哩下载姬(downkyi)v1.4.0 B站视频下载工具 哔哩哔哩视频解析
  10. About The Idea Of Flipped
  11. 32位 4G内存限制 linux,[操作系统]关于32位LINUX只支持4G内存的问题
  12. 中级病案信息技术计算机基础知识要点,病案信息技术职称考试基础知识复习
  13. 激励人生10张英文励志海报
  14. 2014在线旅游业发展的几大趋势
  15. root 启动mysql_非root用户随开机而启动mysql服务
  16. 最喜欢 - 十年生死两茫茫
  17. php可以用百度云加速吗,百度云加速免费版CDN使用方法(图文)
  18. android禁止手机访问某个ip,如何禁止手机访问某个网站
  19. BZOJ3926-[Zjoi20150]诸神眷顾的幻想乡
  20. 微星msi GS66黑苹果安装引导包(OpenCore for macOS Monterey)

热门文章

  1. linux命令键盘快捷键,如何将Linux命令设置成键盘快捷键
  2. 2021年1月PHP面试题总结
  3. PMBOK(第六版) PMP笔记——《十二》第十二章(项目采购管理)
  4. 商业计划书 创业者的“必修课程”
  5. DHCP工作原理和报文格式
  6. Word公式插件Mathpix Snip
  7. 鸡汤:干就完了!!!
  8. MATLAB-数组的使用
  9. 390计算机毕业设计
  10. OpenCV特征检测与匹配方法概览