`
981875739
  • 浏览: 7914 次
  • 性别: Icon_minigender_2
  • 来自: 长沙
社区版块
存档分类
最新评论

画图板总结

阅读更多

在蓝杰上了几节课后就开始了画图板的开发,从一开始简单的界面到能够添加各种颜色工具图片面板,到实现重绘,再到现在的实现保存文件和打开文件,经历了一个漫长的时间,现在的画图板还有许多的不足之处,我觉得最大的问题是(1)实现了保存打开功能后我原本的布局有问题了(原来用的是边框布局,现在改为了流式布局),画布取不到,不知道什么问题,所以现在的画图板布局不是很合理,看着不舒服。(2)我想添加下拉菜单选项的监听器,但是没有找到,最后就将菜单的选项只留下了保存和打开。画图板还有许多的不足之处,我会慢慢修改,使之优化。

这是原先的画板:<!--StartFragment -->

<!--StartFragment -->

这是现在的面板:<!--StartFragment -->
以下是画图板DrawBoard的代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.event.MenuEvent;
import javax.swing.event.MenuListener;
/**
 * 窗体类
 * @author Administrator
 *
 */
public class DrawBoard extends JFrame implements Config {
    //定义属性
 private Graphics g;
 private JPanel drawPanel;
    /**
     * 主函数
     * @param args
     */
 public static void main(String[] args) {
  //创建对象
  DrawBoard ds = new DrawBoard();
  //调用显示窗体的方法
  ds.dra();
 }
    /**
     * 显示窗体的方法
     */
 public void dra() {
  this.setTitle("未命名 - 画图");// 设置窗体的标题
  this.setSize(FRAME_WIDTH, FRAME_HEIGHT);//设置画板大小
  this.setResizable(false);//不可改变画板大小
  this.setLocationRelativeTo(null);// 设置窗体的位置
  this.setDefaultCloseOperation(3);// 设置窗体关闭时是否退出
//// 给窗体添加菜单栏的方法
//createMenuBar();
  // 创建工具,颜色,画板面板
  ToolPanel toolPanel = new ToolPanel();
  ColorPanel colorPanel = new ColorPanel();
  //创建一块面板放置工具面板,颜色面板,保存,打开按钮
  JPanel panel =  new JPanel();
  panel.add(colorPanel);
  panel.add(toolPanel); 
  //给窗体设置流式布局
  FlowLayout fl = new FlowLayout(FlowLayout.LEFT);
  this.setLayout(fl);
  // 创建用来绘图的面板
  drawPanel = new MyPanel();
  //给画图面板设置颜色
  drawPanel.setBackground(Color.WHITE);
  //给画图面板设置大小
  drawPanel.setPreferredSize(new Dimension(DRAW_WIDTH, DRAW_HEIGHT));
  //将面板添加到窗体上
  this.add(panel);
  this.add(drawPanel);
  //设置窗体可见
  this.setVisible(true);
  //获取画布对象
  g = drawPanel.getGraphics();
  //实例化一个画图事件处理类对象
  DrawListener tl = new DrawListener(toolPanel,colorPanel,g);
  //给drawPanel添加鼠标监听器方法,并且绑定事件处理类对象
  drawPanel.addMouseListener(tl);
  //给drawPanel添加鼠标移动监听器方法,并且绑定事件处理类对象
  drawPanel.addMouseMotionListener(tl);
  // 给窗体加鼠标监听器
  DrawListener lis = new DrawListener( toolPanel,colorPanel,g);
  drawPanel.addMouseListener(lis);
  
        //******************************匿名内部类************************************//
  MenuListener ml = new MenuListener(){
   @Override
   public void menuCanceled(MenuEvent arg0) {
    // TODO Auto-generated method stub
    
   }
   @Override
   public void menuDeselected(MenuEvent arg0) {
    // TODO Auto-generated method stub
    
   }
   @Override
   public void menuSelected(MenuEvent e) {
    // TODO Auto-generated method stub
    JMenu m = (JMenu)e.getSource();//获取事件源
    String str = m.getActionCommand();
    //判断选择的游戏方式
    if(str.equals("保存")){
     FileUtil.saveFile("H:\\aa\\test.bmp");
     System.out.println("BMP图片保存完毕!");
    }else if(str.equals("打开")){
     DrawListener.isPaint = true;
     // 读取文件,得到二位数组
     int[][] readData = FileUtil.readFile("H:\\aa\\test.bmp");
     DrawListener.data = readData;
     // 刷新drawPanel
     drawPanel.updateUI();
     System.out.println("BMP图片已打开!");
    }else{
     System.out.println("出错啦!");
    }
   }};
   //给菜单选项添加监听器
   JMenuBar jmb = new JMenuBar();
   this.setJMenuBar(jmb);
   JMenu savemenu= new JMenu("保存");
   jmb.add(savemenu);
   savemenu.addMenuListener(ml);
   JMenu openmenu= new JMenu("打开");
   jmb.add(openmenu);
   openmenu.addMenuListener(ml);
  
  //********************************************************************************//
 
 
 /**
  * 创建菜单栏的方法,并且把菜单栏添加到窗体上
  */
 public void createMenuBar() {
  // 创建菜单条对象
  JMenuBar bar = new JMenuBar();
  String[] menus = { "文件", "颜色", "帮助" };
  String[][] menuItems = { { "新建", "打开", "保存", "退出" }, { "编辑颜色" },
    { "帮助主题", "关于画图" } };
  for (int i = 0; i < menus.length; i++) {
   JMenu menu = new JMenu(menus[i]);
   for (int j = 0; j < menuItems[i].length; j++) {
    JMenuItem menuItem = new JMenuItem(menuItems[i][j]);
    menu.add(menuItem);//将下拉菜单添加到菜单上
    menuItem.setActionCommand(menuItems[i][j]);//获取点击下拉菜单上对象的命令
   } 
   bar.add(menu);//将菜单添加到菜单条上
  }
  this.setJMenuBar(bar);// 把菜单条添加到窗体上
  
  
 }
 /**
  * 重新绘制形状的方法
  * @param g 画布对象
  */
 public void drawShape(Graphics g) {
  // 得到drawPanel的背景色
  Color bgColor = drawPanel.getBackground();
     //设置一个变量存储颜色值
  int bgNum = bgColor.getRGB();
  // 遍历二位数组,取出每个像素点的颜色
  for (int i = 0; i < DrawListener.data.length; i++) {
   for (int j = 0; j < DrawListener.data[i].length; j++) {
    int num = DrawListener.data[i][j];
    if (bgNum != num) {
     // 创建颜色对象
     Color color = new Color(num);
     //设置颜色
     g.setColor(color);
     //画每个像素点
     g.drawLine(j, i, j, i);
    }
   }
  }
 }
   
 
 //其他类,一个类中可以有一个以上的类
 class MyPanel extends JPanel {
  /**
   * 重写父类绘制窗体的方法
   */
  public void paint(Graphics g) {
   // 调用父类的方法
   super.paint(g);
   if (DrawListener.isPaint) {
    // 调用绘制方法
    drawShape(g);
   }
  }
 }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
实现保存打开的代码:
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
public class FileUtil implements Config {
 /**
  * 将图片数据保存到指定的位置
  *
  * @param path
  *            : 要保存数据的位置
  */
 public static void saveFile(String path) {
  try {
   // 创建文件输出流对象
   FileOutputStream fos = new FileOutputStream(path);
   // 将输出流包装成可写基本类型的数据流
   DataOutputStream dos = new DataOutputStream(fos);
   // 写图片的高度和宽度
   dos.writeInt(DrawListener.data.length);
   dos.writeInt(DrawListener.data[0].length);
   // 遍历二维数组,写数据
   for (int i = 0; i < DrawListener.data.length; i++) {
    for (int j = 0; j < DrawListener.data[i].length; j++) {
     int num = DrawListener.data[i][j];
     // 写数据
     dos.writeInt(num);
    }
   }
            //将输出流清空
   dos.flush();
   //将输出流关闭
   fos.close();
  } catch (Exception ef) {
   ef.printStackTrace();
  }
 }
 /**
  * 读取文件中的数据
  *
  * @param path
  *            要读取的文件
  * @return 将读取到的数据作为二位数组返回
  */
 public static int[][] readFile(String path) {
  // 创建文件输入流
  try {
   //创建文件输入流对象
   FileInputStream fis = new FileInputStream(path);
   //将文件输入流包装成可写基本类型的数据流
   DataInputStream dis = new DataInputStream(fis);
   // 读取高度和宽度
   int height = dis.readInt();
   int width = dis.readInt();
   // 定义二维数组
   int[][] readData = new int[height][width];
   //循环读取每个像素点
   for (int i = 0; i < height; i++) {
    for (int j = 0; j < width; j++) {
     // 将数据读入数组
     readData[i][j] = dis.readInt();
    }
   }
   //关闭输入流
   fis.close();
   //返回二维数组
   return readData;
  } catch (Exception ef) {
   ef.printStackTrace();
  }
  return null;
 }
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
监听器类的代码 :
将鼠标动作分为两种,一类是鼠标点击,一类是鼠标拖动
public class DrawListener extends MouseAdapter implements Config {
 //定义属性
 private int x1, y1, x2, y2, x3, y3, x4, y4;// 定义存储鼠标按下和释放时的坐标
 public static boolean isPaint = false;// 是否需要重绘
 private ToolPanel tp;
 private ColorPanel cp;
 private Graphics g;
 private Color color;
 private Robot robot;//机器人对象,自动开始 
 //用来保存数据的二维数组 数组的下标表示每个像素点的坐标,数组中的元素表示每个坐标点的颜色
 public static int[][] data;
 /**
  * 构造函数
  * @param tp 工具面板
  * @param cp  颜色面板
  * @param g  画布
  */
 public DrawListener(ToolPanel tp, ColorPanel cp, Graphics g) {
   // 赋值
  this.tp = tp;
  this.cp = cp;
  this.g = g;
 // 创建对象时可能抛出异常,所以不能直接在定义属性的时候创建
  try {
   robot = new Robot();//创建机器人对象
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 // 鼠标按下时执行的方法
 public void mousePressed(MouseEvent e) {
  x1 = e.getX();
  y1 = e.getY();
  if(e.getButton()==1){
   color = cp.getBColor();
  }else if(e.getButton()==3){
   color = cp.getFColor();
  }
 }
 
 public void mouseDragged(MouseEvent e) {
  // 判断是否需要按下拖动事件
  if (tp.getItem().equals("BrushTool")
    || tp.getItem().equals("PencilTool")
    || tp.getItem().equals("EraserTool")
    || tp.getItem().equals("AtomizerTool")) {
   // 获取坐标
   x2 = e.getX();
   y2 = e.getY();
   Shape shape = null;
   // 判断选择的是哪一个图形,然后创建不同的对象
   if (tp.getItem().equals("BrushTool")) {
    // 使用刷子
    shape = new ShapeBrush(x1, y1, x2, y2, color);
   } else if (tp.getItem().equals("PencilTool")) {
    // 使用铅笔
    shape = new ShapeLine(x1, y1, x2, y2, color);
   } else if (tp.getItem().equals("EraserTool")) {
    // 使用橡皮
    shape = new ShapeEraser(x1, y1, x2, y2, color);
   } else if (tp.getItem().equals("AtomizerTool")) {
    //使用喷枪
    shape = new ShapeAtomizer(x1, y1, x2, y2, color);
   }
   // 开始画图形
   shape.draw(g);
   // 交换坐标
   x1 = x2;
   y1 = y2;
  }
 }
 // 鼠标释放时执行的方法
 public void mouseReleased(MouseEvent e) {
   x2 = e.getX();
   y2 = e.getY();
   if (tp.getItem().equals("LineTool") || tp.getItem().equals("RectTool")
     || tp.getItem().equals("RoundTool")
     || tp.getItem().equals("RoundRectTool")
     || tp.getItem().equals("PolygonTool")) {
    Shape shape = null;
    if (tp.getItem().equals("LineTool")) {
     // 判断是否是直线,开始绘制直线了s
     shape = new ShapeLine(x1, y1, x2, y2,color);
    } else if (tp.getItem().equals("RectTool")) {
     if(x2>x1&&y2>y1){
     // 判断是否是矩形,开始绘制矩形了
      shape = new ShapeRect(x1, y1, x2, y2, color);
     }else if(x2<x1&&y2<y1){
      shape = new ShapeRect(x2,y2,x1,y1,color);
     }else if(x2>x1&&y2<y1){
      shape = new ShapeRect(x1,y2,x2,y1,color);
     }else if(x2<x1&&y2>y1){
      shape = new ShapeRect(x2,y1,x1,y2,color);
     }
     
    } else if (tp.getItem().equals("RoundTool")) {
     if(x2>x1){
      if(y2>y1){
     // 判断是否是圆形,开始绘制圆形了
         shape = new ShapeOval(x1, y1, x2, y2, color);
         }else{
      shape = new ShapeOval(x1,y2,x2,y1,color);
      }
     }else if(x2<x1){
      if(y2<y1){
          shape = new ShapeOval(x2,y2,x1,y1,color);
      }else{
       shape = new ShapeOval(x2,y1,x1,y2,color);
       }
      }
    } else if (tp.getItem().equals("RoundRectTool")) {
     if(x2>x1&&y2>y1){
     // 开始绘制圆矩形
     shape = new ShapeRoundRect(x1, y1, x2, y2, color);
     }else if(x2<x1&&y2<y1){
      shape = new ShapeRoundRect(x2,y2,x1,y1,color);
     }else if(x2>x1&&y2<y1){
      shape = new ShapeRoundRect(x1,y2,x2,y1,color);
     }else if(x2<x1&&y2>y1){
      shape = new ShapeRoundRect(x2,y1,x1,y2,color);
     }
     //绘制多边形
    } else if (tp.getItem().equals("PolygonTool")) {
     //x1,y1,x2,y2没按下和释放一次鼠标都会获取新值,所以用x3,y3,x4,y4
     if (x3 == 0) {//如果x3的值为0,则代表要画的是第一条直线
      x3 = x1;//将鼠标按下和释放时获取的坐标分别赋给x3,y3,x4,y4
      y3 = y1;
      x4 = x2;
      y4 = y2;
      // 开始绘制多边形
      shape = new ShapePolygon(x3, y3, x4, y4, color);
     
     }else{//如果x3的值不是0,则代表之前已经画过直线了,接下来继续画直线
      shape = new ShapePolygon(x4, y4, x2, y2, color);
      //第一组坐标(x4,y4)为画上一条直线时的第二组坐标,第二组坐标为本次画直线获取的第二组坐标
      x4 = x2;//将释放鼠标时获取的坐标(x2,y2)赋给下一次画直线的第一组坐标(起始坐标)
      y4 = y2;
      if((x4-x3 < 5 && x4-x3>-5) && (y4-y3< 5 && y4-y3 > -5)){
       //判断最后一次按下和释放鼠标时获取的x,y坐标之差是否小于5
       x3 = 0;//将直线的初始值设为x3=0,x4=0;重新画多边形
       y3 = 0;
      }
     }
    }
    //System.out.println(null==shape);
    // 调用画图形的方法
    shape.draw(g);
    // 每绘制一次就将整个drawPanel区域内的所有像素点保存起来
    // 得到事件源对象
    Object obj = e.getSource();
    JPanel drawPanel = (JPanel) obj;
    // 得到drawPanel的左上角的点
    Point point = drawPanel.getLocationOnScreen();
    // 得到drawPanel的大小
    Dimension dim = drawPanel.getPreferredSize();
    // 创建矩形区域对象,刚好截取drawPanel在屏幕上所占据的区域
    Rectangle rect = new Rectangle(point, dim);
    // 从屏幕上获取像素区域,得到一个缓存区的图像对象
    BufferedImage img = robot.createScreenCapture(rect);
    data = new int[dim.height][dim.width];
    // 将缓存区的图像对象中的每一个像素的颜色保存起来
    for (int i = 0; i < data.length; i++) {
     for (int j = 0; j < data[i].length; j++) {
      // 得到每个点的颜色(用数字表示的颜色),存入二维数组
      data[i][j] = img.getRGB(j, i);
     }
    }
    isPaint = true;
   }   
  }
}
以上是一些代码和注释以及出现的问题,都需进一步的学习改善,希望大家不吝赐教~~~
分享到:
评论

相关推荐

    画图板,window画图板

    总结,Windows画图板以其简单易用和功能丰富的特点,成为了日常生活中进行动态画图的得力助手。无论是儿童学习绘画,还是成年人进行快速草图设计,它都能提供一个便捷的平台。通过对画图板的深入理解和熟练运用,...

    QT画图板详例

    总结来说,QT画图板是一个很好的学习案例,涵盖了Qt GUI编程中的许多核心概念和技术,包括图形渲染、事件处理、用户交互和数据持久化等。通过学习和实践这个项目,你可以提升对Qt框架的理解,为开发更复杂的应用程序...

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

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

    QTcreator写画图板

    在本文档中,我们将探讨如何使用QtCreator来编写一个画图板程序。画图板是一个基础且功能丰富的应用,常常作为学习图形用户界面(GUI)编程的一个入门项目。本文将重点介绍Qt的GUI框架、主要组件以及编程概念。 ###...

    canvas 画图板.zip

    总结起来,"canvas 画图板.zip" 提供了一个基于 HTML5 Canvas 的简易在线画图工具实现。通过解析 HTML、CSS 和 JavaScript 文件,我们可以了解如何利用 Canvas API 创建交互式的画图板,包括监听鼠标事件、绘制线条...

    画图板的实现

    总结,实现一个画图板涉及多个Java Swing组件和事件处理机制的理解。通过这个过程,开发者可以深入学习GUI编程,以及图形绘制和交互设计的基本原理。对于初学者,这是一个很好的练习项目,能帮助他们更好地掌握Java...

    virtual c++6.o mfc简易画图板

    总结,这个“virtual c++6.0 mfc简易画图板”项目充分展示了MFC在图形界面编程中的应用,通过MFC的类和方法,实现了类似Windows画图板的基本功能。通过学习和实践此类项目,开发者可以深入理解MFC的工作原理,提高...

    画图板代码(一)

    总结来说,这个"画图板代码"项目涵盖了事件处理、图形绘制、图形状态管理和用户交互设计等多个核心编程概念,是学习和实践GUI编程的一个良好起点。通过深入研究和实践,开发者可以进一步提升在图形用户界面开发领域...

    用VC编的画图板程序

    总结来说,这个"用VC编的画图板程序"是一个利用MFC和可能的GDI/GDI+技术实现的图形应用程序,它的开发涉及到C++编程、GUI设计、事件处理、图形绘制等多个方面。对于想要深入理解VC开发和图形编程的用户,这是一个很...

    一个强大的画图板(一)

    总结起来,一个强大的画图板不仅是一个简单的绘图工具,更是创意表达、协同工作和知识传递的重要平台。它在技术博客中扮演着不可或缺的角色,帮助作者以更直观的方式传达复杂的技术概念。无论你是设计师、教师、学生...

    类似于画图板的小程序

    总结,"类似于画图板的小程序"是一个综合性的C#项目,涵盖了图形用户界面设计、事件处理、图形绘制、文件操作等多个知识点,对于学习C#编程和理解Windows应用程序开发流程具有很大的实践价值。通过分析和实践这个...

    用c#写的画图板

    总结起来,创建一个C#画图板涉及到Windows Forms应用程序的基础知识,图形绘制API的使用,以及鼠标事件的处理。这个项目不仅有助于理解C#编程,还能加深对图形用户界面设计的理解。通过不断迭代和添加更多功能,如...

    java画图板的总结

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

    java画图板系统

    总结来说,这个【Java画图板系统】项目展示了如何使用Java GUI技术来创建一个交互式的绘图应用。通过Eclipse IDE,开发者可以方便地管理、编译和调试代码,确保在不同JDK版本下的一致性。对于学习和理解Java GUI编程...

    C#的简单画图板源码

    总结来说,这个C#的简单画图板源码涉及了C#的基础语法、Windows Forms开发、图形绘制、事件处理、颜色选择等核心概念。对于初学者来说,这是一个很好的实践项目,能帮助他们深入理解和掌握这些关键知识点。通过分析...

    画图板C++写的代码

    总结来说,"画图板C++写的代码" 是一个很好的学习资源,它展示了如何使用C++和Windows API或MFC来创建一个功能丰富的图形应用程序。这个项目涵盖了图形绘制、用户交互、文件操作等多个关键领域,对于想要深入学习C++...

    VC++画图板论文

    ### VC++画图板设计与实现 #### 一、项目背景及目标 本课程设计的主要目的是让学生通过实际操作,深入理解和掌握使用Visual C++ (VC++) 开发环境进行软件开发的基本方法和技术。通过本项目的实践,学生将能够熟悉...

    java画图板

    总结来说,《Java画图板》是一款集实用性和教学性于一体的软件,它结合了Java编程的理论与实践,为用户提供了一个简洁易用的图形绘制平台,同时也为学习Java语言的学生提供了一个良好的实践平台。通过设计和实现这样...

Global site tag (gtag.js) - Google Analytics