我的画板
画板总结
1.???????? 界面的实现
public class DrawUI extends javax.swing.JFrame{private Graphics g;public static void main(String args[]){DrawUI dr=new DrawUI();dr.initUI();}//显示登录界面方法public void initUI(){this.setTitle("我的画板");//为画板设置标题 this.setSize(600,500);//为画板设置长和宽//将一个布局管理器加入到界面中java.awt.FlowLayout fl=new java.awt.FlowLayout();this.setLayout(fl);//将窗体显现出来 this.setVisible(true);}
?
?
以上就是我们简单画板的一个界面,可以说,上面的界面的实现步骤都是固定好的,那么为了实现我们的画板,我们的在界面上加上相应的元素组建,例如,我们的直线按钮,矩形按钮,以及椭圆按钮
2.给界面加上画板的相应组建
?
?
//创建直线按钮,椭圆按钮,矩形按钮的对象javax.swing.JRadioButton line=new javax.swing.JRadioButton("直线");javax.swing.JRadioButton rect=new javax.swing.JRadioButton("矩形");javax.swing.JRadioButton oval=new javax.swing.JRadioButton("椭圆");
?
?
?通常我们的画板在执行相应的画图动作时,一次选中画一种图形,而我们以上的画板界面在加完按钮元素组建后,它们都是可选择的,于是,我们就要在画板界面上添加按钮组,将三个按钮放到一块,从而使它们实现只选中一个选项的情况
//设置按钮分组,使得只选中一个有效 javax.swing.ButtonGroup group=new javax.swing.ButtonGroup();//设置按钮分组group.add(line);group.add(oval);group.add(rect);//将三个按钮加到画板当中this.add(line);this.add(Rect);this.add(Oval);
?
?
现在我们就已经基本实现了画板界面的开发,但是这个画板并不能进行画形状的基本操作,但我们随意地在上面画几笔是,它并没有出现任何的反应,这时,我们就得给这一个画板加上画板监听器,来实现坚挺花瓣上发生的相应的事件
3.画板监听器的实现
因为当我们在画图是,利用到的是鼠标的拖动来实现的,因此,我们让我们自定义画板监听器去继承鼠标监听器这一个接口,从而实现监听。我们的画板界面是继承了JFrame而来的,因为在JFrame为我们提供了一个get.Graphics()方法,可以得到java.awt.Graphics对象,通过这个画布对象,我们就可以调用这个对象里面的画各种图形的方法了,利用构造器传参的方法去实现在组运行类当中的画布对象。画板监听器中,对画板界面的监听实现后,是否也要对画板上按钮的监听呢?这时候因为我们上面将三种情况设置为了一个分组,因此我们不需要在按钮上添加监听器了,而是通过按钮的group.getSelection.getActionCommand()来得到我们相应的选中按钮的动作命令(同时我们要在DrawUI中,得到选中图形各自的动作命令),因此,刚刚定义的构造器中的参数还要加上按钮分组对象。经修改后的画板及画板监听器代码如下:
public class DrawUI extends JFrame{ private java.awt.Graphics g;public static void main(String args[]){//创建一个画板类对象DrawUI dr=new DrawUI();dr.initUI();}public void initUI(){//设置画板的标题this.setTitle("我的画板1.0");//设置画板的大小this.setSize(600, 500);//设置画板关闭时程序退出this.setDefaultCloseOperation(EXIT_ON_CLOSE);//让画板的现实位置居中this.setLocationRelativeTo(null);//设置布局管理器java.awt.FlowLayout f1=new java.awt.FlowLayout();//将布局管理器加到画板中this.setLayout(f1);//创建一个按钮组javax.swing.ButtonGroup group=new javax.swing.ButtonGroup();javax.swing.JRadioButton line=new javax.swing.JRadioButton("line");//默认选中直线line.setSelected(true);//获得按钮上的动作命令line.setActionCommand("line");javax.swing.JRadioButton Rect=new javax.swing.JRadioButton("rect");Rect.setActionCommand("rect");javax.swing.JRadioButton Oval=new javax.swing.JRadioButton("oval");Oval.setActionCommand("oval");//将三个单选设置为一组group.add(line);group.add(Rect);group.add(Oval);//将三个按钮加到画板当中this.add(line);this.add(Rect);this.add(Oval);//让窗体显示出来this.setVisible(true);//从窗体上获取画布g=this.getGraphics();DrawListener1 li=new DrawListener1(g,group);//将监听器加到窗体当中this.addMouseListener(li); }}
?
?
?
public class DrawListener1 implements java.awt.event.MouseListener{private int x1,x2,y1,y2; //得到坐标的位置private java.awt.Graphics g;//为了得到一个画布对象 private javax.swing.ButtonGroup group;//为了得到一个分组,实现单选private String type = "line";public DrawListener1(java.awt.Graphics g,javax.swing.ButtonGroup group){this.g=g;this.group=group;} public void mousePressed(MouseEvent e){ //判断要画的是什么图形,得到选项中的动作命令 type=group.getSelection().getActionCommand(); //得到按下使得光标 x1=e.getX(); y1=e.getY(); } //释放鼠标 public void mouseReleased(MouseEvent e){ //得到释放时的光标 x2=e.getX(); y2=e.getY(); //得到数组x和y //调用画布对象的方法,画直线,画圆,画矩形,画三角形 if(type.equals("line")){ g.drawLine(x1, y1, x2, y2); } else if(type.equals("rect")){ g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2)); } else if(type.equals("oval")){ g.drawOval(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1-x2), Math.abs(y1-y2)); } } //进入 public void mouseEntered(MouseEvent e){ //System.out.println("mouseEntered"); } //离开 public void mouseExited(MouseEvent e){ //System.out.println("mouseExited"); } //点击 public void mouseClicked(MouseEvent e){ //System.out.println("mouseClicked"); } }
?
?
?
?
注意点:1.我们需要得到画板上的画布对象,从而利用个画布对象上方法实现绘制的不同图形
?????? 2.因为按钮分组有得到一组中选中哪个按钮的选择,于是我们就可以通过
??????? type=group.getSelection().getActionCommand();来得到相应的动作命令了
4.画板的重绘
当我们移动画板超出屏幕,或是当我们缩小画板时,我们之前所画的形状就没有了,这是因为我们没有将我们划过的形状保存到内存当中。窗体在屏幕上显示时,是将窗体的数据从内存中提取到缓存的,当窗体再次显示时,程序会从内存中获取更新的数据,于是,我们之前画的形状就没有了。那么,我们怎样将划过的形状存入到内存稻种去呢?我们运用到了之前学习的队列,也就是说,我们将Shape这一个抽象类作为队列数组的元素,将每次画好的形状加到队列中,就可以实现了。完整代码如下:
?
?
import java.awt.Graphics;import javax.swing.JFrame;import com.lirui.List.ListImp1;/** * 画板类 * @author lr * */public class DrawUI extends JFrame{ private java.awt.Graphics g; private ListImp1<Shape> shapes=new ListImp1<Shape>(10,10); public static void main(String args[]){//创建一个画板类对象DrawUI dr=new DrawUI();dr.initUI();}public void initUI(){//设置画板的标题this.setTitle("我的画板1.0");//设置画板的大小this.setSize(600, 500);//设置画板关闭时程序退出this.setDefaultCloseOperation(EXIT_ON_CLOSE);//让画板的现实位置居中this.setLocationRelativeTo(null);//设置布局管理器java.awt.FlowLayout f1=new java.awt.FlowLayout();//将布局管理器加到画板中this.setLayout(f1);//创建一个按钮组javax.swing.ButtonGroup group=new javax.swing.ButtonGroup();//获得按钮上的动作命令javax.swing.JRadioButton line=new javax.swing.JRadioButton("line");//默认选中直线line.setSelected(true);line.setActionCommand("line");javax.swing.JRadioButton Rect=new javax.swing.JRadioButton("rect");Rect.setActionCommand("rect");javax.swing.JRadioButton Oval=new javax.swing.JRadioButton("oval");Oval.setActionCommand("oval");//将三个单选设置为一组group.add(line);group.add(Rect);group.add(Oval);//将三个按钮加到画板当中this.add(line);this.add(Rect);this.add(Oval);//让窗体显示出来this.setVisible(true);//从窗体上获取画布g=this.getGraphics();DrawListener1 li=new DrawListener1(g,group,shapes);//将监听器加到窗体当中this.addMouseListener(li);} //重写父类绘制的方法 public void paint(Graphics g){ //实现父类自己的绘制方法 super.paint(g); //实现子类自己的绘制方法 drawshape(g); } public void drawshape(Graphics g){ for(int i=0;i<shapes.size();i++){ //得到Shape队列中的元素 Shape sh=shapes.get(i); //将它们重新画出来 sh.draw(g); } } }}
?
?
?
import java.awt.Color;import java.awt.event.MouseEvent;import com.lirui.List.ListImp1;/** * 画板监听器1.0 * @author lr * */public class DrawListener1 implements java.awt.event.MouseListener{private int x1,x2,y1,y2; //得到坐标的位置private java.awt.Graphics g;//为了得到一个画布对象 private javax.swing.ButtonGroup group;//为了得到一个分组,实现单选 private String type = "line"; private Color color=Color.BLACK;//设置画线的颜色为黑色 private ListImp1<Shape> shape;//定义一个存放图形的形状队列public DrawListener1(java.awt.Graphics g,javax.swing.ButtonGroup group,ListImp1<Shape> shape){this.g=g;this.group=group;this.shape=shape;} public void mousePressed(MouseEvent e){ //判断要画的是什么图形,得到选项中的动作命令 type=group.getSelection().getActionCommand(); //得到按下使得光标 x1=e.getX(); y1=e.getY(); } //释放鼠标 public void mouseReleased(MouseEvent e){ //得到释放时的光标 x2=e.getX(); y2=e.getY(); //得到数组x和y //调用画布对象的方法,画直线,画圆,画矩形,画三角形 Shape sh=null;//创建一个Shape对象 if(type.equals("line")){ sh=new Line(x1,y1,x2,y2,color); } else if(type.equals("oval")){ sh=new Oval(x1,y1,x2,y2,color); } else if(type.equals("rect")){ sh=new Rect(x1,y1,x2,y2,color); } //我们不知道Shape具体实现是什么,在这里,我们实现了多态 //绘制形状 sh.draw(g); //保存到队列中 shape.add(sh); } //进入 public void mouseEntered(MouseEvent e){ //System.out.println("mouseEntered"); } //离开 public void mouseExited(MouseEvent e){ //System.out.println("mouseExited"); } //点击 public void mouseClicked(MouseEvent e){ //System.out.println("mouseClicked"); } }
?
?
?
注意点:1.我们的窗体是继承JFrame来的,他当中有一个paint(Graphics g)的方法,当我们重写这个方法时,首先重写父类方法paint(Graphics g)时,一定要先调用父类自己的,让它绘制窗体,然后我们在自己加入遍历队列的方法,将之前画的形状在重新绘制出来
?????? 2.通过定义DrawUI的属性—Shape 的一个队列,同样作为画板监听器的构造器传给画板监听器中的属性—Shape,于是,它们指向同一个队列,改变任何一方都会使得队列改变
?
?