当前位置:编程学习 > JAVA >>

component.paint(Graphics)如何使用?什么原理?

我是j2se初学者
在做程序时候遇到一个问题。
我在用
jpanel.paint(g)
的时候,将jpanel的组件画在一个bufferImage上。
但是画的时候,会把画面其他的实时更新的组件,一起画在图片上,都是左上角重叠的画出来的。
不太了解paint的原理,以及为什么我用的jpanel.paint(g),能把jpanel以外的组件也画在图片上,
实在搞不明白。
希望有经验的前辈们能给与帮助,谢谢! --------------------编程问答--------------------

paint(Graphics g)会调用以下三个方法
   -paintComponent:绘制组件(JPanel一般重写此方法)
   -paintChildren :绘制此组件的子组件
   -paintBorder   :绘制组件的边框
--------------------编程问答--------------------
引用 1 楼  的回复:
Java code


paint(Graphics g)会调用以下三个方法
   -paintComponent:绘制组件(JPanel一般重写此方法)
   -paintChildren :绘制此组件的子组件
   -paintBorder   :绘制组件的边框


噢,那也没有绘制我传入的jpanel以外组件的功能吧?
比如我用的 JPanel a  的 paint方法
JPanel a 包含一个JLabel  al
但是还有同层的JPanel b
JPanel b 中包含 了 JLabel bl
bl是每秒都会更换背景图片的
创建一个BufferImage  bi
取得bi的 Graphics  big
使用 a.paint(big),并且每秒都会创建一个新的bi 去画。
理论上应该在 bi上画出来  a 和 al
但是却多出来 bl了。。
为什么呢?

看到出来的图片的效果,我会觉得 虽然用的是a的paint,
但是每次画的时候,都是a上面不停地画出来 bl,而且也画出了上次画的al。



--------------------编程问答-------------------- public void paint(Graphics g)
由 Swing 调用,以绘制组件。应用程序不应直接调用 paint,而是应该使用 repaint 方法来安排重绘组件。


看下这篇文章,也许会清楚一些了。
http://www.doc88.com/p-295203521893.html --------------------编程问答--------------------
引用 3 楼  的回复:
public void paint(Graphics g)
由 Swing 调用,以绘制组件。应用程序不应直接调用 paint,而是应该使用 repaint 方法来安排重绘组件。


看下这篇文章,也许会清楚一些了。
http://www.doc88.com/p-295203521893.html

谢谢,的确让我了解了很多。
不过对于我现在的水平,还是不能解决我现在的问题。
按照你给的文章的理解,应该是我调用的paint(g)方法,把所有放在2级缓存的内容都画在了bufferedImage上,
是么? 
我还是不太理解,我明明只用一个JPanel对象调用的paint(g)方法,应该只会把这个JPanel对象的内容画在bufferedImage上的,为什么其他的组件的变化也会画在同一个bufferedImage上。。

还是希望能帮助分析下,谢谢!~ --------------------编程问答-------------------- 楼主看api文档吧:
此方法实际上将绘制工作委托给三个受保护的方法:paintComponent、paintBorder 和 paintChildren。按列出的顺序调用这些方法。

所以执行paint实际上等于执行了下面三个方法paintComponent、paintBorder 、paintChildren
其中的paintChildren是绘制此组件的子组件,所以把jpanel上的其它组件也绘制了。

如果楼主只要绘制jpanel,那不要用paint方法,用paintComponent方法试试。 --------------------编程问答--------------------
引用 5 楼  的回复:
楼主看api文档吧:
此方法实际上将绘制工作委托给三个受保护的方法:paintComponent、paintBorder 和 paintChildren。按列出的顺序调用这些方法。

所以执行paint实际上等于执行了下面三个方法paintComponent、paintBorder 、paintChildren
其中的paintChildren是绘制此组件的子组件,所以把jpanel上的其……

我是打印panel和panel上的组件,
但是打印的时候,其他panel上的自动更新的组件也画上去了。。
代码没法贴。只能靠各位想想了。。不好意思。。
--------------------编程问答-------------------- 有没有人能帮助分析解决下啊!!! --------------------编程问答-------------------- 上面已经说了,不要有paint方法。

楼主倒底是打印组件,还是绘制组件?
打印用 printComponents(Graphics g),绘制用paintComponents(Graphics g) --------------------编程问答-------------------- in JComponent.java

