您的位置:首页 > 移动开发 > 微信开发

Java小程序之高级画板功能篇II

2016-11-14 00:23 316 查看
Java小程序之高级画板功能篇II

前言:在完成Java小程序之高级画板UI篇和功能篇I后,我们的画板已经初具雏形,拥有了较好的UI界面以及能够根据选取的颜色绘制相应颜色的直线、矩形、椭圆等图形了;今天我们将在以前的基础上继续完成画板的铅笔功能、喷桶功能、刷子功能,橡皮擦功能、取色器功能,一起让我们的画板变得更强大吧!

思路:
一、.铅笔、刷子、橡皮擦功能的实现
1.1铅笔功能
1、铅笔是鼠标拖动时画的线,所需要实现MouseMotionListener鼠标移动监听器,我们采用一个类来实现多个接口(当然心可以新建一个类去实现该接口)
2、添加新的鼠标监听器类
3、在鼠标移动时间中实现画笔的逻辑(其实就是绘制直线,鼠标每移动一个像素,就会触发移动事件,通过移动事件获取鼠标的坐标,与上一次移动的坐标连线就可以了)

1.2刷子功能
刷子其实就是加粗的画笔,画出来的直线更粗,这里需要用到Graphic2D画笔,我们强制把获取的画笔转型成Graphic2D类型,这时通过g.setStrock(Strock s)方法设置画笔的粗细,里面的参数Strock是接口类型,这里采用已经实现该该接口类型的子类BasicStrock类型来产生一个粗细的对象

1.3橡皮擦功能
橡皮擦就是把画笔颜色设置成相同的背景颜色就可以了,拖动鼠标时进行擦除,所以在鼠标拖动事件中编写逻辑(这里为了方便擦除,我们把擦除的画笔的粗细变粗一点)

二、绘制多边形

1、第一次鼠标按下和释放:绘制一条直线

2、后续图形绘制:本次释放点和上一次释放点连线(设置标志flag来区分是第一次还是后续绘制)

3、双击,封闭图形(当前点击位置和最开始鼠标按下的位置连线,并将flag标志还原,可以试试不还原会出现的效果)

三、喷桶功能

1、定位方法:鼠标拖动事件实现

2、随机数生成:Random

3.实现原理,在鼠标拖动附近绘制很多的原点

四、取色器功能

1、定位方法:鼠标释放事件

2、机器人类:Robot

3、实现原理:获取到鼠标点击时相对画板的那一个像素点的图片,拿到该图片的背景颜色,将该背景颜色设置成画笔的颜色

源代码:
DrawBorder类:
package com.huaxin.zhou1;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.border.BevelBorder;
import javax.swing.border.Border;

public class DrawBorder extends JFrame{

//声明颜色属性,并赋默认值
public Color c=Color.RED;
//按钮属性,便于其他类访问
public JButton  bt ;

public void initFrame(){

//设置窗体相关属性
this.setSize(600,500);
this.setTitle("我的画板");
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);

//窗体添加主面板
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
this.add(panel);

JPanel panelcenter = new JPanel();
panelcenter.setBackground(Color.white);
panel.add(panelcenter);

//主面板添加左面板
JPanel panelleft = new JPanel();
panelleft.setPreferredSize(new Dimension(50,0));
panelleft.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
panelleft.setBackground(new Color(235,233,238));
panel.add(panelleft,BorderLayout.WEST);

//面板中添加按钮
//按钮归类,统一管路
ButtonGroup bg = new ButtonGroup();
for(int i=0;i<16;i++){
JRadioButton jrb = new JRadioButton();

//给按钮添加图片
ImageIcon img1  = new ImageIcon("images/draw"+i+".jpg");
ImageIcon img2  = new ImageIcon("images/draw"+i+"-1.jpg");
ImageIcon img3  = new ImageIcon("images/draw"+i+"-2.jpg");
ImageIcon img4  = new ImageIcon("images/draw"+i+"-3.jpg");
jrb.setIcon(img1);
jrb.setRolloverIcon(img2);
jrb.setPressedIcon(img3);
jrb.setSelectedIcon(img4);
jrb.setBorder(null);
//设置默认选中的按钮
if(i==10){
jrb.setSelected(true);
}
jrb.setActionCommand("pic"+i);

bg.add(jrb);
panelleft.add(jrb);
}

//主面板添加下方面板
JPanel paneldown =new JPanel();
paneldown.setPreferredSize(new Dimension(0,60));
paneldown.setLayout(null);
paneldown.setBackground(Color.gray);
panel.add(paneldown, BorderLayout.SOUTH);

//下方面板添加子面板
JPanel paneldownchild = new JPanel();
paneldownchild.setBackground(Color.cyan);
paneldownchild.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
paneldownchild.setBounds(10,10,280,40);
paneldown.add(paneldownchild);

//按钮特效
BevelBorder bb = new BevelBorder(0, Color.gray,Color.white);
BevelBorder bb1 = new BevelBorder(1, Color.gray,Color.white);

JPanel left = new JPanel();
left.setBackground(Color.white);
left.setLayout(null);
left.setBorder(bb);
left.setPreferredSize(new Dimension(40,40));

//左面板中的两棵颜色按钮
bt = new JButton();
bt.setBounds(5, 5, 20, 20);
bt.setBorder(bb1);
bt.setBackground(Color.black);
bt.setSize(20,20);
JButton bt1 = new JButton();
bt1.setBorder(bb1);
bt1.setBounds(15,15,20,20);
left.add(bt);
left.add(bt1);

//右面板
JPanel right = new JPanel();
right.setBackground(Color.BLUE);
right.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));
right.setPreferredSize(new Dimension(240,40));

