定义容器

java界面开发主要运用了swing和awt库。主要分为容器类和组件类,为了实现一个能与用户交互的界面,往往需要定义一个底层容器-窗体,窗体负责承载组件类。窗体类的常用方法如下.

JFrame jf = new JFrame();
jf.setSize(900,900);//窗体大小
jf.setTitle("画图工具");//设置标题
jf.setLocationRelativeTo(null);  //居中显示
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //关闭窗体立刻退出进程jf.setVisible(true);//窗体可见

定义组件

定义完窗体后,需要给窗体加上自己想要的组件,比如按钮,文本等。例如定义一个按钮,最后将想要的组件添加到容器当中.当遇到一组组件时,可以创建一个特征数组,存储每个组件的特征,遍历特征数组,定义多个组件.

//单个组件
JButton jbu = new JButton(name[i]);
jf.add(jbu);
//多个组件String[] name = {"三角形","多边形","矩形","分形","山脉","立体山脉","曲线"};for(int i=0;i<name.length;i++) {JButton jbu = new JButton(name[i]);northPanel.add(jbu);jbu.addActionListener(mouse);}Color[] color = {Color.RED,Color.GREEN,new Color(100,100,100)};for(int i=0;i<color.length;i++) {JButton jbu = new JButton();jbu.setBackground(color[i]);jbu.setPreferredSize(new Dimension(30,30));northPanel.add(jbu);jbu.addActionListener(mouse);}

布局

定义完组件,或许你会想到组件会以何种效果呈现在窗体上呢,居中?挤在一起或者是四散而开?这也就是我们要关心的窗体布局方式,窗体布局默认是边界布局.可以定义四周大小,中间的center是占据窗体的剩余空间。画图小程序主要用了边界布局的方法.其次还有网格布局,流式布局,混合布局等.

从边界布局的图不难看出,我们需要进行区域的划分,这时我们又可以定义一个新的容器,取存储组件,再将这个小一些的容器放在底层容器中.例如画图板的功能界面:

JPanel northPanel = new JPanel();northPanel.setBackground(Color.GREEN);northPanel.setPreferredSize(new Dimension(0,60));jf.add(northPanel,BorderLayout.NORTH);

交互功能的实现

在定义完需要的组件后,当我们点击组件或者像画图软件那样拖动鼠标是没有反应的,也就是失去了交互功能.为了实现这一交互功能,我们需要定义一个监听器类,来获取我们用户操作的同时,实现操作结果展现在屏幕上.在类中我们可以定义方法来实现操作结果的展示.在画图小程序种,我们除了要按钮实现功能的切换,还要有一个画笔在画板上绘画:

//监听器:设计界面程序的交互功能
//a.事件源:当前动作所发生的组件(swing)
//b.监听器:鼠标监听器方法
//c.绑定事件处理类
button.addMouseListener(mouse);//a.b(c)//画笔定义在窗体可见之后
jf.setVisible(true);Graphics g = this.getGraphics();

监听器类需要继承多个鼠标方法的接口,并重写接口的所有方法.(一定要重写所有方法!)例如:

public class DrawMouse implements MouseListener{public void mouseClicked(MouseEvent e);/*** Invoked when a mouse button has been pressed on a component.* @param e the event to be processed*/public void mousePressed(MouseEvent e);/*** Invoked when a mouse button has been released on a component.* @param e the event to be processed*/public void mouseReleased(MouseEvent e);/*** Invoked when the mouse enters a component.* @param e the event to be processed*/public void mouseEntered(MouseEvent e);/*** Invoked when the mouse exits a component.* @param e the event to be processed*/public void mouseExited(MouseEvent e);}

在监听器类中,我们首先要拿到画笔,只有先拿到画笔这个对象我们才可以调用画笔的方法去画画,把结果展示在画板中,拿到画笔的方法有两种,一种是采用自定义的set方法,一种是类的构造函数,两种区别就是前者只能单一初始化,后者能为类的多个属性进行初始化.

//set方法public void setGr(Graphics gr){this.gr = gr;}//构造方法初始化属性public DrawMouse(Graphics gr){this.gr = gr;}

