双缓冲时JLabel在图形中的位置



我正在使用线程绘制一些动画,所以我需要为每一帧重新绘制标签。为了做到这一点而不闪烁,我正在用我的backbuffer图形对象更新标签(使用lbl.update(bufferedGraphics);方法),但当我这样做时,标签会在Graphics对象的左上角重新绘制,而不是在setLocation指定的位置。

如何在图形中而不是在拥有标签的面板中指定标签的位置?

这里有一个SSCCE:

import javax.swing.*;
import java.awt.*;
public class LabelSSCCE extends JApplet implements Runnable {
JPanel pnl;
JLabel lbl;
Image buffer;
Graphics bufferedGraphics;
Thread t;
public void init (){
    pnl = new JPanel (null);
    lbl = new JLabel ();
    lbl.setText ("Text");
    lbl.setOpaque(true);
    add(pnl);
    pnl.add (lbl);
    lbl.setLocation(100, 100);
    lbl.setBounds (100, 100, 200, 20);
    buffer = createImage (500, 500);
    bufferedGraphics = buffer.getGraphics ();
    t = new Thread (this, "Label");
    t.start ();
}// init method
public void paint (Graphics g){
    if (g != null)
        g.drawImage (buffer, 0, 0, this);
}//paint
public void update (Graphics g){
    paint (g);
}//update
public void render (){
    bufferedGraphics.setColor (Color.WHITE);
    bufferedGraphics.fillRect (0, 0, 500, 500);
    lbl.update (bufferedGraphics);
    update(getGraphics());
}//render
public void run (){
    while (true){
        try{
            render ();
            t.sleep (20);
        } catch (InterruptedException e){
            e.printStackTrace ();
        }//catch
    }//while
}//run
}//LabelSSCCE

首先,将JLabel转换为BufferedImage:

    public BufferedImage componentToImage(Component component)
{
    BufferedImage img = new BufferedImage(component.getWidth(), component.getHeight(), BufferedImage.TYPE_INT_ARGB_PRE);
    Graphics g = img.getGraphics();
    g.setColor(component.getForeground());
    g.setFont(component.getFont());
    component.paintAll(g);
    Rectangle region = new Rectangle(0, 0, img.getWidth(), img.getHeight());
    return img.getSubimage(region.x, region.y, region.width, region.height);
}

然后,将渲染方法更改为以下内容:

public void render() {
    bufferedGraphics.setColor(Color.WHITE);
    bufferedGraphics.fillRect(0, 0, 500, 500);      
    BufferedImage bi = componentToImage(lbl);
    bufferedGraphics.drawImage(bi, lbl.getX(), lbl.getY(), null);
    update(getGraphics());
}

最新更新