该组件继承自java.awt.Component组件,在这点上与JPanel上是一致的.所以在JPanel拥有与Canvas一样的功能是很很正常的.

之前的一直无法理解为啥有了JPanel还要Canvas组件干啥,毕竟JPanel功能有Canvas的功能.现在的个人理解是JPanel更多的是一个容器的概念,更多的是充当容器的作用,其中有很多是在作图中是不需要的.

在网上看到一个关于Canvas与JPanel的区别评论如下:

Canvas: AWT JPanel: Swing

Swing is based on AWT, so Canvas can be more lightweight and in lower layer.

If canvas meet all your requirements, just use Canvas.

PS: I don't think there would be too much expensive to use JPanel, just choose the one you like.

Canvas是AWT组件,JPanel是Swing组件,Swing组件是以AWT组件为基础的,从理论上来说,Canvas要比JPanel更轻量些.如果canvas能满足需求,就用canvas.

但是作者认为两者并没有太大的性能差异,所以,想用哪个就用哪个,开心就好.

上述评论链接:

public void paint(Graphics g) {

g.clearRect(0, 0, width, height);

}

可以看到,源码是直接做清屏操作,如果不重写,啥也干不了.

paint方法的具体使用,JDK 文档是这么写的:

调用此方法响应对 repaint 的调用。首先通过使用背景色填充 canvas 来清理它,然后通过调用此 canvas 的 paint 方法重绘它。注:重写此方法的应用程序应该调用 super.update(g),或者将上述功能合并到其自身的代码中。

2.update方法

与paint方法极其类似,源码如下:

public void update(Graphics g) {

g.clearRect(0, 0, width, height);

paint(g);

}

所以本质上update方法也是啥也没干,冏

3.repaint方法

该方法继承自Component组件.

JDK文档是这么说该方法的:

重绘此组件。

如果此组件是轻量级组件,则此方法会尽快调用此组件的 paint 方法。否则此方法会尽快调用此组件的 update 方法。

至此update、paint、repaint三个方法之间的默认调用关系很清楚了:

repaint---》update---》paint

repaint方式去调用update方式是通过EventQueue调用,也就是说通过AWT-EventQueue去调用.即开启了线程去重绘canvas.

repaint作用源码如下:

if (isVisible() && (this.peer != null) &&(width > 0) && (height > 0)) {

PaintEvent e = new PaintEvent(this, PaintEvent.UPDATE,

new Rectangle(x, y, width, height));

Toolkit.getEventQueue().postEvent(e);

}

在对一个不断变化的动画来说,就会容易出现线程同步问题.

示例:

class Roll extends Thread {

@Override

public void run() {

while (true) {

//创建粒子

createGrain();

//移动粒子

moveGrain();

//重绘粒子

canvas.repaint();

}

}

}

在上述例子中,粒子是在不断的变化的,存储在List中,但是由于没有重写repaint方法,在重绘粒子的时候是使用的是单独的线程去绘制粒子,而此时createGrain()与moveGrain()已经更改了存储粒子的List的了,此时会抛出如下异常.

Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException

异常

如果想要简单的解决该问题,重写repaint方法即可:

public void repaint() {

Graphics g = this.getGraphics();

update(g);

}

此外,如果不重写repaint方法,在绘制大量图案时,还容易造成界面假死的情况.

造成假死的原因个人理解是由于awt-EventQueue是负责创建用户界面和绘制图形类方法的,此时在该线程中绘制图像,导致程序没有空闲的时间去处理其他的界面事件,因此造成了假死.

完整使用示例:

CanvasTest.java:

package test;

import java.awt.Graphics;

public class CanvasTest {

final int CREATE_GRAIN_NUMBER = 5000;

JFrame frame;

WorldCanvas canvas;

List grains;

/**

* @wbp.parser.entryPoint

*/

public CanvasTest() {

init();

Graphics g = canvas.getGraphics();

g.fillOval(20, 20, 20, 20);

canvas.paint(g);

}

public void init() {

grains = new ArrayList();

frame = new JFrame();

JPanel panel = new JPanel();

frame.getContentPane().add(panel, BorderLayout.NORTH);

JButton startBtn = new JButton("开始");

panel.add(startBtn);

startBtn.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

new Roll().start();

}

});

canvas = new WorldCanvas();

canvas.setGrains(grains);

frame.getContentPane().add(canvas);

frame.setSize(400, 400);

frame.setVisible(true);

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

}

private void createGrain() {

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

grains.add(new Grain());

}

}

private void moveGrain() {

Grain grain;

for (int i = 0; i < grains.size(); i++) {

grain = grains.get(i);

grain.move();

if (grain.isDead()) {

grains.remove(i);

}

}

}

class Roll extends Thread {

@Override

public void run() {

while (true) {

createGrain();

moveGrain();

canvas.repaint();

}

}

}

public static void main(String args[]) {

new CanvasTest();

}

}

Grain.java

package test;

public class Grain{

private final int SPEED_X = 1;

private final int SPEED_Y = 1;

private final int MAX_X = 300;

private final int MAX_Y = 300;

private int pos_x;

private int pos_y;

private int radius = 5;

private int time = 1;

private boolean isDead = false;

public Grain() {

pos_x = generateRandom(0, 350);

pos_y = generateRandom(0, 350);

}

/*

* (non-Javadoc)

*

* @see test.IGrain#move()

*/

public void move() {

pos_x = pos_x + SPEED_X * time;

pos_y = pos_y + SPEED_Y * time;

if (pos_x > MAX_X || pos_y > MAX_Y) {

setDead(true);

}

}

private int generateRandom(int min, int max) {

int random = (int) (Math.random() * (max - min)) + min;

return random;

}

public int getPos_x() {

return pos_x;

}

public void setPos_x(int pos_x) {

this.pos_x = pos_x;

}

public int getPos_y() {

return pos_y;

}

public void setPos_y(int pos_y) {

this.pos_y = pos_y;

}

public boolean isDead() {

return isDead;

}

private void setDead(boolean b) {

isDead = true;

}

public int getRadius() {

return radius;

}

public void setRadius(int radius) {

this.radius = radius;

}

}

