?一、画板界面的实现
??? 简单分析:建立一个DrawingFrame类继承自JFrame类,在实例化后的窗体北边面板上加各种按钮,中间面板用来绘图。
??? 注意:1.因为绘图时只能在中间面板上画,所以不能直接在窗体上取画布。
?????????????? 2.画图是在中间面板完成的,显而易见中间面板是一个事件源,而且画图方式是通过鼠标的按下(pressed)、释放(released)、单击(clicked)或者拖动(dragged)等完成的,所以要添加处理类实现鼠标监听器接口MouseListener和MouseMotionListener(或者继承类MouseAdapter),与之对应的鼠标事件类型是MouseEvent;点击不同按钮要完成不同形状或者绘图方式的切换,所以各按钮上要添加ActionListener来决定所画形状。
???????????????3.在DrawingFrame类中定义一个字符型全局变量shapes,再定义一个getshape()方法,这样可以得到按钮上的命令。
?
DrawingFrame类的建立如下:
class="java">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()+"实现"); }
?
?