java语言画图_Java语言实现画图工具

本文介绍了如何使用Java实现一个类似Windows画图工具的应用。通过事件监听机制,实现了包括动作监听、鼠标监听和鼠标移动监听等功能,允许用户选择图形、颜色,通过鼠标操作在画布上绘制直线、多边形等。主要涉及DrawListener类和DrawFrame类的设计,以及事件处理的各个步骤。
摘要由CSDN通过智能技术生成

我们要做的是一个类似于Windows本身自带的画图工具的应用程序,

从这一目的上来讲,这就是我们要完成的事件,所以就要用到我们之前学过的事件监听机制。事件监听机制可以分为三个部分,事件源、事件监听方法以及时间接口。在完成事件时,我们所需要的具体步骤为:

1、定义一个DrawListener事件处理类,该类要继承事件监听方法中的时间接口,并要重写接口中的抽象方法,并在对应抽象方法中填入所需要实现的功能。

addActionListener(ActionListener l);动作监听方法

用来捕获按钮上的鼠标点击以及输入框中的键盘回车动作。

addMouseListener(MouseListener l);鼠标监听方法

用来捕获事件源对象上的鼠标按下、释放、点击、进入和离开的动作。

addMouseMotionListener(MouseMotionListener l);鼠标移动监听方法

用来捕获事件源对象上的鼠标移动和鼠标拖动动作。

addKeyListener(KeyListener l);键盘监听方法

用来捕获事件源对象上是否有键盘按键按下、释放或敲击动作。

2、定义一个在DrawFrame类中,该类需要完成一个初始画图面板,再在初始面板上添加相应组件,也就是事件中要用到的事件源,并且实例化DrawListener事件处理类的对象。

3、给事件源JFrame类的对象添加addMouseListener事件监听方法,然后给addMouseListener事件监听方法指定DrawListener事件处理类的对象。

4、具体要实现的功能,填写在对应的重写的抽象方法中。

因此我们在开始之前,最先要明白的是我们需要新建两个类,一个是用来实现窗体的,就是我们所说的事件监听事件中的事件源,一个是用来做的就是用来书写事件监听方法,然后对应继承接口的。

对应的具体操作为:

1、定义一个drawlinstener类,该类需要继承我们这个事件中的监听方法,分析事件可知,在画图过程中,我们需要完后两种不同的操作。

(1)选中不同的图形图标,再在画图板上点取两点,可在两点之间画出不同的图形;

这一事件中我们要用到的是动作监听方法,我们首先要知道按钮有没有被点击,另外还有鼠标的监听方法因为我们要知道有没有在画图板上进行点击,因此我们要继承的是mouseListener和actionListener两个接口。

(2)另外画图工具还可以实现铅笔、喷枪、刷子、橡皮等,选取按钮后,点击鼠标拖动,可在拖动过的轨迹上绘制一条任意曲线。

这一种事件是鼠标按下之后,拖动鼠标至一位置松开,会在按下的位置与松开的位置之间绘制一条曲线,因此我们需要继承的是mousemotionlistener接口。

(3)选取不同的颜色图标,再选择各个图形图标,可以绘制出不同颜色的不同图形。

我们还是要区分按钮有没有被点击,这样事件同样的是需要mouselistener事件监听方法,以及actionListener事件监听方法。

这三个不同的事件监听方法,我们定义一个类MouseAdapter继承了mousemotionlistener、mouseListener这两个监听方法的接口,因此我们只需要drawlinstener类继承MouseAdapter类,再继承actionListener接口即可

因此我们的具体操作步骤为:

1、首先定义一个drawListener类,该类要继承事件监听方法中的时间接口,并要重写接口中的抽象方法,并在对应抽象方法中填入所需要实现的功能。

publicclass DrawListener extends MouseAdapter implements ActionListener{

}

并且再要重写接口mousemotionlistener、mouseListener和ActionListener接口中的抽象方法。

2、定义一个DrawFrame类中,该类需要完成一个简易初始画图面板,再在初始面板上添加相应组件,也就是事件中要用到的事件源,并且实例化DrawListener事件处理类的对象。

(1)实例化jframe顶级容器,并设置窗体的标题、大小、位置、可关闭性以及可见性。另外因为我们要在容器上添加不同位置的组件,所以设置窗体的布局为边框布局。