WorldCanvas.java

package test;

import java.awt.Canvas;

import java.awt.Color;

import java.awt.Graphics;

import java.util.List;

public class WorldCanvas extends Canvas {

/**

*

*/

private static final long serialVersionUID = 1L;

private List grains;

// public void update(Graphics g) {

// g.clearRect(0, 0, 350, 350);

// super.update(g);

// }

@Override

public void repaint() {

Graphics g = this.getGraphics();

update(g);

}

@Override

public void paint(Graphics g) {

g.setColor(Color.blue);

for (Grain grain : grains) {

g.fillOval(grain.getPos_x(), grain.getPos_y(), grain.getRadius(),

grain.getRadius());

}

}

public List getGrains() {

return grains;

}

public void setGrains(List grains) {

this.grains = grains;

}

} 貌似排版有点渣....... 经过一番折腾,好多了,看样子是使用的姿势不对呃~ 距离上次更新博客差不多是一年前的事情了,一年来,却没有什么大的长进,真是个悲伤的故事~

java awt canvas_JAVA.AWT.CANVAS使用相关推荐

  1. java awt canvas_java.awt 类 Canvas - Java 中文参考手册

    java.lang.Object java.awt.Component java.awt.Canvas 所有已实现的接口:ImageObserver, MenuContainer, Serializa ...

  2. java异常awt_java.awt.HeadlessException

    Linux下安装eclipse的有关问题 Linux上安装eclipse的问题1.之前在Windows下安装的Myeclipse,写了一个java程序,用到了swing界面2.然后我在ubuntu上安 ...

  3. java.awt.color,AWT Color类

    颜色类规定在默认sRGB颜色空间或颜色的任意颜色空间中的颜色确定的颜色. 类的声明 以下是声明java.awt.Color类: publicclassColorextendsObjectimpleme ...

  4. swing java awt_java中AWT和SWing的区别与联系

    AWT和Swing都是java中的包. AWT(Abstract Window Toolkit):抽象窗口工具包,早期编写图形界面应用程序的包. Swing :为解决 AWT 存在的问题而新开发的图形 ...

  5. java awt canvas_JavaFX AWT Canvas

    更新 虽然本答案中的代码曾经在Windows上使用早期版本的JavaFX,但我在OS X 10.9.5 JavaFX 8u72上重新测试了相同的代码,代码不再有效. 行swingNode.setCon ...

  6. # java swing,awt图形化界面代码案例合集

    文章目录 java awt,swing图形化界面代码案例合集 java awt,swing图形化界面代码案例合集 package Demo1; import java.awt.*; public cl ...

  7. Java学习记录 AWT绘图篇

    绘制图形 Canvas画布类 Class Canvas java.lang.Object java.awt.Component java.awt.Canvas 用来 绘制图形 或 捕获用户输入的事件. ...

  8. java awt table_java.awt.image 类 LookupTable - Java 中文参考手册

    java.lang.Object java.awt.image.LookupTable 直接已知子类:ByteLookupTable, ShortLookupTable public abstract ...

  9. java 围棋_Java.awt实现一个简单的围棋

    目录 0.前言 我小时候学过一段时间的围棋,可惜脑子不好使,是个臭棋篓子,到现在也有十多年的时间没有下过棋了,但是近几年围棋AI的出现,又让我重新关注了围棋 围棋真的很有意思,千变万化,有人简明的围空 ...

最新文章

  1. 汉语科技术语识别实验结果
  2. 2013首部著作封面抢先曝光
  3. JVM 监控以及内存分析
  4. php 开启 pathinfo,nginx下PHP开启pathinfo模式
  5. 维护SAP帮助信息(WEB)
  6. caffe blob操作
  7. Linux 内核修复5个高危漏洞
  8. Java — 如何产生随机数(Random类)
  9. VS中依赖库相对路径的配置及项目间依赖项
  10. Java面试个人简历
  11. Reza Zafarani经典教材-《社交媒体挖掘》PDF+随书课件打包分享
  12. 846计算机类,x846-《计算机类学科基础》考试内容及范围(8页)-原创力文档
  13. 中国甜奶油粉市场趋势报告、技术动态创新及市场预测
  14. SPI 读取不同长度 寄存器_几种常用的总线设计:UART/SPI/I2C
  15. 完全不懂SEO怎样入手做网站优化
  16. python|爬虫东宫小说
  17. PHP审计-RIPS
  18. 从配置,外观,写一篇小米13测评报告
  19. webpack打包命令报错显示无法加载文件——解决办法
  20. matlab绘制星座图,怎么弄星座图:systemview 信号星座图怎么画

热门文章

  1. 简单题我重拳出击,困难题我唯唯诺诺
  2. vue页面详情页返回列表页_vue 详情页返回列表页,保留列表页之前的筛选条件...
  3. 不要USB数据线调试Android开发
  4. Mac使用数据线连接安卓手机传输文件
  5. python程序设计实用教程清华大学出版社_清华大学出版社-图书详情-《Python程序设计简明教程》...
  6. Vue2.x实现根据获取到的数据 显示不同性别图片
  7. 九龙证券“风光储锂芯”集体回暖 创业板指探低回升
  8. 想要运营公众号?公众号形象定位有哪些?
  9. 软件登录软件 DIY
  10. Python之qq自动发消息