4.1 Paint 画笔&&鼠标监听事件
4.1.1 Paint 画笔
大家了解过 GDI+ 吗?
答:GDI在全称是Graphics Device Interface,即图形设备接口。是图形显示与实际物理设备之间的桥梁。
Java 的 AWT 是基于 C/C++ 写的,而 C/C++ 的图形库,在Windows 平台上,是基于 Win32API 的 GDI+接口 写的。
如果你有一定的了解,肯定知道 任何的图形界面其实都是 类似于像 画画一样,一点儿一点儿 画出来的!只不过 这些复杂的 画画过程,被我们 封装起来,形成了一个方法,当我们去调用时候的,就会瞬间产生一个 窗口,甚至是各种组件。
这章节,我们就来介绍,Paint 画笔,是Java AWT 类库,最先封装的方法之一。(没有这个方法,可能就没有 一键生成界面的那些方法。)
我们会发现,当我们每次 继承 Frame 类的时候,都可以 写这么多的方法来使用。但是由于我们对 GUI 编程只是作为了解,所以学会需要的就可以了。
package com.muquanyu.lesson03;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class TestPaint {
public static void main(String[] args) {
MyPaint m = new MyPaint();
m.loadFrame();
}
}
class MyPaint extends Frame{
public void loadFrame()
{
setBounds(200,200,600,500);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
System.exit(0);
}
});
setVisible(true);
}
//画笔方法
@Override
public void paint(Graphics g)
{
super.paint(g);
//画笔,需要有颜色,画笔就是用来画画的。
g.setColor(Color.red);
g.drawOval(100,100,100,100);
g.setFont(new Font("宋体",Font.PLAIN,32));
g.drawString("你好",200,200);
}
}
首先我们要用 paint 这个方法,其实也可以 不放在 Mypaint 子类里,直接 建立个 Frame 对象就能玩。
Graphics g = new Graphics();//图像
g.setColor(Color.red);
g.drawOval(100,100,100,100);
g.setFont(new Font(“宋体”,Font.PLAIN,32));
g.drawString(“你好”,200,200);
Frame.paint(g);//把图像画出来
想画什么,直接就调用 g 的方法就行,比如画个 空心圆,Oval,画字符串就是 String。很简单的,而且还可以设置画笔的属性,比如说 设置它的颜色 set Color,设置它画出 字体的大小,粗细和样式。比如说 宋体,Font.BOLD,18px。
举例:g.setFont(new Font(“宋体”,Font.PLAIN,32));
这个 paint 是很有用的,在你对图形进行处理的时候,很难做到自定义,甚至在图片上显示几个字出来,都很难。但是 paint 可以做到!
4.1.2 鼠标监听事件
MouseAdapter(是鼠标的适配器,不是监听事件),所以不建议用implements 来实现接口,而是 直接继承 就行了!
适配器是 多个事件组合在一起 形成的接口。interface,但是 当你要自定义监听器的时候,想要 从 适配器那里自定义。那么就建议你不要傻傻的 用 implements ,因为 implements 是真 abstract!!意味着你必须 助写 所有适配器接口下的 方法!多不划算呀,这不扯淡呢吗。。
- mousePressed(这次就介绍一个 鼠标监听事件,当鼠标按下时)
4.1.2.1 实现鼠标按下后就画圆圈
package com.muquanyu.lesson03;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Iterator;
public class TestMouseLisener {
public static void main(String[] args) {
MyFrame frame = new MyFrame();
}
}
//自己的类
class MyFrame extends Frame{
//画画需要画笔,需要监听鼠标当前的位置,而且要存储这个点
MyFrame(){this("");};
ArrayList points;
public MyFrame(String name)
{
super(name);
setBounds(200,200,400,300);
//存鼠标点击的点
//<>这个是泛型编程的 模板类型,即不确定是什么类型,所以你需要把确定的类型写进去!
points = new ArrayList<Point>();
setVisible(true);
this.addMouseListener(new MyMouseListener());
}
@Override
public void paint(Graphics g){
//画画,监听鼠标的事件
Iterator iterator = points.iterator();
while(iterator.hasNext())
{
Point point = (Point)iterator.next();//读取出 每个坐标
g.setColor(Color.BLUE);
g.fillOval(point.x,point.y,10,10);//根据坐标 画圆
}
}
public void addPoint(Point point)
{
points.add(point);
}
private class MyMouseListener extends MouseAdapter {
@Override
public void mousePressed(MouseEvent e){
MyFrame frame = (MyFrame)e.getSource();
//这里我们点击的时候,就会在界面上产生一个点!
//这个点就代表鼠标的点
frame.addPoint(new Point(e.getX(),e.getY()));
frame.repaint();
}
}
}
解析:
- 首先我们需要获取到 鼠标的坐标位置,然后将鼠标的坐标位置存储到 ArrayList 这个集合里面。(实际上也可以用 class 封装一个 伪结构体,设定 int x 和 int y两个属性,定义一个数组来进行存储。只不过需要每次都对数组的大小进行扩张,还要保存之前的数组进行再次存储和赋值。然后用 for 循环来进行 画画就行了。这就显得很麻烦。用链表又显得大材小用,所以 直接 用ArrayList 这个 集合的容器模板来进行存储,和方法的调用是极其好的解决方案!)
- 每次点击鼠标,都需要把 鼠标当前的位置 添加到 points 这个集合里面。用 ArrayList.add(new Point(e.getX(),e.getY())) 方法就行。
frame.getX() 和 frame.getY()是获取 当前鼠标在 frame 框架的 x坐标和 y坐标的方法。- interator 只要是泛型编程,都可以 定义 迭代器,迭代器是为了 让泛型编程的容器,更加方便的操作而存在的。
Iterator iterator = points.iterator();
iterator.hasNext() 是来检测是否还有下一个元素的意思
iterator.next() 是获取到 元素的意思- 将 iterator.next() 获取到的每个元素数据,都 用 Point 进行强转!因为我们知道 这些数据,就是 点。
- 通过 g.fillOval(x,y,宽度,高度); 来画出 圆圈。
- 因为我们每次点击鼠标,都会记录一次 坐标。然后存储到集合里面,我们只要 每次点击鼠标的时候 repaint 进行重画 就可以实现 所有圆圈的加载了。