Java学习笔记(五)
画图板的实现(2018.06.7)
综合前面学习的图形界面、类的继承、事件监听机制等内容,实现一个画图板。
1.实现画图程序需要使用的API类?
JFrame 画图板是一个窗体,这是肯定需要的。
MouseListener 鼠标事件接口,提供处理按下,释放,点击,进入和离开动作的方法,我们都知道接口并不能实例化对象,因此需要写一个DrawListener类,去监听这个窗体发生的动作。而这个窗体能提供给我们的捕获动作方法有鼠标的、键盘的,但我们只需用到鼠标的,因此选取鼠标事件接口。
Graphics 画笔类,提供绘制各种图形的方法。画笔类是抽象类并不能实例化对象,所以我们要怎么调用它呢?通俗的讲,我们所看到的界面是画出来的,awt通过调用系统底层的制图函数来绘制我们的界面。因此我们可以向JFrame窗体“借”这个画笔类的对象,怎么借呢?在上一篇博客有详细说明。在窗体获取到Graphics的对象后传到DrawListener中去即可,怎么传?参照上一篇博客。
2.界面实现
DrawFrame类,作为界面,这里有一种简便的写法,就是直接extends JFrame就好了,就没有必要去实例化一个JFrame对象了,直接用this来调用一些方法即可。源码如下:
import javax.swing.JFrame;
public class DrawJFrame extends JFrame{
public static void main(String []args)
{
DrawJFrame J = new DrawJFrame();
J.initUI();
}
public void initUI()
{
this.setTitle("画板");
this.setSize(700, 500);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setVisible(true);
}
}
3.功能实现
在窗体上按下鼠标按键,然后释放鼠标按键,根据按下和释放的位置来绘制一个图形。
事件监听机制
(1)事件源对象:窗体
(2)事件监听方法:addMouseListener(MouseListener l);
(3)事件接口:MouseListener(提供了很多方法,将光标移动到它,按下F3即可查看,然后复制到你的类里面去重写即可。)
4.练习
1.实现直线、矩形、文字、图片、填充3D矩形、填充圆、任意多边形、等腰三角形。
讲一下这里:除了任意多边形、等腰三角形,其它的Java都提供了相应的方法。现在来分析如何画任意多边形和等腰三角形,首先是任意多边形:每按下一次鼠标到松开画出一条线,然后在上一次松开鼠标的地方再按下鼠标并拖动一定距离再松开,画出多条边后缝合。关键的就是这个缝合,意思就是当你最后一次松开鼠标的那个位置离你第一次按下鼠标的那个位置比较近时,将这两个点连起来(而不是你手动拖到那个点去)。一个比较笨的方法就是将鼠标第一次被按下时的x,y坐标保存起来,然后每次都与鼠标被释放时的x,y坐标作判断,距离小于某个值时,就在这两点画一条直线。(下面源码采用了这种方法)然后是画等腰三角形,已知等腰三角形两点的时候根据三角函数可以算出第个定点的x,y坐标。公式如下:
设A( x1,y1),B(x2,y2) , C(x3,y3)
若AB的斜率存在,则设tana = y1-y2/x1-x2;(此时要考虑下除0错误,因此点击的时候不要在同一个位置按下并释放鼠标)
然后根据反三角函数算的 a = arctan(y1-y2/x1-x2)
A、B两点点的距离:L=sqrt((y1-y2)*(y1-y2)+(x1-x2)*(x1-x2));
那么x3 = x2 + L*cos(a+60);(看你选取那个点为等腰三角形的顶点,x1,x2都可以)
同理 y3 = y2 + L*sin(a+60);
最后我们调用那个画多个点的方法,详情看下面的源码。
首先分析它的事件源对象,然后分析它产生的动作,选取事件监听方法,再看它有没有提供相应的捕获方法。
源码如下:
画板界面:
import javax.swing.JFrame;
public class DrawJFrame extends JFrame{
public static void main(String []args)
{
DrawJFrame J = new DrawJFrame();
J.initUI();
}
public void initUI()
{
this.setTitle("画板");
this.setSize(700, 500);
this.setDefaultCloseOperation(3);
this.setLocationRelativeTo(null);
this.setVisible(true);
DrawListener Dr = new DrawListener();//通俗的讲就是安装摄像头监控窗体
Dr.setG(getGraphics());//将借到的Graphics类的对象传到DrawListener类里面去。
this.addMouseListener(Dr);//安装摄像头
}
}
DrawListener:
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.lang.Math;
public class DrawListener implements MouseListener {
private int x1,x2,y1,y2;
private Graphics G;
public void setG(Graphics g)
{
G = g;
}
public void drawTrangle(int x1,int y1,int x2,int y2)
{
if(y1-y2!=0 && x1-x2!=0)
{
int T = (y1-y2)/(x1-x2);
int a = (int) Math.atan(T);
int L = (int) Math.sqrt((y1-y2)*(y1-y2)+(x1-x2)*(x1-x2));
int x3 = (int) (x2+(int)L*Math.cos(a+60));
int y3 = (int) (y2+(int)L*Math.sin(a+60));
int[]x={x1,x2,x3};
int[]y={y1,y2,y3};
G.drawPolygon(x, y, 3);
}
}
public void drawduobian(int x1,int y1,int x2,int y2)
{
System.out.println(x1+" "+y1);
G.drawLine(x1, y1, x2, y2);
if(Math.abs(x2-temp1)<10|| Math.abs(y2-temp2)<10)
{
G.drawLine(temp1, temp2, x2, y2);
}
}
public void mouseClicked(MouseEvent e){
}
/**
* Invoked when a mouse button has been pressed on a component.
*/
int count = 0;
int temp1 = 0;
int temp2 = 0;
int tempx2 = 0;
int tempy2 = 0;
public void mousePressed(MouseEvent e){
System.out.println("鼠标被按下!");
x1 = e.getX();
y1 = e.getY();
if(count==0)
{
temp1 = x1;
temp2 = y1;
}
count++;
}
/**
* Invoked when a mouse button has been released on a component.
*/
public void mouseReleased(MouseEvent e){
System.out.println("鼠标被释放!");
x2 = e.getX();
y2 = e.getY();
tempx2 = x2;
tempy2 = y2;
G.setColor( new Color(255,100,255));
this.drawduobian(x1, y1, x2, y2);
//G.drawLine(x1, y1, x2, y2);
//G.drawOval(x2, y2, 100, 100);//画圆的
//G.drawRect(x1, y1, 200, 100);//画矩形的
//G.drawString("AAA", x1, y1);//画文字的
//javax.swing.ImageIcon IMG = new javax.swing.ImageIcon("C:\\Users\\25280\\Desktop\\综合文件夹\\收稿\\摄影作品_张雨泉\\5.jpg");
//Image img = IMG.getImage();
//G.drawImage(img, x1, y1,null);
//G.fill3DRect(x1, y1, 100, 100, true);
//G.fillOval(x1, y1, 100, 100);
//G.fillRoundRect(x1, y1, 100, 100, 50, 50);
//this.drawTrangle(x1, y1, x2, y2);
//this.drawduobian(x1, y1, x2, y2);
}
/**
* Invoked when the mouse enters a component.
*/
public void mouseEntered(MouseEvent e){
System.out.println("鼠标进入画板!");
}
/**
* Invoked when the mouse exits a component.
*/
public void mouseExited(MouseEvent e){
System.out.println("鼠标离开画板!");
}
}
等腰三角形演示图:
任意多边形演示:
加油!