public void paint(Graphics g) {
boolean shouldClearPaintFlags = false;

        if ((getWidth() <= 0) || (getHeight() <= 0)) {
            return;
        }

        Graphics componentGraphics = getComponentGraphics(g);
        Graphics co = componentGraphics.create();
        try {
            RepaintManager repaintManager = RepaintManager.currentManager(this);
    Rectangle clipRect = co.getClipBounds();
            int clipX;
            int clipY;
            int clipW;
            int clipH;
    if (clipRect == null) {
                clipX = clipY = 0;
clipW = getWidth();
clipH = getHeight();
            }
    else {
        clipX = clipRect.x;
clipY = clipRect.y;
clipW = clipRect.width;
clipH = clipRect.height;
            }

            if(clipW > getWidth()) {
                clipW = getWidth();
            }
            if(clipH > getHeight()) {
                clipH = getHeight();
            }

            if(getParent() != null && !(getParent() instanceof JComponent)) {
                adjustPaintFlags();
                shouldClearPaintFlags = true;
            }

    int bw,bh;
    boolean printing = getFlag(IS_PRINTING);
            boolean repainting = getFlag(IS_REPAINTING);
            if(!printing && repaintManager.isDoubleBufferingEnabled() &&
               !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered() &&
                    (repaintManager.isPainting() || repainting)) {
                repaintManager.beginPaint();
                try {
                    repaintManager.paint(this, this, co, clipX, clipY, clipW,
                                         clipH);
                } finally {
                    repaintManager.endPaint();
                }
            } 
            else {
// Will ocassionaly happen in 1.2, especially when printing.
if (clipRect == null) {
    co.setClip(clipX, clipY, clipW, clipH);
}

                if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
    if (!printing) {
paintComponent(co);
paintBorder(co);
    }
    else {
printComponent(co);
printBorder(co);
    }
                }
if (!printing) {
    paintChildren(co);
}
else {
    printChildren(co);
}
            }
        } finally {
            co.dispose();
            if(shouldClearPaintFlags) {
                setFlag(ANCESTOR_USING_BUFFER,false);
                setFlag(IS_PAINTING_TILE,false);
                setFlag(IS_PRINTING,false);
                setFlag(IS_PRINTING_ALL,false);
            }
        }
    }
--------------------编程问答--------------------
引用 7 楼  的回复:
有没有人能帮助分析解决下啊!!!

看了paint,貌似没有发现会连带更新兄弟组件的地方

可能哪里出了问题,不过代码不贴的话很难分析啊 --------------------编程问答--------------------
引用 8 楼  的回复:
上面已经说了,不要有paint方法。

楼主倒底是打印组件,还是绘制组件?
打印用 printComponents(Graphics g),绘制用paintComponents(Graphics g)

额,不好意思,那个paint(Graphics g)API说叫打印,我其实是把画面的一部分保存成图片。
试过paintComponents(Graphics g)了,依旧保存的图片上还是多出来了其他panel的label和button了。
问题已用其他方式解决,但是的确还是不知道为什么会在图片上出现其他组件。 --------------------编程问答--------------------
引用 10 楼  的回复:
引用 7 楼  的回复:

有没有人能帮助分析解决下啊!!!

看了paint,貌似没有发现会连带更新兄弟组件的地方

可能哪里出了问题,不过代码不贴的话很难分析啊

的确是,但是代码太多太杂了。我也不方便贴上来。我自己继续看看api的代码和楼上贴的代码研究下吧。
问题用别的方式解决了,但是依旧不明白为什么之前的问题会出现,我会好好看看大家给的资料和建议的。
谢谢。 --------------------编程问答--------------------
引用 9 楼  的回复:
in JComponent.java
Java code

public void paint(Graphics g) {
    boolean shouldClearPaintFlags = false;

        if ((getWidth() <= 0) || (getHeight() <= 0)) {
            return;
        }

     ……

 if(getParent() != null && !(getParent() instanceof JComponent)) {
                adjustPaintFlags();
                shouldClearPaintFlags = true;
            }
我会好好看看的,之前debug进到这个方法了。但是没太看懂。 --------------------编程问答--------------------

private void adjustPaintFlags() {
JComponent jparent = null;
Container parent;
for(parent = getParent() ; parent != null ; parent =
    parent.getParent()) {
    if(parent instanceof JComponent) {
jparent = (JComponent) parent;
if(jparent.getFlag(ANCESTOR_USING_BUFFER))
  setFlag(ANCESTOR_USING_BUFFER, true);
if(jparent.getFlag(IS_PAINTING_TILE))
  setFlag(IS_PAINTING_TILE, true);
if(jparent.getFlag(IS_PRINTING))
  setFlag(IS_PRINTING, true);
if(jparent.getFlag(IS_PRINTING_ALL))
  setFlag(IS_PRINTING_ALL, true);
break;
    }
}
    }
--------------------编程问答--------------------
引用 12 楼  的回复:
引用 10 楼  的回复:

引用 7 楼  的回复:

有没有人能帮助分析解决下啊!!!

看了paint,貌似没有发现会连带更新兄弟组件的地方

可能哪里出了问题,不过代码不贴的话很难分析啊

的确是,但是代码太多太杂了。我也不方便贴上来。我自己继续看看api的代码和楼上贴的代码研究下吧。
问题用别的方式解决了,但是依旧不明白为什么之前的问题会出现,我会好好看看大家给的……

你可以试着模拟出一段同样带这个问题,但是独立又简单的程序。

看adjustPaintFlags方法中
它会上溯那些是JComponent的父类组件,并
if(jparent.getFlag(IS_PRINTING_ALL))
    setFlag(IS_PRINTING_ALL, true);

感觉和这个可能有关
补充:Java ,  Java SE
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,