一、画板界面的实现
简单分析:建立一个DrawingFrame类继承自JFrame类,在实例化后的窗体北边面板上加各种按钮,中间面板用来绘图。
注意:1.因为绘图时只能在中间面板上画,所以不能直接在窗体上取画布。
2.画图是在中间面板完成的,显而易见中间面板是一个事件源,而且画图方式是通过鼠标的按下(pressed)、释放(released)、单击(clicked)或者拖动(dragged)等完成的,所以要添加处理类实现鼠标监听器接口MouseListener和MouseMotionListener(或者继承类MouseAdapter),与之对应的鼠标事件类型是MouseEvent;点击不同按钮要完成不同形状或者绘图方式的切换,所以各按钮上要添加ActionListener来决定所画形状。
3.在DrawingFrame类中定义一个字符型全局变量shapes,再定义一个getshape()方法,这样可以得到按钮上的命令。
DrawingFrame类的建立如下:
public class DrawingFrame extends JFrame{
/**
*入口主函数
* @param args
*/
public static void main(String[] args) {
//实例化一个界面
DrawingFrame newFrame = new DrawingFrame();
newFrame.initUI();
}
private String shapes = "直线";
public String getshapes(){
return shapes;
}
//初始化界面的方法
public void initUI(){
this.setTitle("简单画板");//定义标题
this.setLocation(250,100);//窗体位置
this.setSize(700, 500);//窗体大小
this.setResizable(false);//大小不可调整
this.setDefaultCloseOperation(3);//关闭时退出程序
//实例化两个面板
JPanel northjp = creatNorthPanel();
JPanel centerjp = creatCenterPanel();
this.add(northjp,BorderLayout.NORTH);
this.add(centerjp,BorderLayout.CENTER);
this.setVisible(true);
//获取画布必须在窗体可见之后,否则为null
Graphics g = centerjp.getGraphics();
g.setColor(Color.BLUE);
//实例化一个DrawingListener类的处理对象
DrawingListener dr = new DrawingListener(g,this);
centerjp.addMouseListener(dr);
centerjp.addMouseMotionListener(dr);
}
//创建北边面板的方法
public JPanel creatNorthPanel(){
JPanel jp = new JPanel();
jp.setPreferredSize(new Dimension(0,50));
jp.setBorder(null);
ActionListener ac = new ActionListener(){
public void actionPerformed(ActionEvent e){
shapes = e.getActionCommand();
if(shapes.equals("还原")){
repaint();//清除画面
}
else if(shapes.equals("铅笔")){
System.out.println(shapes+"模式");
}
else
System.out.println("现在选择画"+shapes);
}
};
JButton jbuLine = new JButton("直线");
JButton jbuRect = new JButton("矩形");
JButton jbuRouR = new JButton("圆角矩形");
JButton jbuCirc = new JButton("圆");
JButton jbuTria = new JButton("三角形");
JButton jbuClear = new JButton("还原");
JButton jbuPencil = new JButton("铅笔");
jbuLine.setBorderPainted(false);
jbuLine.setFocusPainted(false);
jbuRect.setBorderPainted(false);
jbuRect.setFocusPainted(false);
jbuRouR.setBorderPainted(false);
jbuRouR.setFocusPainted(false);
jbuCirc.setBorderPainted(false);
jbuCirc.setFocusPainted(false);
jbuTria.setBorderPainted(false);
jbuTria.setFocusPainted(false);
jbuClear.setBorderPainted(false);
jbuClear.setFocusPainted(false);
jbuPencil.setBorderPainted(false);
jbuPencil.setFocusPainted(false);
jbuLine.addActionListener(ac);
jbuRect.addActionListener(ac);
jbuRouR.addActionListener(ac);
jbuCirc.addActionListener(ac);
jbuTria.addActionListener(ac);
jbuClear.addActionListener(ac);
jbuPencil.addActionListener(ac);
jp.add(jbuLine);
jp.add(jbuRect);
jp.add(jbuRouR);
jp.add(jbuTria);
jp.add(jbuCirc);
jp.add(jbuClear);
jp.add(jbuPencil);
jp.setBackground(Color.DARK_GRAY);
return jp;
}
//创建中间面板的方法
public JPanel creatCenterPanel(){
JPanel jp = new JPanel();
jp.setBackground(Color.WHITE);
jp.setBorder(null);
return jp;
}
}
二、建立图形图像处理类,该类实现MouseListener和MouseMotionListener接口,达到画画的目的
MouseListener中处理鼠标事件的方法有 mousePressed(MouseEvent)(鼠标按下)、mouseReleased(MouseEvent)(鼠标释放)、mouseClicked(MouseEvent)(鼠标单击)、mouseEntered(MouseEvent)(鼠标进入)、mouseExited(MouseEvent)(鼠标离开)
MouseListener中处理鼠标事件的方法有 mouseDragged(MouseEvent) (鼠标拖动)、mouseMoved(MouseEvent)(鼠标移动)
1.简单图形的绘画(直线、矩形、圆、圆角矩形)
在Graphics中有专门画简单图形的方法,这些方法可以直接调用。
画直线: drawLine(int x1, int y1, int x2, int y2) 在此图形上下文的坐标系中,使用当前颜色在点 (x1, y1)
和 (x2, y2)
之间画一条线。
画矩形: drawRect(int x, int y, int width, int height) 绘制指定矩形的边框。矩形的左边缘和右边缘分别位于 x
和 x + width
。上边缘和下边缘分别位于 y
和 y + height
。使用图形上下文的当前颜色绘制该矩形。
圆角矩形:drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) 用此图形上下文的当前颜色绘制圆角矩形的边框。矩形的左边缘和右边缘分别位于 x
和 x + width
。矩形的上边缘和下边缘分别位于 y
和 y + height
。
画圆: drawOval(int x, int y, int width, int height) 绘制椭圆的边框。得到一个圆或椭圆,它刚好能放入由 x
、y
、width
和 height
参数指定的矩形中。
根据函数可以观察出这些图形均可由两点得到,可以在鼠标按下时得到一个点的坐标,鼠标释放时得到一个点的坐标,完成绘画。另外注意鼠标拖动的方向对图形的影响。
//画简单图形的方法
public void drawing(){
//判断画直线
if(fm.getshapes().equals("直线"))
g.drawLine(x1, y1, x2, y2);
//画矩形
if(fm.getshapes().equals("矩形")){
if(x1<x2&&y1<y2)
g.drawRect(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1));
if(x1>x2&&y1<y2)
g.drawRect(x2, y1, Math.abs(x2-x1), Math.abs(y2-y1));
if(x1<x2&&y1>y2)
g.drawRect(x1, y2, Math.abs(x2-x1), Math.abs(y2-y1));
if(x1>x2&&y1>y2)
g.drawRect(x2, y2, Math.abs(x2-x1), Math.abs(y2-y1));
}
//画圆角矩形
if(fm.getshapes().equals("圆角矩形")){
if(x1<x2&&y1<y2)
g.drawRoundRect(x1, y1, Math.abs(x2-x1), Math.abs(y2-y1),10,10);
if(x1>x2&&y1<y2)
g.drawRoundRect(x2, y1, Math.abs(x2-x1), Math.abs(y2-y1),10,10);
if(x1<x2&&y1>y2)
g.drawRoundRect(x1, y2, Math.abs(x2-x1), Math.abs(y2-y1),10,10);
if(x1>x2&&y1>y2)
g.drawRoundRect(x2, y2, Math.abs(x2-x1), Math.abs(y2-y1),10,10);
}
//画圆
if(fm.getshapes().equals("圆")){
if(x1<x2&&y1<y2)
g.drawOval(x1, y1,Math.abs(x2-x1), Math.abs(x2-x1));
if(x1>x2&&y1<y2)
g.drawOval(x2, y1, Math.abs(x2-x1), Math.abs(x2-x1));
if(x1<x2&&y1>y2)
g.drawOval(x1, y2, Math.abs(x2-x1), Math.abs(x2-x1));
if(x1>x2&&y1>y2)
g.drawOval(x2, y2, Math.abs(x2-x1), Math.abs(x2-x1));
}
public void mousePressed(MouseEvent e){
//获取按下的坐标位置
x1 = e.getX();
y1 = e.getY();
}
public void mouseReleased(MouseEvent e){
//获取释放的坐标位置
x2 = e.getX();
y2 = e.getY();
//绘图函数
drawing();
}
2.画三角形(画一条直线后任点一点将该点与直线两端点连接)
分析:先画了一条直线,画法与画直线相同。因为当鼠标单击时要完成与直线两端点的连接,所以必须要将之前的按下与释放坐标保存,然而单击过程就是一个按下+释放的过程,当完成单击时,之前所保存的坐标也更改了,按下、释放、单击的点的坐标就会相同。故而在监听器内要设置一个标志位,让按下、释放的点坐标得以保存。
public void mousePressed(MouseEvent e){
//获取按下的坐标位置
x1 = e.getX();
y1 = e.getY();
if(fm.getshapes().equals("三角形")){
if(t==0){//t为标志位且初始值为0
ax = x1;
ay = y1;
t=1;
}
}
}
public void mouseReleased(MouseEvent e){
//获取释放的坐标位置
x2 = e.getX();
y2 = e.getY();
//绘图函数
drawing();
if(fm.getshapes().equals("三角形")){
if(t==1){
g.drawLine(x1,y1,x2,y2);
bx = x2;
by = y2;
t = 2;
}
}
}
public void mouseClicked(MouseEvent e) {
if(fm.getshapes().equals("三角形")){
if(t==2){
g.drawLine(ax,ay,x1,y1);
g.drawLine(bx,by,x1,y1);
t = 0;
}
}
}
3.铅笔工具的实现
分析:根据铅笔工具的特性,易想到使用MouseDragged,鼠标在画图板上朝不同方向拖动,拖动就会产生新的坐标,只要把新坐标和老坐标的点依次连接起来就是铅笔的效果。
private Polygon p = new Polygon();
public void mousePressed(MouseEvent e){
p.addPoint(e.getX(), e.getY());
if(fm.getshapes()=="铅笔"){
firstp = p.npoints;
}
}
public void mouseDragged(MouseEvent e) {
p.addPoint(e.getX(), e.getY());
if(fm.getshapes()=="铅笔")
for(int i = firstp;i<p.npoints-1;i++){
System.out.println(p.xpoints[i]+" "+p.ypoints[i]);
g.drawLine(p.xpoints[i], p.ypoints[i], p.xpoints[i+1], p.ypoints[i+1]);
}
System.out.println(fm.getshapes()+"实现");
}