用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; }
同样的是插入文字也要用数组保存 所有输入的文字
相关推荐
【标题】"仿XP画图板"是一款基于JAVA编程语言开发的应用程序,旨在模拟Windows XP操作系统中的经典画图工具。这个项目是为那些希望学习或熟悉GUI(图形用户界面)编程和事件处理的初学者设计的,同时也为用户提供了...
【标题】"仿WindowsXP画图板设计(1)"是一个关于开发类似Windows XP操作系统中经典画图工具的项目。这个项目旨在帮助学习者理解和实践图形用户界面(GUI)设计、事件处理以及基本的绘图功能。 【描述】虽然描述为空...
使用JAVA来开发仿XP画图板,意味着该程序可以在任何安装了JAVA运行环境的平台上运行,体现了JAVA的“一次编写,到处运行”的特性。 2. **图形用户界面**(GUI):仿XP系统画图板的界面设计是其关键部分,开发者可能...
Java是一种广泛使用的编程语言,因其跨平台性而被选中来开发这个仿XP画图板。Java的Swing或JavaFX库可以用来构建GUI(图形用户界面),提供丰富的组件和功能,用于创建这个应用程序的界面和交互逻辑。画图板部分则...
标题 "一个仿XP的画图板实现" 暗示我们即将探讨的是一个软件开发项目,这个项目的目标是创建一个类似微软Windows XP操作系统中的“画图”程序的复制品。这个程序可能包含了基本的绘图工具,如选择颜色、线条粗细、...
`jspaint` 是一个基于HTML5技术的在线画图工具,它高度模仿了经典的Windows XP系统自带的画图程序。这个工具利用HTML5的Canvas元素,为用户提供了在Web浏览器上进行绘画和图像编辑的能力。Canvas是HTML5的一个重要...
个人开发的Access小程序合集(按...仿XP风格窗体.rar 通用窗体.rar 特种设备管理信息系统V10.rar 成语词典.rar Access词汇表.rar 英语小词典.rar 程序框架.rar AccNotePad.rar 港发设备管理系统V2.9.rar 成语接龙.rar
Java版水果管理系统源码 HubuPaint 基于.net之仿Windows画板...随着操作系统不断的更新换代,其自带的画图板界面及功能也在不断变化,例如XP、Vista、Win10,它们画图板的界面布局风格以及功能都有所不同,这表明尽管
软件不仅能在目前主流操作系统,如Windows NT、XP上优化运行,而且还完美兼容Windows98。在编程语言方面,软件提供的接口不仅能够支持VB、VC、Delphi、FoxPro、PowerBuilder、C++Builder、 C#、VB.net、VC.net、IE...
- **操作系统支持**:支持Windows 98/Me/2000/XP等多个版本。 - **长期开发经验**:产品经过15年以上的持续开发和改进。 - **全球用户基础**:在全球35个国家拥有数千个用户。 - **技术支持**:提供直接来自开发者的...