paneldownchild.add(left);
paneldownchild.add(right);

//给右面板的颜色按钮天添加监听器,注意传递this对象
ButtonListener bl =new ButtonListener(this);
//颜色数组,用来设置按钮的背景颜色
Color []colors = {new Color(0,56,67),new Color(89,3,14),new Color(189,3,14)
,new Color(89,93,14),new Color(89,113,14),new Color(89,73,14)
,new Color(89,3,14),new Color(89,3,14),new Color(29,83,14)
,new Color(89,3,184),new Color(189,233,14),new Color(89,253,14)
,new Color(89,93,14),new Color(89,89,94),new Color(1,3,14)
,new Color(9,83,94),new Color(89,178,147),new Color(9,33,164)
,new Color(34,23,14),new Color(89,173,154),new Color(8,193,194)
,new Color(9,253,76),new Color(89,240,104),new Color(199,73,4)};

//循环添加24个颜色按钮
for(int i=0;i<24;i++){
JButton bt3 = new JButton();
Color c=new Color(i*10,30-i,i*7+50);
bt3.setBackground(colors[i]);
bt3.setPreferredSize(new Dimension(20,20));
bt3.setBorder(bb);
bt3.addActionListener(bl);
right.add(bt3);
}

this.setVisible(true);

//画笔必须在setVisible后才能拿
Graphics g=panelcenter.getGraphics();

//传递画笔,按钮组管理对象,以及this对象
DrawListener dl =new DrawListener(g,bg,this);

//添加普通鼠标监听器
panelcenter.addMouseListener(dl);

//添加鼠标拖动监听器
panelcenter.addMouseMotionListener(dl);

}
}


ButtonListener类:

package com.huaxin.zhou1;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;

//按钮监听类,实现ActionListenerde接口
public class ButtonListener implements ActionListener{

public DrawBorder db;

//构造函数
public ButtonListener(DrawBorder db1) {
db=db1;
}

//监听具体实现
public void actionPerformed(ActionEvent e) {

//拿到被选中按钮的对象
JButton bt =(JButton)e.getSource();
//拿到被选中按钮的背景颜色
Color c= bt.getBackground();
//把背景颜色复制给DrawBorder中的颜色属性
db.c=c;
//把左面板中的按钮颜色设置成选中按钮的背景颜色
db.bt.setBackground(c);

}

}


DrawListener类:
package com.huaxin.zhou1;

import java.awt.AWTException;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Stroke;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.ButtonGroup;
import javax.swing.ButtonModel;

