`
人生难得糊涂
  • 浏览: 117381 次
社区版块
存档分类
最新评论

仿XP画图板开发-1

 
阅读更多

用JAVA做仿XP画图板 ,前前后后可以算是做了三次,现在做了个半成品产品出来,现在贴出第一个版本的核心代码  也把开发过程中遇到的问题写下了  画图板还会继续做 到时候会更新内容 欢迎交流 欢迎拍砖

在开发画图板的过程中 ,遇到的最大问题就是如何把绘画的各种不同图形 保存下来

在我的第一个画图板版本中 我是用一个定义了一个图形类 Drawing  他有若干个子类(直线 矩形 椭圆等等),

然后我定义了一个Drawing[] 数组,itemList 。 每次在鼠标释放时添加一个Drawing对象到itemlist数组中,在paint方法中 对itemlist数组遍历 绘画存在其中的所有图形。

贴个截图



 

以下是代码(画布)DrawPanel,和Drawing类的代码  

DrawPanel

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

import java.awt.event.MouseMotionAdapter;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import java.util.Random;

//绘图区类(各种图形的绘制和鼠标事件)
public class DrawPanel extends JPanel {
	Drawing[] itemList = new Drawing[5000];; // 绘制图形类
	BottomToolBar bottombar;
	BottomPanel bottomPanel;
	int index = 0;// 当前已经绘制的图形数目
	Random rd = new Random();// 喷雾的随机点生成器
	int reSize=0;//用于设置拖动事件是否改变panel大小
	public DrawPanel() 
	{
		setBackground(Color.white);// 设置绘制区的背景是白色
		addMouseListener(new MouseListener());// 添加鼠标事件
		addMouseMotionListener(new MouseMotion());
		createNewitem();
	}
	/**
	 * 将JFrame的下部面板工具栏传递给DrawPanel
	 * @param bottombar
	 */
	public void setBar(BottomToolBar bottombar)
	{
		this.bottombar=bottombar;
	}
	/**
	 * 将下部信息面板传递个DrawPanel
	 * @param bottomPanel
	 */
	public void setBottomPanel(BottomPanel bottomPanel)
	{
		this.bottomPanel=bottomPanel;
	}
	/**
	 * 画图方法
	 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		Graphics2D g2d = (Graphics2D) g;// 定义随笔画
		int j = 0;
		//g2d.drawImage(Save4Bit.img, null, 0, 0);
		if(DrawSet.img!=null)
			g2d.drawImage(DrawSet.img,null,0,0 );
		while (j <= index) {
			//System.out.println("this is  repaint");
			itemList[j].draw(g2d);
			j++;
		}

	}

	// 新建一个图形的基本单元对象的程序段
	public void createNewitem() {
		//System.out.println(DrawSet.drawTool);
		switch (DrawSet.drawTool) {
		case 2:
			itemList[index] = new Rubber();
			break;
		case 4:
			itemList[index] = new TiQu();
			break;
		case 6:
			itemList[index] = new Pencil();
			break;
		case 8:
			itemList[index] = new PenWu();
			break;
		case 9:
			itemList[index] = new Word();
			System.out.println("创建>>>9");
			break;
		case 10:
			itemList[index] = new Line();
			break;
		case 12:
			itemList[index] = new Rect();
			break;
		case 14:
			itemList[index] = new Oval();
			break;
		case 15:
			itemList[index] = new RoundRect();
			break;
		}

	}

	// TODO 鼠标事件MouseA类继承了MouseAdapter
	// 用来完成鼠标的响应事件的操作
	class MouseListener extends MouseAdapter {
		public void mousePressed(MouseEvent me) {
			itemList[index].strokeWidth = DrawSet.strokeWidth;
			itemList[index].x1 = itemList[index].x2 = me.getX();
			itemList[index].y1 = itemList[index].y2 = me.getY();
		
			// 判断是鼠标左键还是右键设置颜色
			int clickCount = me.getButton();
			if (clickCount == 1)
				itemList[index].pColor = DrawSet.drawColor1;
			if (clickCount == 3)
				itemList[index].pColor = DrawSet.drawColor2;
			// 如果当前选择为随笔画或橡皮擦 ,则进行下面的操作
			if (DrawSet.drawTool == 6 || DrawSet.drawTool == 2) {
				itemList[index].x1 = itemList[index].x2 = me.getX();
				itemList[index].y1 = itemList[index].y2 = me.getY();
			}
			if (DrawSet.drawTool == 8) {
				int r = (int) (DrawSet.strokeWidth + 2) * 5;
				int pointNumber = (r * 2);
				itemList[index].r1 = new int[pointNumber];
				itemList[index].r2 = new int[pointNumber];
				itemList[index].pointNumber = pointNumber;
				for (int i = 0; i < pointNumber; i++) {
					itemList[index].r1[i] = rd.nextInt(r) - r;
					itemList[index].r2[i] = rd.nextInt(r) - r;
				}

			}
			// 如果当前选中的是输入文字
			else if (DrawSet.drawTool == 9) {
				itemList[index].str=JOptionPane.showInputDialog(null, "请输入文字"+index);//这里设置了str
				itemList[index].x1 = me.getX();
				itemList[index].y1 = me.getY();
				index++;
				createNewitem();// 创建新的图形的基本单元对象
				repaint();
			}
			else if(DrawSet.drawTool == 4)//提取
			{
				int x = me.getXOnScreen();
				int y = me.getYOnScreen();
//				System.out.println("ScreenX: "+x+" ScreenY: "+y);
//				System.out.println("X: "+me.getX()+" Y: "+me.getY());
				Robot robot;
				try {
					robot = new Robot();
					//要用就绝对坐标 这是另一种获取颜色的方法
//					int c = 0;
//					Rectangle screenRect = new Rectangle(x,y, 1,1);
//					BufferedImage img=robot.createScreenCapture(screenRect);
//					c=img.getRGB(0, 0);
//					bottombar.setFirstLabel(new Color(c));//设置下部颜色显示面板
					
					Color c=robot.getPixelColor(x,y);//x y 为屏幕绝对坐标
					bottombar.setFirstLabel(c);
					DrawSet.drawColor1=c;
				} catch (AWTException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				
				
			}
		}

		public void mouseReleased(MouseEvent me) {
				repaint();
				index++;
				createNewitem();// 创建新的图形的基本单元对象
				DrawPanel.this.bottomPanel.hwLabel.setText("");
		}

	}

	// 鼠标事件MouseB继承了MouseMotionAdapter
	// 用来处理鼠标的滚动与拖动
	class MouseMotion extends MouseMotionAdapter {
		public void mouseDragged(MouseEvent me)// 鼠标的拖动
		{
			if(reSize==1)
			{
				me.getX();
				me.getY();
				DrawPanel.this.setSize(me.getX(), me.getY());
				return ;
			}
			//显示信息
			int showW=Math.abs(itemList[index].x2 - itemList[index].x1);
			int showH=Math.abs(itemList[index].y2 - itemList[index].y1);
			DrawPanel.this.bottomPanel.hwLabel.setText(showW+" , "+showH);
			//画图
			if (DrawSet.drawTool == 6 || DrawSet.drawTool == 2) {
				// // 为什么这里断断续续的
				// itemList[index].x2 = itemList[index].x1 =me.getX();
				// itemList[index].y2 = itemList[index].y1 = me.getY();
				itemList[index].x1 = itemList[index].x2;
				itemList[index].y1 = itemList[index].y2;
				itemList[index].x2 = me.getX();
				itemList[index].y2 = me.getY();
			} else {
				itemList[index].x2 = me.getX();
				itemList[index].y2 = me.getY();
			}
			repaint();
		}
		/**
		 * 判断鼠标是否在画布边缘
		 * @param x
		 * @param y
		 * @return
		 */
		public boolean isDrag(int x,int y)
		{
			int rightX=(int)(DrawPanel.this.getWidth()+DrawPanel.this.getBounds().getX());
			 int  bottomY=(int)(DrawPanel.this.getHeight()+DrawPanel.this.getBounds().getY());
			if(Math.abs(x-rightX)<10&&Math.abs(y-bottomY)<10)
				return true;
			return false;
			
		}
		public boolean isInPanel(int x,int y)
		{
			if(x>=0&&x<DrawPanel.this.getWidth()&&y>=0&&y<DrawPanel.this.getHeight())
				return true;
			return false ;
		}
		 public void mouseMoved(MouseEvent e) 
			{
				int x=e.getX();
				int y=e.getY();
				DrawPanel.this.bottomPanel.pointLabel.setText("X: "+x+" Y: "+y);
				//重大错误
				if(!isInPanel(x,y))
				{
					System.out.println("out");
					try {
						Robot robot=new Robot();
						Rectangle rec=new Rectangle(0,0,DrawPanel.this.getWidth(),DrawPanel.this.getHeight());
						DrawSet.img=robot.createScreenCapture(rec);
					} catch (AWTException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
					
				}
				else
				{
					System.out.println("in");
				}
				//Cursor cursor=DrawPanel.this.getCursor();
				if(isDrag(x,y))
				{
					
					DrawPanel.this.setCursor(Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
					reSize=1;
				}
				else
				{
					DrawPanel.this.setCursor(DrawSet.cursorIcon);
					reSize=0;
				}
					
			}//move方法结束
	}//监听事件结束
	
}

 

Drawing

import java.awt.AWTException;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.geom.Line2D;
import java.awt.geom.Line2D.Double;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.io.Serializable;
//图形绘制类 用于绘制各种图形
//父类,基本图形单元,用到串行的接口,保存使用到
//公共的属性放到超类中,子类可以避免重复定义
import java.util.ArrayList;
import java.util.Random;

/*类通过实现 java.io.Serializable 接口以启用其序列化功能。
 未实现此接口的类将无法使其任何状态序列化或反序列化。
 可序列化类的所有子类型本身都是可序列化的。序列化接口没有方法或字段,
 仅用于标识可序列化的语义。*/

public class Drawing implements Serializable {
	int x1, x2, y1, y2; // 定义坐标属性
	public Color pColor;// =DrawSet.drawColor1; //定义色彩属性
	Line2D pLine;//临时的Line
	float strokeWidth;//画笔宽度
	String str=null;//写文字
	Random rd = new Random();//喷雾的随机数
	int r1[], r2[];//喷雾的各点半径
	int pointNumber;//喷雾生产点的个数
	static Robot robot;
	ArrayList<Line2D> pLines = new ArrayList<Line2D>();//用来存随笔画的线
	public static BufferedImage img;
	void draw(Graphics2D g2d) {
	}// 定义绘图函数
}

class Line extends Drawing// 直线类
{
	void draw(Graphics2D g2d) {
		g2d.setPaint(pColor);// 为 Graphics2D 上下文设置 Paint 属性。
		g2d.setStroke(new BasicStroke(strokeWidth));
		g2d.drawLine(x1, y1, x2, y2);// 画直线

	}
}

class Rect extends Drawing {// 矩形类
	void draw(Graphics2D g2d) {
		g2d.setStroke(new BasicStroke(strokeWidth));
		g2d.setPaint(pColor);
		g2d.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1),
				Math.abs(y2 - y1));
	}
}

class fillRect extends Drawing {// 实心矩形类
	void draw(Graphics2D g2d) {
		g2d.setPaint(pColor);
		g2d.fillRect(Math.min(x1, x2), Math.min(y2, y2), Math.abs(x1 - x2),
				Math.abs(y1 - y2));

	}
}

class Oval extends Drawing {// 椭圆类
	void draw(Graphics2D g2d) {
		g2d.setStroke(new BasicStroke(strokeWidth));
		g2d.setPaint(pColor);
		g2d.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2),
				Math.abs(y1 - y2));
	}
}

class fillOval extends Drawing {// 实心椭圆类
	void draw(Graphics2D g2d) {
		g2d.setPaint(pColor);
		g2d.fillOval(Math.min(x1, x2), Math.min(y2, y2), Math.abs(x1 - x2),
				Math.abs(y1 - y2));
	}
}

class Circle extends Drawing {// 矩形类
	void draw(Graphics2D g2d) {
		g2d.setStroke(new BasicStroke(strokeWidth));
		g2d.setPaint(pColor);
		g2d.drawOval(Math.min(x1, x2), Math.min(y2, y2),
				Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)),
				Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)));
	}
}

class fillCircle extends Drawing {// 实心圆类
	void draw(Graphics2D g2d) {
		g2d.setPaint(pColor);
		g2d.fillOval(Math.min(x1, x2), Math.min(y2, y2),
				Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)),
				Math.max(Math.abs(x1 - x2), Math.abs(y1 - y2)));
	}
}

class RoundRect extends Drawing {// 圆角矩形类
	void draw(Graphics2D g2d) {
		g2d.setStroke(new BasicStroke(strokeWidth));
		g2d.setPaint(pColor);
		g2d.drawRoundRect(Math.min(x1, x2), Math.min(y1, y2),
				Math.abs(x1 - x2), Math.abs(y1 - y2), 50, 35);
	}
}

class fillRoundRect extends Drawing {// 实心圆角矩形类
	void draw(Graphics2D g2d) {
		g2d.setPaint(pColor);
		g2d.fillRoundRect(Math.min(x1, x2), Math.min(y2, y2),
				Math.abs(x1 - x2), Math.abs(y1 - y2), 50, 35);
	}
}

class Pencil extends Drawing {// 随笔画类
	void draw(Graphics2D g2d) {
		g2d.setStroke(new BasicStroke(strokeWidth));
		pLine = new Line2D.Double(x1, y1, x2, y2);
		pLines.add(pLine);
		g2d.setPaint(pColor);
		for (Line2D tpLine : pLines)
			g2d.draw(tpLine);
	}
}

class Rubber extends Drawing {// 橡皮擦类
	void draw(Graphics2D g2d) {
		g2d.setPaint(new Color(255, 255, 255));// 白色
		pLine = new Line2D.Double(x1, y1, x2, y2);
		pLines.add(pLine);
		g2d.setStroke(new BasicStroke(5.0f));
		for (Line2D tpLine : pLines)
			g2d.draw(tpLine);
	}
}

class PenWu extends Drawing {//喷雾类

	void draw(Graphics2D g2d) {
		g2d.setPaint(pColor);
		g2d.setStroke(new BasicStroke(1.0f));
		for (int i = 0; i < pointNumber; i++) {
			int x0 = x1 + r1[i];
			int y0 = y1 + r2[i];
			g2d.drawLine(x0, y0, x0, y0);
		}
	}
}

class Word extends Drawing {// 输入文字类
	
	void draw(Graphics2D g2d) {	
		g2d.setPaint(pColor);
		if(str!=null)
		g2d.drawString(str, x1, y1);
	}
}
/**
 * 提取类实际上是空的 其功能在DrawPanel中实现
 * @author ZhangZunC
 *
 */
class TiQu extends Drawing {
}

 开发过程中遇到的问题:(原问题代码没保存下来 所以以下内容 看起来可能会不明所以)

1.在绘画喷雾的时候 发现每次一个repaint操作以画好的喷雾的点会再次随机绘画(喷雾的实现是随机产生若干个点 然后绘画出来)弄了半天 在龙哥的帮助下 才发现我每次新建一个图像后 对会调用Drawing类的draw方法 ,每次都会产生新的随机数 所以每次repaint,已经画好的喷雾都会再次随机

找到问题后解决起来就简单了,直接用了一个数组来保存每个喷雾对象已产生的随机点

itemList[index].r1 = new int[pointNumber];
                itemList[index].r2 = new int[pointNumber];
                itemList[index].pointNumber = pointNumber;
                for (int i = 0; i < pointNumber; i++) {
                    itemList[index].r1[i] = rd.nextInt(r) - r;
                    itemList[index].r2[i] = rd.nextInt(r) - r;
                }

 同样的是插入文字也要用数组保存 所有输入的文字

 

  • 大小: 49.7 KB
分享到:
评论
4 楼 人生难得糊涂 2014-05-25  
金R在奋斗着 写道
为神马这篇木有浏览量捏。。。。。。。。。。。。。。。

我也不解。 表情帝
3 楼 金R在奋斗着 2014-05-25  
为神马这篇木有浏览量捏。。。。。。。。。。。。。。。
2 楼 人生难得糊涂 2014-05-23  
肆无忌惮_ 写道
给力。

1 楼 肆无忌惮_ 2014-05-23  
给力。

相关推荐

    仿XP画图板

    【标题】"仿XP画图板"是一款基于JAVA编程语言开发的应用程序,旨在模拟Windows XP操作系统中的经典画图工具。这个项目是为那些希望学习或熟悉GUI(图形用户界面)编程和事件处理的初学者设计的,同时也为用户提供了...

    仿WindowsXP画图板设计(1)

    【标题】"仿WindowsXP画图板设计(1)"是一个关于开发类似Windows XP操作系统中经典画图工具的项目。这个项目旨在帮助学习者理解和实践图形用户界面(GUI)设计、事件处理以及基本的绘图功能。 【描述】虽然描述为空...

    仿 XP 系统画图板

    使用JAVA来开发仿XP画图板,意味着该程序可以在任何安装了JAVA运行环境的平台上运行,体现了JAVA的“一次编写,到处运行”的特性。 2. **图形用户界面**(GUI):仿XP系统画图板的界面设计是其关键部分,开发者可能...

    仿XP系统 画图板

    Java是一种广泛使用的编程语言,因其跨平台性而被选中来开发这个仿XP画图板。Java的Swing或JavaFX库可以用来构建GUI(图形用户界面),提供丰富的组件和功能,用于创建这个应用程序的界面和交互逻辑。画图板部分则...

    一个仿XP的画图板实现

    标题 "一个仿XP的画图板实现" 暗示我们即将探讨的是一个软件开发项目,这个项目的目标是创建一个类似微软Windows XP操作系统中的“画图”程序的复制品。这个程序可能包含了基本的绘图工具,如选择颜色、线条粗细、...

    仿windows画图工具的html5画图工具

    `jspaint` 是一个基于HTML5技术的在线画图工具,它高度模仿了经典的Windows XP系统自带的画图程序。这个工具利用HTML5的Canvas元素,为用户提供了在Web浏览器上进行绘画和图像编辑的能力。Canvas是HTML5的一个重要...

    经典的Access源码合集Trynew合集1

    个人开发的Access小程序合集(按...仿XP风格窗体.rar 通用窗体.rar 特种设备管理信息系统V10.rar 成语词典.rar Access词汇表.rar 英语小词典.rar 程序框架.rar AccNotePad.rar 港发设备管理系统V2.9.rar 成语接龙.rar

    Java版水果管理系统源码-HubuPaint:基于.net之仿Windows画板设计

    Java版水果管理系统源码 HubuPaint 基于.net之仿Windows画板...随着操作系统不断的更新换代,其自带的画图板界面及功能也在不断变化,例如XP、Vista、Win10,它们画图板的界面布局风格以及功能都有所不同,这表明尽管

    一款超强的图形系统——Delphi源码Delphi-source-VG7.23

    软件不仅能在目前主流操作系统,如Windows NT、XP上优化运行,而且还完美兼容Windows98。在编程语言方面,软件提供的接口不仅能够支持VB、VC、Delphi、FoxPro、PowerBuilder、C++Builder、 C#、VB.net、VC.net、IE...

    protues教程PDF

    - **操作系统支持**:支持Windows 98/Me/2000/XP等多个版本。 - **长期开发经验**:产品经过15年以上的持续开发和改进。 - **全球用户基础**:在全球35个国家拥有数千个用户。 - **技术支持**:提供直接来自开发者的...

Global site tag (gtag.js) - Google Analytics