为了实现不同图形的画法,我们需要获取鼠标的点击结果.获取组件,因为getSource返回的是一个Object类,(为何返回Object类,原因系统点击一个组件后,并不清楚点击的究竟是什么类型的组件,Object作为所有子件的父类,返回时不会出错.)所以我们需要强转.来拿到按钮的方法,获取按钮的文本,如果是空就是颜色,不是空就是画图方法.

 public void actionPerformed(ActionEvent e){JButton jbu = (JButton)e.getSource();if(jbu.getText().equals("")) {color = jbu.getBackground();gr.setColor(color);}else{name=e.getActionCommand();}}

在拿到name后,我们就可以根据不同的name实现不同的画图方法.一类图形是画笔自带的,比如直线,矩形等.一类是需要自己定义画的,这类图形最主要是记录坐标点,实现多个点的直线连接.三角形和多边形都是先线在点的方法,利用标记位的方法,利用flag==1先画出一条直线,在通过鼠标点击,获取下一个坐标点,在把上一个直线的坐标点和获取到的新坐标点连线.此外多边形在最后一条边时只需要双击,实现最后一个点和第一个点的连线.

 public class DrawMouse implements MouseListener, ActionListener , MouseMotionListener {//引用传递private Graphics gr;  //保存传递过来的画笔对象private int x1,y1,x2,y2,x3,y3;private String name;//标记位,用来控制代码的执行过程private int flag = 1;private Color color;public ArrList<Shape> shape=new ArrList<>();private int index=0;private boolean flag1=false;//定义set 方法,初始化属性//this 表示本类对象public void setGr(Graphics gr){this.gr = gr;}//构造方法初始化属性public DrawMouse(Graphics gr){this.gr = gr;}public DrawMouse(){}public ArrList<Shape> getShape(){return shape;}public void actionPerformed(ActionEvent e){JButton jbu = (JButton)e.getSource();if(jbu.getText().equals("")) {color = jbu.getBackground();gr.setColor(color);}else{name=e.getActionCommand();}}public void mouseClicked(MouseEvent e){System.out.println("点击");x3 = e.getX();y3 = e.getY();if("三角形".equals(name)){gr.drawLine(x1,y1,x3,y3);gr.drawLine(x2,y2,x3,y3);Shape s=new Shape(x1,y1,x2,y2,x3,y3,"三角形",color);shape.add(index++,s);flag=1;}if("多边形".equals(name)){gr.drawLine(x2,y2,x3,y3);Shape s=new Shape(x2,y2,x3,y3,"多边形",color);x2 = x3;y2 = y3;shape.add(index++,s);if(e.getClickCount() == 2){gr.drawLine(x1,y1,x3,y3);Shape s1=new Shape(x1,y1,x3,y3,"多边形",color);shape.add(index++,s1);flag=1;}}}public void Rect(int x1,int y1,int x2,int y2,int x3, int y3,int count){gr.drawLine(x1, y1, x2, y2);gr.drawLine(x2, y2, x3, y3);gr.drawLine(x3, y3, x1, y1);gr.drawLine((x1+x2)/2,(y1+y2)/2,(x1+x3)/2,(y1+y3)/2);gr.drawLine((x2+x3)/2,(y2+y3)/2,(x2+x1)/2,(y2+y1)/2);gr.drawLine((x3+x1)/2,(y3+y1)/2,(x3+x2)/2,(y3+y2)/2);if(count==0)return;count--;Rect(x1,y1,(x1+x3)/2,(y1+y3)/2,(x2+x1)/2,(y1+y2)/2,count);Rect(x2,y2,(x1+x2)/2,(y1+y2)/2,(x2+x3)/2,(y2+y3)/2,count);Rect(x3,y3,(x1+x3)/2,(y1+y3)/2,(x2+x3)/2,(y2+y3)/2,count);}double rate=0.5;int height=500;int xx,yy,highher;Random random=new Random();public void Mountain(int x1,int y1,int x2,int y2, int height){if(Math.abs(x1-x2)<=1 || height==0)gr.drawLine(x1,y1,x2,y2);else {xx=(x1+x2)/2;yy=(y1+y2)/2;highher= random.nextInt( 2*height)-height;int height1 = (int) (height * rate);Mountain(xx,yy+highher,x2, y2, height1);Mountain(x1, y1, xx, yy+highher, height1);}}public void mousePressed(MouseEvent e){System.out.println("按下");//获取当前坐标值if(flag == 1) {x1 = e.getX();y1 = e.getY();}}int[][] Point=new int[8][2];int count=10,k=0;public void mouseReleased(MouseEvent e){System.out.println("松开");if(flag == 1) {x2 = e.getX();y2 = e.getY();}//绘制图形
//        gr.drawLine(x1,y1,x2,y2);//绝对值int w = Math.abs(x1-x2);int h = Math.abs(y2-y1);if("矩形".equals(name)){gr.drawRect(x1,y1,w,h);Shape s=new Shape(x1,y1,w,h,"矩形",color);shape.add(index++,s);}if(("三角形".equals(name) || "多边形".equals(name)) && flag == 1){gr.drawLine(x1,y1,x2,y2);Shape s=new Shape(x1,y1,x2,y2,"多边形",color);shape.add(index++,s);flag++;}if("分形".equals(name)){Point[k][0]=e.getX();Point[k][1]=e.getY();k++;if(k==3){int x1=Point[0][0];int y1=Point[0][1];int x2=Point[1][0];int y2=Point[1][1];int x3=Point[2][0];int y3=Point[2][1];Rect(x1,y1,x2,y2,x3,y3,count);}}if("山脉".equals(name)){Point[k][0]=e.getX();Point[k][1]=e.getY();k++;if(k==2){int x1=Point[0][0];int y1=Point[0][1];int x2=Point[1][0];int y2=Point[1][1];Mountain(x1,y1,x2,y2,height);}}}public void mouseEntered(MouseEvent e){}public void mouseExited(MouseEvent e){}public void mouseDragged(MouseEvent e) {if("曲线".equals(name)) {x2 = e.getX();y2 = e.getY();gr.drawLine(x1, y1, x2, y2);Shape s=new Shape(x1,y1,x2,y2,"曲线",color);shape.add(index++,s);x1 = x2;y1 = y2;}}public void mouseMoved(MouseEvent e) {}
}

paint方法重写

看完上述代码,你可能会不理解,为什么有shape?shape是什么?

其实当你画完图准备最小化,或者觉得窗体小的时候,你想鼠标拉大窗体的时候,你会发现图不见了!,因为当你改变窗体的时候,窗体会调用paint方法,而paint方法会覆盖我们的画图结果,因此我们需要在paint方法中保留我们画图的结果,换句话说就是我们在监听器的操作,复制到paint方法中保存.

所以我们需要定义一个Shape类来保存不同的图形

public class Shape {public int x1,y1,x2,y2,x3,y3;public String name;public Color color;public Shape(int x1,int y1,int x2,int y2,String name,Color color) {this.x1=x1;this.y1=y1;this.x2=x2;this.y2=y2;this.name=name;this.color=color;}public Shape(int x1, int y1, int x2, int y2,int x3,int y3 ,String name, Color color) {this.x1 = x1;this.y1 = y1;this.x2 = x2;this.y2 = y2;this.x3 = x3;this.y3 = y3;this.name = name;this.color = color;}public void drawShape(Graphics g){if(name.equals("三角形")){g.setColor(this.color);g.drawLine(x1,y1,x2,y2);g.drawLine(x2,y2,x3,y3);g.drawLine(x1,y1,x3,y3);}if(name.equals("矩形")){g.setColor(this.color);g.drawRect(x1,y1,x2,y2);}if(name.equals("多边形")){g.setColor(this.color);g.drawLine(x1,y1,x2,y2);}if(name.equals("曲线")){g.setColor(this.color);g.drawLine(x1,y1,x2,y2);}}
}

