仿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;
                }

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值