Java——简单画图板的制作

[color=darkblue]Java——简单画图板的制作
现在我们用一些比较基础的Swing包中的类和监听器来完成一个简单画图板的制作。
首先:画图板需要图形化的界面,界面上还需要有按钮,标签等组件。
其次:在按下相应按钮时应该用监听器来接收信息,告诉程序要干什么。
最后:需要把所画图形重绘出来。避免最小化或移动窗口后所画图形的缓存被清理掉。


现在,我们来做一个画图板的主界面,可以把它放在一个类中:我们可以叫它Frame类,让它继承Jframe类,拥有其属性和方法
然后在这个Frame对象上添加我们所需要的组件,假设我们需要画图板能画出直线,立方体。(1):
我们可以添加两个按钮。使得我们点选直线按钮时能画出直线。点选矩形按钮时能画出立方体。我们还需要一个可以选择颜色的组件。这里可以用JcolorChooser中的showDialog方法来进行颜色选择。
(2):我们还需要在界面上加入画布对象,这样才可以绘画。
(3):我们还需要在画布上加入监听器对象,在按钮上加入监听器对象。
(4):为了完成重绘,我们需要把画好的形状对象存入一个队列中,然后重写Jframe中的paint方法(父类的paint方法是把所画图形存在缓存中。当窗口改变时清空缓存)。重写paint。使窗口改变时重绘存入队列的形状对象。

首先,我们先来做一个画图板界面:
package DrawTest;
import java.awt.FlowLayout;
import java.awt.Graphics;
import javax.swing.JButton;

/**
* 主界面类,继承JFrame
*
* @author Administrator
*
*/
public class Frame extends javax.swing.JFrame {

//创建用来存储形状对象的容器
public static ShapeList<Shape> shapes=new ShapeList<Shape>();


/**
* 创建画板界面的方法
*/
public void InitFrame() {
/**
* 设置窗口标题和大小
*/
this.setTitle("我的画板程序");
this.setSize(500, 600);
/**
* 设置布局为流式布局,1代表居中
*/
FlowLayout layout=new FlowLayout(1);
//将布局对象添加到窗口上
this.setLayout(layout);
/**
* 创建几个按钮
*/
javax.swing.JButton bu1=new javax.swing.JButton("直线");
javax.swing.JButton bu2=new javax.swing.JButton("矩形");
javax.swing.JButton bu3=new javax.swing.JButton("颜色");
/**
* 将按钮添加到窗体上
*/
this.add(bu1);
this.add(bu2);
this.add(bu3);
//设置窗口为可见
this.setVisible(true);
//添加画布到窗体上
Graphics g=this.getGraphics();

//添加带画布的监听器对象
Listener li=new Listener(g);

//给窗体加上监听器
this.addMouseListener(li);
//给按钮加上监听器
bu1.addActionListener(li);
bu2.addActionListener(li);
bu3.addActionListener(li);

}
这样就完成了画图板界面的创建;

接下来就要实施按钮功能了。使能在用户点击了直线按钮后可以在画布上画直线,和点击了矩形后能载画布上画立方体以及点击颜色按钮能选择颜色的操作。这就是监听器要完成的任务。
我们新建另一个类作为监听器类,我们叫他Listener类;鉴于我们需要在画布上用鼠标能作图,我们需要用到鼠标监听器。而且需要在点击按钮时能依据按钮上文字判断操作,我们需要动作监听器。于是我们让Listener继承MouseListener 和ActionListener两个接口,由于是接口,它们里面的方法都要被实现。
当我们把Listener的对象添加于Frame对象上后,就可以对Frame进行监听了。

代码:
package DrawTest;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JColorChooser;

/**
* 监听器类,继承鼠标监听器和动作监听器接口
*
* @author Administrator
*
*/
public class Listener implements MouseListener, ActionListener {

private Graphics gr;
private int x1, x2, y1, y2;
private Color color;
private String text = "Line";
//带画布对象的构造方法,将Frame中的画布传入监听器对象
public Listener(Graphics gr) {
this.gr = gr;
}

/**
* 鼠标按下时的方法,获得鼠标按下时的坐标
*/
public void mousePressed(MouseEvent e) {
// 将鼠标按下时的坐标赋值给x1,y1
x1 = e.getX();
y1 = e.getY();
}

/**
* 鼠标离开时的方法,获得鼠标离开时的坐标。并画出图形
*/
public void mouseReleased(MouseEvent e) {
// 将鼠标释放时的坐标赋值给x2,y2
x2 = e.getX();
y2 = e.getY();
// 设置作画颜色 在监听器类中写出getColor方法
gr.setColor(getColor());
// 当要画直线的时候
if (text.equals("直线")) {
// 实例化一个直线对象 (接下来讲述)
Shape l = new Line();
// 给直线对象属性赋值
l.x1 = x1;
l.x2 = x2;
l.y1 = y1;
l.y2 = y2;
l.color=color;
// 调用画直线方法
l.draw(gr);
//将画好对象放入队列保存
Frame.shapes.add(l);

}
else if (text.equals("矩形")) {
// 实例化一个矩形对象
Shape r = new Rect();
// 给矩形对象属性赋值
r.x1 = x1;
r.x2 = x2;
r.y1 = y1;
r.y2 = y2;
r.color=color;
// 调用画直线方法
r.draw(gr);

//将画好对象放入队列保存
Frame.shapes.add(r);
}
}

public void mouseClicked(MouseEvent e) {

}

public void mouseEntered(MouseEvent e) {
}

public void mouseExited(MouseEvent e) {
}

// ********************************************************************************

/**
* 定义选择颜色的方法
*/
public void actionPerformed(ActionEvent e) {
// 将事件源的文本赋值给text、
text = e.getActionCommand();
// 判断事件源的文本
if (text.equals("颜色")) {
// 将选择的颜色赋值给color
color = JColorChooser.showDialog(null, "Choose Color", Color.black);
}

}

// *********************************************************************************
/**
* 得到颜色的方法
*/
public Color getColor() {
// 返回颜色的值
return color;
}
}

上面说到的监听器中使用了Shape对象,这是用来绘画形状的一个抽象类。它可以具体由Line和Rect实现。让Line跟Rect继承它,并实现其中draw方法即可。代码如下:
package DrawTest;
import java.awt.Color;
import java.awt.Graphics;

/**
* 形状类,抽象类
* @author Administrator
*
*/
public abstract class Shape {
/**
* 属性:点坐标
*/
int x1,x2,y1,y2;
/**
* 属性:颜色
*/
    Color color;
    /**
     * 绘制形状的方法
     */
    public abstract void draw(Graphics g);
}

以上是Shape类具有的方法和属性,现在具体的实现,我们的画图板可以绘画直线和矩形。于是我们用Line类和Rect类来继承Shape类。分别实现draw方法,代码如下:

Line类
package DrawTest;
import java.awt.Graphics;
/**
* 绘制直线对象的方法
*
* @author Administrator
*
*/
public class Line extends Shape {

//实现父类中的draw方法
public void draw(Graphics g) {
//设置画布颜色为所选颜色
g.setColor(color);
//调用画直线方法
g.drawLine(x1, y1, x2, y2);
}
}
Rect类:
package DrawTest;

import java.awt.Graphics;

/**
* 定义一个Rect类继承Shape类
*
* @author Administrator
*
*/
public class Rect extends Shape {

/**
* 实现父类抽象方法
*/
public void draw(Graphics g) {
g.setColor(color);
g.drawRect(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y2 - y1));
}
}

