关于paint() repaint() update()函数问题。

afgkidy 2008-10-15 10:49:17
1、介绍下我知道的轻量级和重量级组件
轻量级组件 是用JAVA代码画出来的,这样具有平台移植性.
重量级组件 是调用操作系统的函数画出来的组件,比如主窗体.
一般来说尽量用轻量级的组件,这样对程序的移植性很好,一般javax.swing包里的组件大部分是轻量级的java.awt里面的是重量级的。
Swing是由100%纯Java实现的,Swing组件是用Java实现的轻量级( light-weight)组件,没有本地代码,不依赖操作系统的支持,这是它与AWT组件的最大区别。由于AWT组件通过与具体平台相关的对等类(Peer)实现,因此Swing比AWT组件具有更强的实用性。Swing在不同的平台上表现一致,并且有能力提供本地窗口系统不支持的其它特性。

2、在重量级组件中,清空背景的动作在update中实现,之后调用paint()。
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;

public class HeavyWeightPaintDEMO extends Canvas { /* Canvas是重量级组件 */
int i = 20;
int j = 30;
public HeavyWeightPaintDEMO() {
this.setPreferredSize(new Dimension(250, 350));
}

//1、根据我的理解,如果不覆写update,那么将先调用update清空背景,在调用paint,这时只显示最新画出的那根直线,和预期效果一样。
//2、如果覆写update(即使用下面覆写的update函数),则先调用update(update中只有paint函数,背景不会被清空,并且调用paint,update结束后,会看到2根直
//线),再调用paint函数,也就是说paint函数被调用了2次;效果和预期一样,但是paint 只调用了一次,为啥子只调用一次呢????
//
/* public void update(Graphics g){
paint(g); //不擦除背景
}*/

public void paint(Graphics g) {
g.setColor(Color.BLACK);
g.drawLine(i, i + 30, j, j + 40);
}

public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame myFrame = new JFrame("HeavyWeightPaintDEMO");
final HeavyWeightPaintDEMO t1 = new HeavyWeightPaintDEMO();
myFrame.add(t1);
JButton move = new JButton("移动");
move.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
t1.i = t1.i + 5;
t1.repaint();
}
}
);

myFrame.add(BorderLayout.SOUTH, move);
myFrame.pack();
myFrame.setVisible(true);
}
}

3、而对于轻量级组件,用户调用repaint()后,repaint()调用paint()实现绘制的动作。因此清空背景的动作在repaint()中实现,因此我们覆盖update不再有用,因为轻量级组件repaint()不再调用update。但是如果我们覆盖了repaint(),就可以达到同样的效果。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DrawString extends JPanel {
private int x = 20;
private int y = 20;

public void paint(Graphics g) {
g.setColor(Color.red);
g.drawString("string ", x, y);
x = x + 20;
}

public static void main(String[] args) {
JFrame myFrame = new JFrame("DrawString");
final DrawString t1 = new DrawString();
myFrame.add(t1);
JButton move = new JButton("移动");
move.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
t1.repaint();
}
}
);

myFrame.add(BorderLayout.SOUTH, move);
myFrame.setSize(400, 300);
myFrame.setVisible(true);
}
}

为什么实际效果背景没有被清除呢?

我哪里理解错误,请知道的解释下,谢谢。
...全文
370 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
zk20052009 2008-10-16
  • 打赏
  • 举报
回复
repaint()
方法只是会调用update()方法
如果还有疑问 你可以看下src包中的Canvas
afgkidy 2008-10-16
  • 打赏
  • 举报
回复
你意思是 重写之前
调用了update 就不会调paint 了吧。
zk20052009 2008-10-16
  • 打赏
  • 举报
回复
你重写之前
repaint()方法调用
update()响应
update
{
清屏();
paint();
}
所以你只看到一条直线

重写后
update()
{
paint();
}
repaint()调用
update()响应
原来屏幕上有一条直线
现在update()由于没有清屏,所以原来那条直线还在
然后再画一条,就两条了
afgkidy 2008-10-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 zk20052009 的回复:]
我再表达自己观点清楚点
就是说update()方法响应repaint()方法
update()方法包括两个部分 1使用背景色填充 2调用paint()

而不是说repaint()方法调用update()再调用paint()
[/Quote]

从我的第一个程序来看,不是这样的,这2个方法分开调用的。你再把我说的看清楚点。
zk20052009 2008-10-16
  • 打赏
  • 举报
回复
我再表达自己观点清楚点
就是说update()方法响应repaint()方法
update()方法包括两个部分 1使用背景色填充 2调用paint()

而不是说repaint()方法调用update()再调用paint()
zk20052009 2008-10-16
  • 打赏
  • 举报
回复
是原来的update()方法里面就调用了paint()方法吧
而不是说是分开调用update();再paint();
zk20052009 2008-10-16
  • 打赏
  • 举报
回复
api中JComponent的paint方法
public void paint(Graphics g)由 Swing 调用,以绘制组件。应用程序不应直接调用 paint,而是应该使用 repaint 方法来安排重绘组件。
此方法实际上将绘制工作委托给三个受保护的方法:paintComponent、paintBorder 和 paintChildren。按列出的顺序调用这些方法,以确保子组件出现在组件本身的顶部。一般来说,不应在分配给边框的 insets 区域绘制组件及其子组件。子类可以始终重写此方法。只想特殊化 UI(外观)委托的 paint 方法的子类只需重写 paintComponent。

你要是重写paintComponent()方法就不会出现你的背景问题

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class DrawString extends JPanel {
private int x = 20;
private int y = 20;

public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.drawString("string ", x, y);
x = x + 20;
}

public static void main(String[] args) {
JFrame myFrame = new JFrame("DrawString");
final DrawString t1 = new DrawString();
myFrame.add(t1);
JButton move = new JButton("移动");
move.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
t1.repaint();
}
}
);

myFrame.add(BorderLayout.SOUTH, move);
myFrame.setSize(400, 300);
myFrame.setVisible(true);
}
}
afgkidy 2008-10-16
  • 打赏
  • 举报
回复
关注。
afgkidy 2008-10-16
  • 打赏
  • 举报
回复
从上面我的第三个程序来看,我并没有覆写repaint 方法,但是开始绘出的并没有清除。
afgkidy 2008-10-16
  • 打赏
  • 举报
回复
对于重量级组件,看来运行结果和你解释一致了。

那么对于轻量级的又是怎么回事呢?
afgkidy 2008-10-15
  • 打赏
  • 举报
回复
怎么都没有人给我解惑啊!

62,616

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