public class DrawListener implements MouseListener,MouseMotionListener{

public Graphics2D g;
public int x1,y1,x2,y2,ox,oy,x3,y3;
public ButtonGroup bg;
public String command;
public Color color;
public DrawBorder db;
public boolean flag=true;

public static final  Stroke s1 = new BasicStroke(1);
public static final  Stroke s2 = new BasicStroke(10);
public static final  Stroke s3 = new BasicStroke(15);

public Random r =new Random();
//构造函数1
public DrawListener(Graphics g1){
g=(Graphics2D)g1;
}

//构造函数2
public DrawListener(Graphics g2, ButtonGroup bg2) {
g=(Graphics2D)g2;
bg=bg2;
}

//构造函数3
public DrawListener(Graphics g2, ButtonGroup bg2, DrawBorder db1) {
g=(Graphics2D)g2;
bg=bg2;
db=db1;
}

//鼠标按下事件监听
public void mousePressed(MouseEvent e) {
//获取鼠标按下点的坐标
x1=e.getX();
y1=e.getY();

//判断选择的是左面板中的那个按钮被选中(前面已经设置每个按钮的名称了)
ButtonModel bm=bg.getSelection();//拿到按钮组中被选中的按钮
command=bm.getActionCommand();//拿到选中按钮的名字

}

public void mouseReleased(MouseEvent e) {
//获取鼠标释放的坐标
x2=e.getX();
y2=e.getY();

//如果选中的是绘制直线的按钮,那么根据鼠标按下点的坐标和释放点的左边绘制直线(两点确定一条直线)
if("pic10".equals(command))
{
g.drawLine(x1, y1, x2, y2);
}//同理选中的是矩形按钮,那么绘制矩形(这里有绘制矩形的纠正,不纠正的话从右下角往左上角方向绘制矩形会出现问题,参看后面难点解析)
else if("pic12".equals(command)){
g.drawRect(Math.min(x2, x1),Math.min(y2, y1), Math.abs(x2-x1),Math.abs(y1-y2));
}//绘制椭圆
else if("pic14".equals(command)){
g.drawOval(Math.min(x2, x1),Math.min(y2, y1), Math.abs(x2-x1),Math.abs(y1-y2));
} else if("pic15".equals(command)){
g.drawRoundRect(Math.min(x2, x1),Math.min(y2, y1), Math.abs(x2-x1),Math.abs(y1-y2),40,40);
}//绘制曲线
else if("pic13".equals(command)){

//第一次画直线,设置标志
if(flag){
g.drawLine(x1, y1, x2, y2);
flag=false;
//记录这次鼠标释放的坐标,作为下次绘制直线的起点
x3=x2;
y3=y2;
//记录第一点击的坐标,绘制封闭的曲线
ox=x1;
oy=y1;
}
else{
g.drawLine(x3, y3, x2, y2);
//记录上次鼠标释放的坐标
x3=x2;
y3=y2;
}
}
//取色功能
else if("pic4".equals(command)){

//拿到相对面板的那个坐标
int x=e.getXOnScreen();
int y=e.getYOnScreen();

try {

Robot robot = new Robot();//Robot类的使用

//拿到坐标点的那个矩形
Rectangle rect = new Rectangle(x,y,1,1);
//生成该矩形的缓冲图片
BufferedImage bi =robot.createScreenCapture(rect);
//得到图片的背景颜色
int  c =bi.getRGB(0, 0);
//将该颜色进行封装
Color color = new Color(c);
//将取色笔取来的图片设置成画笔的颜色
db.c=color;
} catch (AWTException e1) {
e1.printStackTrace();
}
}

}

public void mouseClicked(MouseEvent e) {
//多边形图形双击封闭
int count =e.getClickCount();
if(count==2 && "pic13".equals(command)){
g.drawLine(ox, oy, x2, y2);
flag=true;
}
}

public void mouseEntered(MouseEvent e) {
color=db.c;//设置画笔颜色
g.setColor(color);
g.setStroke(s1);
}

public void mouseExited(MouseEvent e) {

}

public void mouseDragged(MouseEvent e) {

int x=e.getX();
int y=e.getY();

//画笔功能
if("pic6".equals(command)){
g.drawLine(x1, y1, x, y);
x1=x;
y1=y;
}
//橡皮擦功能
else if("pic2".equals(command)){
db.c=Color.white;
g.setColor(db.c);
g.setStroke(s3);
g.drawLine(x1, y1, x, y);
x1=x;
y1=y;
}
//刷子功能
else if("pic7".equals(command)){
g.setStroke(s2);//设置画笔 粗细
g.drawLine(x1, y1, x, y);
x1=x;
y1=y;
}
//喷桶功能
else if("pic8".equals(command)){
//随机产生30个-15到15之间的整数
for (int i = 0; i < 30; i++) {
int xp=r.nextInt(31)-15;
int yp=r.nextInt(31)-15;
//在x,y附件绘制原点
g.drawLine(x+xp, y+yp, x+xp, y+yp);
}

}

}

public void mouseMoved(MouseEvent e) {

}

}


测试类:Test

package com.huaxin.zhou1;

public class Test {

//测试函数
public static void main(String[] args) {
DrawBorder db = new DrawBorder();
db.initFrame();
}
}


运行结果:



总结:

仔细理解各种功能的实现机制,按照思路编写程序!

遇到的问题,因坐标值传递出错,绘制的图形不正确,出现很多很怪异的图形;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: