`
981875739
  • 浏览: 7657 次
  • 性别: 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;
   }   
  }
}
以上是一些代码和注释以及出现的问题,都需进一步的学习改善,希望大家不吝赐教~~~
分享到:
评论

相关推荐

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

    NULL 博文链接:https://xiaoyjj.iteye.com/blog/1702155

    java画图板的总结

    NULL 博文链接:https://pengchenming.iteye.com/blog/1399196

    基于HTML5 Canvas的画图板设计与实现

    在此基础上实现了部分类似Windows画图板的功能,包括铅笔、图章仿制、画直线、圆、矩形、橡皮擦、背景图、取色板、插入文字等功能,在实现过程中也利用了最新的CSS3技术,最后再次总结了这次毕设的经验和对未来的...

    凸轮机构画图总结.doc

    凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图总结 凸轮机构画图...

    基于HTML5_Canvas的画图板设计与实现

    本文详细分析了HTML5技术的简介和发展前景,并深入探讨了HTML5引入的核心标签Canvas元素,介绍了Canvas可以实现的主要功能,在此基础上实现了部分类似Windows画图板的功能,包括铅笔、图章仿制、画直线、圆、矩形、...

    mfc实现画图板(源码+实验报告)

    (1) 能够用鼠标操控方式,绘制直线、矩形、椭圆。 (2) 在绘图时,选择绘制某种图像后(如直线),在画布中按住鼠标左键后移动鼠标,在画布中实时的根据鼠标的移动显示相应的图形。在松开鼠标左键后,一次绘图操作...

    PCB画图经典技巧总结

    布过板的人都知道,这在实际操作上有一定的难度。 要布出更好的板,首先您得对您所使用的IC有个电气方面的了解,有哪些引脚会产生高次谐波(数字信号或开关量方波信号的上升/下降沿),哪些引脚易感应电磁于扰,...

    原理图和PCB板绘图问题总结20170215.docx

    之前经常画图,总结了几个容易犯错的问题

    stata面板门槛回归模型,门限模型,门限回归,门槛模型,面板xthreg ,命令安装和回归分析LR画图都讲的很详细哦

    stata面板门槛回归模型,门限模型,门限回归,门槛模型,面板xthreg ,命令安装和回归分析LR画图都讲的很详细哦,资料都是本人在学习面板门槛模型是归纳总结的,结合了连玉君老师以及王群勇两位老师的命令,配有详细...

    个人总结--CMD常用命令(精华)

    mspaint--------画图板 mstsc----------远程桌面连接 mplayer2-------媒体播放机 。。。。。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。。。。。。。 。。。。。。。。。。。。。。。。...

    基础电子中的电子爱好者教你如何自制PCB板

    在一些电子刊物上经常能看到他们撰写自制PcB经验的文章,以前我在业余时间也手工做过很多单面PCB板,现在总结出一套方法跟大家分享下,大家一起来研究研究。  PCB最好采用1:1的比例其步骤:  ◆设计元件分布图:取...

    详解制作PCB覆铜板的五大方法

    电子工程师就是玩电路的,那么就少不了画板子,想让板子...当然现在很多种方法制PCB板,网上画PCB板的方法虽多,但是都很分散,这里是以为电路高手自己结合实际经验收集归纳总结的,如果你有不同的看法也可以共同探讨!

    软件工程-期末考试复习总结知识点必考题型(根据老师讲的重点自己整理)

    软件工程-期末考试复习总结知识点必考题型(根据老师讲的重点自己整理) 简答和应用大题着重复习课后习题,尤其是...软件工程-期末考试复习总结知识点 必考题型.docx(把基础知识看看解答题没问题,画图题直接背就好)

    韩顺平 满汉楼餐饮系统 开发文档

    3.1 画图面板类 11 3.2 数据库连接类 11 3.3 音乐控制类 11 第 4 章 数据库设计 12 4.1 本系统拥有如下20个数据表 12 4.2 数据表的连接关系 12 第 5 章 功能模块设计 13 5.1 管理界面 13 5.1.1 人事管理 13 5.1.2 ...

    nlp学习资料,学习总结

    nlp学习资料 学习总结 人工智能&gt;机器学习&gt;深度学习 数据 算力 算法 自然语言处理 人机交互 数据分析/挖掘 开发工具 python + pycharm 常用工具 tensorflow pytorch gensim sklearn numpy 数据处理常用库 jieba ...

    互联网开发转正述职模板

    开发转正述职汇报ppt...对于个人:,定时总结工作出现的问题和解决方案记录,增加程序逆向思维排查问题解决问题,深度学习公司已有技术 对于项目:保质保量完成迭代任务。增加项目沟通协作。,增加后期流程拓展和维护

    ASP.NET4高级程序设计第4版 带目录PDF 分卷压缩包 part1

    1.3 总结 第2章 Visual Studio 2.1 Visual Studio 2.1.1 网站和Web项目 2.1.2 创建无项目文件的网站 2.1.3 设计网页 2.2 Visual StudioIDE 2.2.1 解决方案资源管理器 2.2.2 文档窗口 2.2.3 工具...

Global site tag (gtag.js) - Google Analytics