JFrame jfa=new JFrame();

BorderLayout bl = new BorderLayout();

jfa.setLayout(bl);

jfa.setVisible(true);

(2)实例化南北中三个JPanel窗体组件,简易画图面板的窗体,我们设置北面为图形按钮,南边为颜色按钮,剩下的中间部分为画图板。并且需要设置中间画板的背景颜色为白色。最重要的是要将窗体组件添加到容器组件的相应位置上。

JPanel centerPanel = new JPanel();

centerPanel.setBackground(Color.WHITE);

jfa.add(centerPanel, BorderLayout.CENTER);

并且我们在北边窗体上需要再实例化添加可点击的按钮,JButton类组件,按钮的个数是按照我们输入的文本的个数自动获取的,值得注意的是我们不可以在这里设置按钮框体的大小,因为按钮大小会根据文本长度自动选择,如果我们的窗体大小设置的太小,那么当文本过长时,就会出现文本显示不完全的情况,最重要的是要将按钮组件添加到窗体组件上。

Panel northjp=new JPanel();

String[]shapeArray={ "Line","Rect","Oval" ,"OvalRect" ,"Image","String","3DRect","Polygon","Pencil", "eraser","刷子","喷枪"};

for (int i = 0; i < shapeArray.length; i++) {

JButton button = new JButton(shapeArray [i]);

// button.setPreferredSize(new Dimension(70, 30)); 设置按钮的大小

northjp.add(button);

button.addActionListener(dl);

}

jfa.add(northjp,bl.NORTH);

当我们在南边窗体上实例化添加颜色的按钮组件时,与北边添加组件的方法基本一致,只是颜色按钮中不包含文本信息,我们需要添加颜色信息,并且设置对应的按钮的背景颜色为颜色信息中的颜色。设置颜色的方法有两类,一类是color直接给出的颜色,类似于Color.BLACK,Color.green,Color.red,Color.ORANGE,还有一种是可以给出颜色的三个参数,分别表示颜色的三原色的比例,new Color(220,30,30),在设置颜色之间要在类中给出颜色的属性。

JPanel southjp=new JPanel();

Color[]color={Color.BLACK,Color.green,Color.red,Color.ORANGE,Color.white,new Color(220,30,30),Color.BLUE,Color.PINK,Color.magenta,Color.cyan};

for (int i = 0; i < color.length; i++) {

JButton button = new JButton();

button.setBackground(color[i]);

button.setPreferredSize(new Dimension(30, 30));

southjp.add(button);

button.addActionListener(dl);

}

jfa.add(southjp,bl.SOUTH);

3、给对应的组件添加监听方法,并在DrawListener类中实例化DrawFrame类的对象,将frame的属性传递到DrawListener类中。

4、根据具体的操作,在对应的抽象方法中,写出对应的处理过程。

第一类获取鼠标点击下绘制特定图形

我们首先要清楚这一类是在鼠标点击画图板下完成的,因此,我们需要在鼠标按下,释放,或者点击,三个抽象方法中完成。

第一步,我们需要判断获取按钮中的信息,再根据按钮中信息的不同,绘制不同的图形,比如直线“line”,如果点击按钮获取到“line”,就获取到鼠标点击的坐标,设置画笔的颜色,最后设置画笔绘制直线,将两个点连成一条直线。获取颜色按钮信息,是因为我们给有字符串的按钮中可以获取到字符串,而没有字符串的就为空,因为我们设置了无字符串内容的按钮的背景颜色,接下来我们就可以获取他的背景颜色,再赋给画笔即可。

if (e.getActionCommand().equals("")) {

JButton button = (JButton) e.getSource();

color = button.getBackground();

} else {

shape = e.getActionCommand();

}

publicvoid mousePressed(MouseEvent e){

x1=e.getX();

y1=e.getY();

g = (Graphics2D)centerPanel.getGraphics();

g.setColor(color);

}

publicvoid mousePressed(MouseEvent e){

x2=e.getX();

y2=e.getY();

if (shape.equals("Line")) { //画直线

g.drawLine(x1, y1, x2, y2);

}

}

同理,我们可以利用选取两点绘制出不同的图形,("Line","Rect","Oval" ,"OvalRect")等,但需要注意的,当释放鼠标处的坐标小于按下处的坐标值时,绘制图形就会出现错误,因此我们需要判断大小,来绘制图形。比如绘制矩形