在UI类中我们需要继承Jpanel,并把监听器类获得的shape集合传给UI类,给paint方法重写使用.

public class DrawUI extends JPanel{private ArrList<Shape> shapeArr;//1.显示界面public void showUI(){//窗体:默认就是边框布局BorderLayoutJFrame jf = new JFrame();jf.setSize(900,900);jf.setTitle("画图工具");jf.setLocationRelativeTo(null);  //居中显示jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //退出进程//        jf.setLayout(new FlowLayout());//边框布局
//        jf.setLayout(new BorderLayout());//功能面板JPanel northPanel = new JPanel();northPanel.setBackground(Color.GREEN);northPanel.setPreferredSize(new Dimension(0,60));jf.add(northPanel,BorderLayout.NORTH);DrawMouse mouse = new DrawMouse();String[] name = {"三角形","多边形","矩形","分形","山脉","立体山脉","曲线"};for(int i=0;i<name.length;i++) {JButton jbu = new JButton(name[i]);northPanel.add(jbu);jbu.addActionListener(mouse);}Color[] color = {Color.RED,Color.GREEN,new Color(100,100,100)};for(int i=0;i<color.length;i++) {JButton jbu = new JButton();jbu.setBackground(color[i]);jbu.setPreferredSize(new Dimension(30,30));northPanel.add(jbu);jbu.addActionListener(mouse);}//画图面板
//        JPanel drawPanel = new JPanel();this.setBackground(Color.WHITE);jf.add(this,BorderLayout.CENTER);jf.setVisible(true);//3.画笔:自定义内容显示在哪个组件上,画笔就从该组件上获取//从窗体上获取画笔对象,一定要在窗体显示可见之后Graphics g = this.getGraphics();//监听器:设计界面程序的交互功能//a.事件源:当前动作所发生的组件(swing)//b.监听器:鼠标监听器方法//c.绑定事件处理类//数据类型//1.基本类型(8个)//2.引用类型(自定义类型):类(class),接口(interface),数组//2.给窗体添加鼠标监听器方法//接口不能直接创建对象:重新定义类继承接口重写接口中的抽象方法this.addMouseListener(mouse);this.addMouseMotionListener(mouse);//把画笔对象传递给DrawMouse类mouse.setGr(g);shapeArr=mouse.getShape();}public void paint(Graphics g){super.paint(g);for(int i=0;i<shapeArr.size();i++){if(shapeArr.get(i)!=null){if(shapeArr.get(i).name.equals("三角形"))shapeArr.get(i).drawShape(g);else if(shapeArr.get(i).name.equals("矩形"))shapeArr.get(i).drawShape(g);else if(shapeArr.get(i).name.equals("多边形"))shapeArr.get(i).drawShape(g);elseshapeArr.get(i).drawShape(g);}}}//主函数public static void main(String[] args){DrawUI ui = new DrawUI();ui.showUI();}
}

这样我们就可以实现改变窗体的时候,画图结果也能保存下来.

效果图:

