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);
}
}为什么实际效果背景没有被清除呢?我哪里理解错误,请知道的解释下,谢谢。
轻量级组件 是用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);
}
}为什么实际效果背景没有被清除呢?我哪里理解错误,请知道的解释下,谢谢。
而不是说是分开调用update();再paint();
就是说update()方法响应repaint()方法
update()方法包括两个部分 1使用背景色填充 2调用paint()而不是说repaint()方法调用update()再调用paint()
repaint()方法调用
update()响应
update
{
清屏();
paint();
}
所以你只看到一条直线重写后
update()
{
paint();
}
repaint()调用
update()响应
原来屏幕上有一条直线
现在update()由于没有清屏,所以原来那条直线还在
然后再画一条,就两条了
调用了update 就不会调paint 了吧。
方法只是会调用update()方法
如果还有疑问 你可以看下src包中的Canvas
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);
}
}