您的当前位置:首页正文

画图

2021-09-30 来源:年旅网
/**

* 最简单实现拖动鼠标画圆功能(可以推广画其它图形),目的: * 1、锻炼Graphics对象画图,画到什么地方, * 2、实现拖动鼠标画图时显示轨迹效果; * 3、锻炼repaint()与paint()方法应用. * 4、实现双缓冲效果. */

import java.awt.Color; import java.awt.Graphics; import java.awt.Image;

import java.awt.event.MouseEvent; import java.awt.event.MouseListener;

import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage;

import javax.swing.JFrame; import javax.swing.JPanel;

public class TestDrawFrame extends JFrame {

private static final long serialVersionUID = 1L;

// 内部类对象,用于画图的面板,实现MouseListener和MouseMotionListener接口 pane p = null;

// 按下鼠标时的X、Y坐标 int pressX; int pressY;

// 用于画图的缓冲区图片

private Image image = new BufferedImage(300, 400, BufferedImage.TYPE_INT_BGR);

// 初始化窗体

public void init() {

// 从缓冲区图片获得Graphics对象,每次注意g是哪里来的 Graphics g = image.getGraphics(); // 将缓冲区图片用白色填充背景,目的是那在上面画时好呈现各种颜色,用其它颜色作背景

// 不是不可以,但不多(习惯)。 g.setColor(Color.white); g.fillRect(0, 0, 300, 400); // 初始化面板,并添加鼠标事件 p = new pane();

p.setBackground(Color.white); p.addMouseListener(p);

p.addMouseMotionListener(p);

// 添加面板到窗体中去,并设置窗体大小,可见等 this.add(p);

this.setSize(300, 400); this.setVisible(true); }

public static void main(String[] args) {

TestDrawFrame frame = new TestDrawFrame(); frame.init(); }

/*

* 内部类,用于实现画图的面板 */

class pane extends JPanel implements MouseListener, MouseMotionListener {

private static final long serialVersionUID = 1L;

/*

* 此处要注意几点: 一:paint()方法是哪个的,可以把该代码放到外面frame中试度,因为frame

* 也有该方法,但这样一来,刷新的是frame,而不是画板;因此每次刷新时 * 面板中的paint()方法中的代码不会被执行,因此效果也没了,放到外面试试! * 二:如果把该方法注掉,然后再把窗口最大化或最小化一次(让窗口刷新), * 图片没了,那是因为每次刷新都要将缓冲区中的图片往屏幕(实际是面板,注意 这个g是从那里来的)上画一次,感觉就是没变化,还是刚才的图,试试。 */

public void paint(Graphics g) { g.drawImage(image, 0, 0, null); }

public void mousePressed(MouseEvent e) {

pressX = e.getX(); pressY = e.getY(); }

public void mouseReleased(MouseEvent e) { /*

* 此处的Graphics对象是缓冲区图片对象提供,将图画到缓冲区,要注意与下面Draw()方法

* 中的Graphics区别,(Graphics提供对象不同,画的地方不同),显示调用repaint()方法,

* 是执行pane对象的paint()方法,目的是把缓冲区的图片画到屏幕上(实

际是面板上) */

Graphics g = image.getGraphics(); g.setColor(Color.red);

int x = e.getX() > pressX ? pressX : e.getX(); int y = e.getY() > pressY ? pressY : e.getY();

g.drawOval(x, y, Math.abs(pressX - e.getX()), Math.abs(pressY - e.getY())); }

public void draw(MouseEvent e) {

/*

* 此处的Graphics对象是由画图面板Pane提供,因此画的时候只显示在面板上(显示轨迹),并不能真正

* 写到缓冲区图片上,该事件重新执行时会被第二句:g.drawImage(image, 0, 0, null);覆盖,实际

* 就成了什么都没做。于是会出现刚才画的东东一下不见了,可以将MouseReleased中的代码注

* 掉试试试!真正画图到缓冲区的代码放在了MouseReleased中,而真正将图片画到屏幕是 paint()方法中. */

Graphics g = p.getGraphics();

// 此处也很重要,如果没有此句,出现的就是很多个圆的重叠,因为没有用 // 缓冲区的图片来擦去每次拖动产生的圆,可以将该句代码注掉试试。 g.drawImage(image, 0, 0, null);

int x = e.getX() > pressX ? pressX : e.getX(); int y = e.getY() > pressY ? pressY : e.getY(); g.setColor(Color.red);

g.drawOval(x, y, Math.abs(pressX - e.getX()), Math.abs(pressY - e.getY())); }

// 以事件不关心,因此不用实现

public void mouseClicked(MouseEvent e) { }

public void mouseEntered(MouseEvent e) { }

public void mouseExited(MouseEvent e) { }

}

public void mouseDragged(MouseEvent e) { draw(e); }

public void mouseMoved(MouseEvent e) { } }

因篇幅问题不能全部显示,请点此查看更多更全内容