接下来就是要实现重绘,这需要一个队列来保存所画的形状,我们新建一个ShapeList<E>类来保存形状对象。这里用到了泛型,因为我们要用它来保存不同类的对象。

ShapeList内需要有能把元素加到队列中的方法,还需要有根据下标得到队列对象的方法,此外,还要有获得队列大小的方法。下面来实现ShapeList类

代码 :
package DrawTest;
/**
* 定义泛型队列类,用来保存形状对象
* @author Administrator
*
* @param <E>
*/
public class ShapeList<E> {
//定义一个数组用来保存形状对象
private Object[] Shapes=new Object[0];

public void add(E e){
//新数组,长度较原数组加一
Object[] Shapesnew=new Object[Shapes.length+1];
//将新元素加入新数组末尾
Shapesnew[Shapes.length]=e;
//将原数组元素复制到新数组中
for(int i=0;i<Shapes.length;i++){
Shapesnew[i]=Shapes[i];
}
//将新数组赋值给原数组
Shapes=Shapesnew;
}
/**
* 得到队列长度
* @return
*/
public int size(){
return Shapes.length;
}

//得到队列对象
public E getShape(int index){
E sh=(E)Shapes[index];
return sh;
}
}

最后我们需要做的就是能实现重绘,就是一个存入形状对象,取出形状对象,画出所取的形状对象的过程。这要我们重写JFrame类(也就是Frame的父类)中的paint方法:
代码如下:
/**
* 重写父类的paint方法
*/
public void paint(Graphics g){
//调用父类的方法来正确绘制窗体
super.paint(g);
//遍历形状对象
for(int i=0;i< shapes.size();i++){
//取得形状对象
Shape sh=shapes.getShape(i);
//绘制形状对象
sh.draw(g);
}
}

然后我们再写一个Main类作为程序入口,创建一个Frame对象并调用方法,就可以运行画图板程序了。
package DrawTest;
/**
* 程序入口
* @author Administrator
*
*/
public class Main {
public static void main(String[] args) {
Frame f=new Frame();
f.InitFrame();
}
}

[color=darkblue]
[/color][/color]

你可能感兴趣的:(java,swing,画图板)