黑马程序员技术交流社区

标题: java画图板详解 [打印本页]

作者: 庭院深深深几许    时间: 2019-4-18 09:56
标题: java画图板详解
  我们要做一个像画图那样的面板
  首先我们先创建一个窗体JFrame
  然后我们设置它的属性
  .setSize(X,Y);
  --设置窗体大小(宽度,高度);
  .setLocationRelativeto(null);
  --设置窗体相对屏幕居中(null为居中);
  .setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  --设置窗体关闭模式(关闭窗体并退出程序);
  .setTitle("......");
  --设置标题(“..标题..”);
  .setResizable(false);
  --设置窗体大小是否可变(false);
  .setLayout(new FlowLayout());
  --设置窗体布局格式(流式布局);
  .setVisible(true);
  --设置窗体可见(true);
  接下来我们建立一个事件处理类
  这里建立的方法有两种
  一种是通过继承MouseListener和MouseMotionListener
  另一种则通过继承MouseAdapter鼠标适配器类
  后者较为方便,因为当使用前者时需要重写所有的抽象类
  而后者它实现MouseListener、MouseMotionListener和MouseWheelListener这三个接口,并且把抽象方法重写了
  所以在继承MouseAdapter鼠标适配器类之后,我们只需要重写需要用到的抽象方法就可以了
  顺带一提,一般的画图程序除了绘制边框、填充图形还有各种线性和各种特效
  为了减少程序的冗杂,同时我们还需要用到数组以及Graphics的扩展Graphics2D
  数组可以用来储存多个元素
  创建数组的格式为:元素类型[ ]数组名={元素1,元素2,元素3......};
  访问数组中元素的方法:数组名[索引](索引的取值:0~长度-1)
  数组的长度为:数组名.length
  数组的遍历(访问数组的所有元素):for(int i=0;i<数组名.length;i++){......数组名......}
  接下来,我们建立2个数组,分别储存各种绘图方法和各种颜色
  代码如下:
  String[ ] ShuZu = { "直线", "矩形", "圆弧角矩形", "三角形", "圆", "椭圆", "文字", "图片", "拖动", "刷子", "橡皮", "喷枪", "任意多边形" };
  for (int i = 0; i < ShuZu.length; i++) {
  JButton AnNiu = new JButton(ShuZu[ i ]);// 实例化一个按钮对象
  AnNiu.addActionListener(HTANHZ);// 给按钮添加监听方法,指定事件处理类的对象。
  anban.add(AnNiu);// 将按钮添加到窗体上
  }
  Color[ ] colorArray = {color.balck,color.red,color.green,color.blue,Color.WHITE, new Color(12, 123, 200) };
  for (int i = 0;i < colorArray.length; i++) {
  JButton button = new JButton();// 实例化一个按钮对象
  button.setBackground(colorArray[ i ]);// 设置按钮的背景颜色
  button.setPreferredSize(new Dimension(30, 30));// 设置除了顶级容器外其它组件大小的方法
  button.addActionListener(HTANHZ);// 给按钮添加监听方法,指定事件处理类的对象。
  anban.add(button);// 将按钮添加到窗体上
  }
  看到这里可能有人会问了,为什么第二个数组比第一个数组多了2行代码,原因是:
  第一,需要设置背景颜色才能在界面上有所区别;
  第二,前者用的是文字,默认的按钮大小会自适应而后者没有文字,如果不设置组件大小,那么显示出来的组件大小将会失常
  当然,以上两个数组也要在窗体可见之前写好
  然后我们在窗体可见之后实例化画笔对象,并调用画画的方法
  最后写主函数
  我们再回到事件处理类这边
  我们首先让它继承MouseAdapter鼠标适配器类和ActionListener鼠标动作接口
  然后定义属性:
  Graphics2D g;
  int x1,y1,x2,y2,x3,y3,x4,y4;
  int DJCS = 1;
  String Shu;
  String WZ = "这句话有八个字";
  Color color =color.black;
  以及图片的位置:
  public static javax.swing.ImageIcon HQZ = new javax.swing.ImageIcon("D:javawzq-h.jpg");
  public static javax.swing.ImageIcon BQZ = new javax.swing.ImageIcon("D:javawzq-b.jpg");
  同时定义设置Graphics2D属性的方法
  public void setFF(Graphics FF) {
  g = (Graphics2D) FF;
  }
  然后接下来我们首先要确定我们在界面上是点击了哪一种按钮
  public void actionPerformed(ActionEvent e) {
  String hq = e.getActionCommand();// 获取按钮上的文字信息
  if (hq.equals(" ")) {// 判断点击的是否是颜色按钮
  JButton button = (JButton) e.getSource();// 获取事件源对象
  color = button.getBackground();// 获取按钮上的背景颜色
  } else {// 表示点击的是图形按钮
  Shu = hq;// 将按钮上的文字存入属性
  }
  }
  获取点击次数
  public void mouseClicked(MouseEvent e) {
  DJCS = e.getClickCount();
  }
  获取鼠标按下时的坐标同时设置颜色
  public void mousePressed(MouseEvent e) {
  x1 = e.getX();
  y1 = e.getY();
  g.setColor(color);
  }
  获取鼠标释放时的坐标同时绘制图形
  public void mouseReleased(MouseEvent e) {
  x2 = e.getX();
  y2 = e.getY();
  if ("直线".equals(Shu)) {
  g.drawLine(x1, y1, x2, y2);
  } else if ("矩形".equals(Shu)) {
  g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
  } else if ("圆弧角矩形".equals(Shu)) {
  g.drawRoundRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1), 75, 100);
  } else if ("圆".equals(Shu)) {
  g.fillOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(x2 - x1));
  } else if ("椭圆".equals(Shu)) {
  g.fillOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1));
  } else if ("三角形".equals(Shu)) {
  if (DJCS == 1) {
  DJCS++;
  g.drawLine(x1, y1, x2, y2);
  x3 = x1;
  y3 = y1;
  x4 = x2;
  y4 = y2;
  } else if (DJCS == 2) {
  g.drawLine(x3, y3, x2, y2);
  g.drawLine(x2, y2, x4, y4);
  DJCS--;
  }
  } else if ("文字".equals(Shu)) {
  g.drawString(WZ, Math.min(x1, x2), Math.min(y1, y2));
  } else if ("图片".equals(Shu)) {
  g.drawImage(HQZ.getImage(), Math.min(x1, x2), Math.min(y1, y2), Math.abs(x2 - x1), Math.abs(y2 - y1), null);
  }
  }
  这里我们还用了:Math.min--取最小值;Math.abs--取绝对值
  因为我们画图时,并不一定每次都是从左上角往右下角进行绘制
  获取拖动时鼠标的位置并绘制图形
  public void mouseDragged(MouseEvent e) {
  if ("拖动".equals(Shu) || "刷子".equals(Shu) || "橡皮".equals(Shu) || "喷枪".equals(Shu)) {
  x2 = e.getX();
  y2 = e.getY();
  }
  if ("拖动".equals(Shu)) {
  g.setStroke(new BasicStroke(1));
  g.drawLine(x1, y1, x2, y2);
  x1 = x2;
  y1 = y2;
  } else if ("刷子".equals(Shu)) {
  g.setStroke(new BasicStroke(20));
  g.drawLine(x1, y1, x2, y2);
  x1 = x2;
  y1 = y2;
  } else if ("橡皮".equals(Shu)) {
  JFrame anban =(JFrame)e.getSource();
  color = anban.getBackground();
  g.setColor(color);
  g.setStroke(new BasicStroke(55));
  g.drawLine(x1, y1, x2, y2);
  x1 = x2;
  y1 = y2;
  } else if ("喷枪".equals(Shu)) {
  g.setStroke(new BasicStroke(0));
  Random r = new Random();
  int a = r.nextInt(35);
  int b = r.nextInt(35);
  g.drawLine(x2 + a, y2 + b, x2 + a, y2 + b);
  g.drawLine(x2 - a, y2 - b, x2 - a, y2 - b);
  g.drawLine(x2 + a, y2 - b, x2 + a, y2 - b);
  g.drawLine(x2 - a, y2 + b, x2 - a, y2 + b);
  g.drawLine(x2 + a/2, y2 + b/2, x2 + a/2, y2 + b/2);
  g.drawLine(x2 - a/2, y2 - b/2, x2 - a/2, y2 - b/2);
  g.drawLine(x2 + a/2, y2 - b/2, x2 + a/2, y2 - b/2);
  g.drawLine(x2 - a/2, y2 + b/2, x2 - a/2, y2 + b/2);
  x1 = x2;
  y1 = y2;
  }
  }
  当然,在这里的喷枪纯属随意......同时用到了线条纹理BasicStroke和随机数Random
  这样一来,一个简单的画图板程序就完成了......






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2