elseif (shape.equals("Rect")) { //画矩形

if(x2>=x1){

if(y2>=y1){

g.drawRect(x1, y1, x2-x1,y2-y1);

}else{

g.drawRect(x1, y2, x2-x1,y1-y2);

}

}

if(x2<=x1){

if(y2>=y1){

g.drawRect(x2, y1, x1-x2,y2-y1);

}else{

g.drawRect(x2, y2, x1-x2,y1-y2);

}

}

}

特例:绘制任意多边形

与绘制普通图形有些不同的是,绘制任意多边形,任意多边形的绘制,是点下鼠标后,拖动至一点释放,绘制第一条线,后面在其他位置点击一下,就会连接上一个释放点,与新的点击点,以此类推,当连续点击两次鼠标时,多边形自动闭合,最后一个点击的点连接到第一个按下的点。

因此我们在调用抽象方法时,首先在鼠标的第一次按下与释放获取到两个点的坐标绘制一条线,但在此之后鼠标的点击,绘制直线的方法就会变,因此,我们需要定义一个boolean变量flag,privateboolean flag = true;这个变量只有两个值,true或false,在第一次点击时为true,绘制直线后,改变flag的值,之后变成鼠标点击下的过程,

if(shape.equals("Polygon")&& !flag) {

x2=e.getX();

y2=e.getY();

g.drawLine(ex, ey, x2, y2);

if (e.getClickCount()== 2){

g.drawLine(sx, sy, x2, y2);

flag=true;

}

ex = x2;

ey = y2;

}

}

在flag值改变之后,可以把第一个点的坐标存储在sx,sy中,为了最后可以得到闭合图形,并把释放点也就是每次点击后的上一个点的坐标存储在ex,ey内,为了后面继续绘制直线。并且获取新的点的坐标,当点击之后,就连接上一个点ex,ey与新点击的点x2,y2,并且判断是不是点的双击,如果是双击就闭合,连接最后一个点x2,y2和第一个点sx,sy即完成任意多边形的绘制。

第二类 绘制鼠标拖动下的任意直线与图形等

鼠标拖动是需要在鼠标点击之后未释放,拖动过程中经过的地方会绘制一条线,类似于用铅笔写字。因此我们需要在鼠标拖动的抽象方法下完成。

与鼠标点击画直线类似,我们需要在鼠标拖动过程中获取所有点的坐标,并且我们只需要把所有点连接起来就可以绘制出一条线,但我们没有必要连接两个相邻的点,我们只需要把所有的点绘制出来就可以连成线,并且我们可以设置画笔的宽度以及颜色为画板的背景颜色,再设置画笔抗锯齿,就可以形成一个类似于橡皮功能的铅笔。

if (shape.equals("Pencil")) {

x2 = e.getX();

y2 = e.getY();

g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

g.setStroke(new BasicStroke(5));

g.drawLine(x1, y1, x2, y2);

x1 = x2;

y1 = y2;

}

特例:喷枪的实现

喷枪是在鼠标拖动过程中,并不是所有的点都绘制出来,只是随机的绘制几个点。那么我们就可以利用随机数的生成,来完成喷枪。

首先实例化产生随机数的方法,并设置随机数的范围,要知道random.nextInt(5)

括号里输入为5,那么随机产生的数就是0-4,五个随机数。

我们还是需要获取鼠标拖动过程中所有点的坐标,但我们把随机数利用在画图时,在获取到所有点周围绘制图形,也就是并不是所有的点都绘制出来。

Random random = new Random();

x2=e.getX();

y2= e.getY();

g.setStroke(new BasicStroke(1));

n=random.nextInt(5);

for (int i=0;i<=n;i++){

n1=random.nextInt(5);

n2=random.nextInt(5);

g.drawLine(x2, y2, x2, y2);

g.drawLine(x2+n1, y2+n2, x2+n1, y2+n2);

g.drawLine(x2-n1, y2-n2, x2-n1, y2-n2);

}

}

画图工具到这里,基本的功能就已经实现,我们只需要再加以完善,可以添加画圆,画矩形,画图片,以及橡皮等功能,就可以像Windows里的画图工具一样,画出自己想要的图形啦。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值