java学习-画图小程序相关推荐

  1. 用JAVA写一个画图小程序(JAVA 大作业)

    第一次写博客 且是稍微大点的程序 看看就行 重新写的在这,更加清晰明了:点击进入:用JAVA写一个画图小程序(JAVA 大作业)重排版本 设计思路 首先我直接去了Windows自带画图程序去实践模拟, ...

  2. java与微信小程序通讯_java与微信小程序实现websocket长连接

    本文实例为大家分享了java与微信小程序实现websocket长连接的具体代码,供大家参考,具体内容如下 背景: 需要在小程序实现地图固定坐标下实时查看消息 java环境 :tomcat7 jdk1. ...

  3. java中的基本小程序_12个用Java编写基础小程序经典案例(收藏篇)

    原标题:12个用Java编写基础小程序&经典案例(收藏篇) 如果是刚接触或者刚学习java,练习一些基础的算法还是必须的,可以提升思维和语法的使用. 1.输出两个int数中的最大值 impor ...

  4. Java实现微信小程序校验图片是否含有违法违规内容

    文章目录 1.Java实现微信小程序校验图片是否含有违法违规内容(security.imgSecCheck) 2.接口文档简述 3.Java实现对接接口 4.压缩图片(Thumbnails) 5.整合 ...

  5. 【程序源代码】微信小程序商城管理系统(Java后台+微信小程序)最新版

    关键字:微信小程序 商城系统 02 - [技术框架] 微信小程序商城管理系统(Java后台+微信小程序) 基于Spring+Vue+Mysql+Redis主流技术开发框架集成开发的微信商场管理系统:其 ...

  6. 计算机毕业设计Java课堂管理系统小程序用户端(源码+mysql数据库+系统+lw文档)

    计算机毕业设计Java课堂管理系统小程序用户端(源码+mysql数据库+系统+lw文档) 计算机毕业设计Java课堂管理系统小程序用户端(源码+mysql数据库+系统+lw文档) 本源码技术栈: 项目 ...

  7. 小程序学习 - 01小程序简介+微信小程序基础

    小程序简介 小程序是一个全新的.轻量级的移动端应用. 起源 在小程序出现之前的移动端开发的解决方案有: Android iOS Windows Phone - 后来退出历史舞台 移动端开发发展了一段时 ...

  8. 600多个微信小程序源码_点餐系统的开发,java后台+微信小程序 实现完整的餐厅点餐系统。微信扫码点餐小程序源码讲解...

    今天来给大家讲解一个完整的微信扫码点餐项目.java后台+微信小程序实现点餐系统. 后台技术选型: JDK8 MySQL(需要5.6以上) Spring-boot Spring-data-jpa Lo ...

  9. 微信小程序实现lot开发01 学习微信小程序 helloworld

    最近走进一个新项目的任务里,主要的任务是实现用微信小程序利用websocket使用mqtt协议走网络控制继电器(其实在生活中这个技术已经普及了,我们用的充电桩扫码充电,我们学校里的饮水机扫码接水以及我 ...

最新文章

  1. ssh tar 命令把远程文件拉回来或推过去
  2. python主要就业方向-四种Python高薪就业方向
  3. python xlrd简单读取excel
  4. 热烈祝贺Polymer中文组织站点上线
  5. lisp改图元字体式样_一个更改尺寸类型的LISP程序
  6. 配置web项目session永不超时
  7. ElasticSearch Pipeline 为新增数据设置更新时间
  8. 3.5 定向搜索的误差分析
  9. java代码内创建mysql索引_点评阿里JAVA手册之MySQL数据库 (建表规约、索引规约、SQL语句、ORM映射)...
  10. 计算机病毒不会直接危害计算机用户的健康,北京语言大学入学测试机考(高起点)计算机基础模拟题...
  11. 用matlab的dsp软件仿真,基于MATLAB的DSP软件仿真
  12. VMware Workstation Pro安装
  13. PC安装Linux系统傻瓜式教程
  14. 阿里巴巴矢量图标库使用步骤
  15. linux开源社区贡献代码,4岁小萝莉向Linux内核贡献代码修复「漏洞」而且代码已经合并到内核...
  16. 手把手教你用docker 搭建zoolkepper 和 dubbo 的测试环境
  17. 手机令牌 dKey M6介绍
  18. PowerJob 的自实现高可用方案,妙妙妙!
  19. 基于数字温度传感器的数字温度计 华氏度和摄氏度
  20. java实现hj协议_环保 HJ212协议解析

热门文章

  1. Android学习笔记——APP页面转换与Intent学习
  2. 计算机培训教学准备,计算机教学计划锦集五篇
  3. Pycharm新手使用教程(详解)
  4. 云智慧智能研究院:2022年智能运维发展八大趋势
  5. 新一代人工智能产业八大主要应用场景研判
  6. 2020年全球及中国术后镇痛药行业市场现状分析,非阿片类药物需求不断增长「图」
  7. 《西瓜书》笔记整理——第一章
  8. FastBoot BootLoader Recovery 模式学习
  9. 基于百度地图API在AI Studio上的卫星地图块图像处理与分类
  10. 产品架构图到底是怎么“画”出来的?