`

画图板实现和优化总结

阅读更多

画图板实现和优化总结

       来蓝杰参加培训的第一个完整意义上但还远不满意的项目——画图板的实现及优化。个人基础较差,技术欠佳,感谢老师和室友的帮助和指导,才使得我这个丑丑的简单画图板最终实现了。

       一、简单画图板的初步实现

         1、画图板面板的实现

       在JFrame上通过RadioButton的轻量级组件实现面板的制作。

public class DrawingPad extends javax.swing.JFrame{
     /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	//主方法
	public static void main (String[] args){
		DrawingPad dp=new DrawingPad();
	    dp.initDP();
	}
	//初始化窗体Ailse画板1.0的方法
	public void initDP(){
		this.setTitle("AilseDrawingPad1.0");
		this.setSize(600,500);
		this.setDefaultCloseOperation(3);
		//为窗体定义并实例流式布局
		java.awt.FlowLayout fl=new java.awt.FlowLayout();
		this.setLayout(fl);
        //创建一个按钮组
		javax.swing.ButtonGroup group=new javax.swing.ButtonGroup();
		//为窗体定义、实例并添加单选框
        javax.swing.JRadioButton line=new javax.swing.JRadioButton("StrightLine");
		this.add(line);
		javax.swing.JRadioButton rect=new javax.swing.JRadioButton("rect");
		this.add(rect);
		javax.swing.JRadioButton oval=new javax.swing.JRadioButton("oval");
		this.add(oval);
		javax.swing.JRadioButton arcu=new javax.swing.JRadioButton("arcu");
		this.add(arcu);
		javax.swing.JRadioButton rrect=new javax.swing.JRadioButton("rrect");
		this.add(rrect);
		javax.swing.JRadioButton arcd=new javax.swing.JRadioButton("arcd");
		this.add(arcd);
		//设置单选框动作命令
		line.setActionCommand("line");		
		rect.setActionCommand("rect");
        oval.setActionCommand("oval");
        arcu.setActionCommand("arcu");
        rrect.setActionCommand("rrect");
        arcd.setActionCommand("arcd");

 2、画图板鼠标监听

面板准备好后,我们需要考虑画在什么地方和怎么画的问题。设置以整个窗体为画布,和通过对鼠标动作的监听来控制画出图形。通过两点坐标来实现画直线,画矩形,椭圆等功能。

画板中要添加入监听器:

  //创建并定义一个画布,窗体在屏幕中所占区域为画布
        java.awt.Graphics g=this.getGraphics(); 
        
      //创建并实例一个鼠标监听对象
    	DPMouseListener dpml=new DPMouseListener(g,group);
    	this.addMouseListener(dpml);
 

监听器:

package DrawingPad;

import java.awt.event.MouseEvent;

public class DPMouseListener implements java.awt.event.MouseListener{
	private int x1,x2,y1,y2; 
	private String kind;
	private java.awt.Graphics g;
	private javax.swing.ButtonGroup group;
	
	public DPMouseListener(java.awt.Graphics g,javax.swing.ButtonGroup group){
		this.g=g;
		this.group=group;
	}
	
	/**
     * 单击鼠标(在同一地方按下和释放鼠标)
     */
    public void mouseClicked(MouseEvent e){
    	//System.out.println("mouseClicked");
    }

    /**
     * 按下鼠标
     */
    public void mousePressed(MouseEvent e){
    	System.out.println("mousePressed");
    	//设置默认选项
    	
    	//判断所选图形并选所对应命令
    	kind=group.getSelection().getActionCommand();
    	System.out.println("选择的图形是:"+kind);
    	x1=e.getX();
    	y1=e.getY();
    }

    /**
     *释放鼠标
     */
    public void mouseReleased(MouseEvent e){
    	System.out.println("mouseReleased");
        x2=e.getX();
        y2=e.getY();
        if("line".equals(kind)){
        	g.drawLine(x1, y1, x2, y2);
        }
        else if("rect".equals(kind)){
        	g.drawRect((x1<x2?x1:x2), (y1<y2?y1:y2), Math.abs(x1-x2),Math.abs(y1-y2));
        }
        else if("oval".equals(kind)){
        	g.drawOval((x1<x2?x1:x2), (y1<y2?y1:y2), Math.abs(x1-x2), Math.abs(y1-y2));
        }
        else if("arcu".equals(kind)){
        	g.drawArc((x1<x2?x1:x2), (y1<y2?y1:y2), Math.abs(x1-x2), Math.abs(y1-y2),0,-180);
        }
        else if("rrect".equals(kind)){
        	g.drawRoundRect((x1<x2?x1:x2), (y1<y2?y1:y2), Math.abs(x1-x2), Math.abs(y1-y2), 35, 35);
        }
        else if("arcd".equals(kind)){
        	g.drawArc((x1<x2?x1:x2), (y1<y2?y1:y2), Math.abs(x1-x2), Math.abs(y1-y2),0,180);
        }
    }

 在画的过程当中,遇到许多问题:

1)矩形等只能从左上角向右下角画。

通过观察发现,无论我怎么画,画出的矩形都是以鼠标点下时所获得的点的坐标作为矩形的左上定点。而且,正常情况下,我们所画出的矩形的特点是左上的定点x坐标总是所有点中最小的,而y坐标也是一样。结合以上两点,首先想到了通过两次比较x坐标和y坐标就可以解决。后来向室友学习,发现在学习c时使用的问号表达式在java中同样可以使用,且完全可以替代两次比较。代码见上图。

2)arc函数画弧线

初始时,只实现了直线、矩形、和椭圆功能,在拓展功能时,发现了arc函数。查询jdk API后知道其前四个参数和矩形的是类似的,只是后两个参数中,前一个是初始角度,而后一个是转过的角度,所画的圆弧就是以这两个角度之间的弧。考虑我想画个笑脸娃娃,so就定义了+/-180度的转角,得到了开口向上的弧(转角=-180°)和开口向下的弧(转角=180°)。同理,应该可以实现特殊角度弧线的绘制。

 

      二、简单画图板的重绘

所谓重绘就是,我最小化我的面板后,不至于因为内存中没有留下而丢失了。就是将画的形状保存在内存中,然后在最小化或拖出屏幕后,再取出这些形状。想起了学的c中的动态数组,龙哥说java中有一种数据结构叫队列,原理很像动态数组。画画总是需要颜色的,而颜色和绘制形状时的两点坐标不是同一种数据类型,就要定义两个队列来存储了。于是,我们采用了顶层类(貌似是叫这个)——shape形状抽象类,将两点坐标和颜色定为形状抽象类的属性,要求所有的形状类都要继承该类。然后把所绘制的形状以形状抽象类的对象的形式存储入内存。

鼠标监听器:
 public void mouseReleased(MouseEvent e){
    	System.out.println("mouseReleased");
        x2=e.getX();
        y2=e.getY();
        
        shapes sh=null;
        if("line".equals(kind)){
        	//创建直线对象
        	sh=new Line(x1, y1, x2, y2,color);
        	
        }
        else if("rect".equals(kind)){
        	sh=new rect(x1,x2,y1,y2,color);
        }
        else if("oval".equals(kind)){
        	sh=new oval(x1,y1,x2,y2,color);
        }
        else if("arcu".equals(kind)){
        	sh=new arcu(x1,y1,x2,y2,color);
        }
        else if("rrect".equals(kind)){
        	sh=new rrect(x1,y1,x2,y2,color);
        }
        else if("arcd".equals(kind)){
        	sh=new arcd(x1,y1,x2,y2,color);
        }
    
        //绘制形状
        sh.draw(g);
        //保存形状
        shape.add(sh);
        
    }

    形状抽象类:
package REDrawingPad;

import java.awt.Color;
import java.awt.Graphics;
/**
 * 形状抽象类,所有的形状类都必须继承该类
 *
 */ 
public abstract class shapes {
    int x1,x2,y1,y2;
    Color color;
    //绘制形状的方法
    public abstract void draw(Graphics g) ;
}

 直线形状类:

package REDrawingPad;

import java.awt.Color;
import java.awt.Graphics;
/**
 * 形状抽象类,所有的形状类都必须继承该类
 *
 */
public abstract class shapes {
    int x1,x2,y1,y2;
    Color color;
    //绘制形状的方法
    public abstract void draw(Graphics g) ;
}
面板:

//重写父类中窗体绘制方法
      public void paint(Graphics g){
        //调用父类的方法,绘制窗体
        super.paint(g);
        //调用绘制形状的方法
        redraw(this.g);
    }
      //重新绘制形状的方法
      public void redraw(Graphics g){
        //遍历队列
        for(int i=0;i<sh.size();i++){
            //取出形状
            shapes shape=sh.get(i);
            //绘制
            shape.draw(g);
        }
    }
}

绘制后和恢复窗口后的存储和取出都要用到队列,队列中我定义了添加(add)、插入(addx)、全部删除(delectAll)、取出(get)、删除指定元素(delect)、修改(modify)和size方法。具体会在数据结构的优化的总结中叙述。

 

附:简单画图板的结果:


 

 

额……有点丑啊!呵呵!不是我画的啊!哈哈!

  • 大小: 14.6 KB
分享到:
评论
1 楼 JuliaAilse 2011-10-22  
额……有点流水账的感觉啊!不行啊!下次要总结清晰明了,有条理些。重点是应该写的是关键代码,不是全部!

相关推荐

    java学习小总结——画图板制作(附代码)

    在Java学习过程中,创建一个简单的画图板是一个经典的练习项目,它可以帮助我们深入理解图形用户界面(GUI)的构建和事件处理机制。本篇小结将聚焦于如何使用Java实现一个基本的画图板,同时提供相关的源码分析。 1...

    openGL画图板实现简单画图功能

    总结,这个基于C++和OpenGL的画图板项目是一个很好的实践,它涵盖了OpenGL的基本概念、窗口管理、事件处理以及简单的图形绘制。通过学习和实现这样的项目,开发者可以深入理解OpenGL的工作流程,并为更复杂的3D图形...

    画图板总结

    这篇博文主要围绕一个特定的画图板应用进行总结,探讨其功能、实现原理以及可能的应用。 首先,我们要理解画图板的基本功能。一个标准的画图板通常包括颜色选择、线条粗细调整、形状绘制(如圆形、矩形、直线等)、...

    java画图板的总结

    在Java编程语言中,画图板(Canvas)是图形用户界面(GUI)开发的一个关键组件。它是Java AWT(Abstract Window Toolkit)库的一部分,用于在窗口上绘制图形。Canvas类继承自Component,允许程序员直接在屏幕上进行...

    vc++简易画图板

    实验报告通常会包含以下部分:项目概述、设计思路、关键代码解析、功能实现、遇到的问题及解决方案、性能优化以及总结。这有助于学生对整个项目的理解和反思,加深对C++和MFC的理解。 在项目中,可能会涉及到的文件...

    画图板(C#源码)(有点像Windows画图)

    《C#实现简易画图板:GraphicalCS详解》 在计算机编程领域,尤其是图形用户界面(GUI)的开发中,模拟系统自带功能是常见的学习和实践方式。本篇文章将详细探讨一个用C#编写的简易画图板项目,这个项目名为...

    C# 实现画图软件

    在本文中,我们将深入探讨如何使用C#编程...总结,使用C#开发画图软件涉及用户界面设计、事件处理、绘图逻辑、调色板和保存功能的实现。通过理解这些核心概念并进行实践,开发者可以创建出一款功能齐全的个人画图应用。

    QT简易画图板程序

    总结来说,"QT简易画图板程序"是一个利用Qt库和C++语言实现的图形绘制应用,它展示了如何使用Qt来创建交互式的图形界面,并提供了一种基础的绘图体验。对于初学者来说,这是一个了解Qt和C++图形编程的好项目,而对于...

    huatu.rar_JAVA画图面板_绘画面板

    总结来说,"JAVA画图面板_绘画面板"涉及Java GUI编程中的自定义绘图技术,包括使用`Canvas`或`JPanel`创建画布,通过`Graphics`对象进行绘图,以及处理用户交互。"huatu.rar"中的内容很可能是为了帮助开发者理解这些...

    简单画板实现

    总结起来,这个“简单画板实现”项目结合了自定义View和SurfaceView的优势,提供了用户可以直接在屏幕上绘图的功能。通过处理触摸事件、路径绘制、颜色和宽度设置,以及撤销/重做机制,这个画板为用户提供了丰富的...

    C#实现功能强大画图器

    在本文中,我们将深入...总结来说,实现一个C#画图器需要掌握C#编程、GUI设计、图形绘制以及用户交互等多方面技能。通过不断学习和实践,我们可以创建出一个功能齐全、易用的画图应用程序,满足用户的基本绘图需求。

    Android-LittleDrawBoardPC端是基于Socket实现的android端和PC端同步绘画板

    总结起来,"Android-LittleDrawBoardPC端"项目展示了如何运用Socket技术实现在Android和PC间的实时同步绘画,这不仅是对跨平台协作的一种创新尝试,也为开发者提供了学习和实践网络编程、多平台同步以及用户交互设计...

    java画图(双缓冲)

    例如,以下是一个简单的双缓冲画图板实现的概要: ```java import javax.swing.*; import java.awt.*; import java.awt.geom.*; public class DrawBoard extends JPanel { private Graphics2D offscreenGraphics;...

    VC++编写的强大画板程序

    键盘快捷键的实现可能涉及到Windows消息循环和消息映射。当用户按下键盘上的特定键时,程序会捕获到相应的键盘消息(如WM_KEYDOWN),然后通过消息映射机制调用相应的处理函数,执行对应的绘图操作。例如,Ctrl+L...

    PCB画图经典技巧总结

    在电子设计领域,PCB(Printed Circuit Board)布局与布线是至关重要的步骤,它直接影响到电路的电气性能和稳定性。以下是一些关于PCB设计的...在实践中,不断学习和总结,结合具体项目的需求,才能设计出优秀的PCB板。

    画板总结

    【标题】:“画板总结”通常指的是一个关于图形绘制或设计工具的项目,可能是对一个电子画板软件或在线画图平台的开发经验、功能特点和技术实现的总结。在这个项目中,作者可能分享了他们在创建这样一个画板应用过程...

    PictureBox画图.rar

    总结起来,通过C#的WinForm和PictureBox控件,我们可以创建一个简单的画板应用,用户可以自由地进行绘图。通过处理鼠标事件并利用Graphics和Pen对象,可以实现基本的绘图功能。对于初学者来说,这是一个很好的练习...

    MFC单文档画图程序 MFC编程

    在本文中,我们将深入探讨如何使用Microsoft Foundation Class (MFC)库来创建一个单文档界面(SDI)...在实际开发过程中,可能还需要考虑性能优化、错误处理、多线程支持等问题,这些都是提升程序质量和用户体验的关键。

    实验一画图(SDK)自由画线

    开发者可以通过打开这个项目文件来查看和学习实现画图工具的详细代码。代码中可能会包含事件处理函数,比如鼠标点击和移动事件,用于控制画线的开始和结束;以及可能的颜色选择和线条样式设置的逻辑。 总结起来,这...

Global site tag (gtag.js) - Google Analytics