如何在Java中成功扩展Graphics

时间:2009-02-03 10:09:01

标签: java inheritance graphics

我正在尝试创建一个通用的图形导出工具,它通过实现Graphics接口来工作,并拦截和解释对其各种方法的调用。但是,虽然我可以成功地为单个组件执行此操作,但当我在包含其他组件的组件上使用它时,我的Graphics类正在被替换。奇怪的是,这只发生在Windows和Linux上。在OSX上它工作正常。

有人可以建议我如何确保它是传递给所有子组件的原始Graphics类吗?

我有一个简短的脚本,演示了根本问题。当我使用MyGraphics的实例显式调用paint时,我在JPanel中看不到MyGraphics - 只是sun.java2d.SunGraphics2D。

import java.awt.*;
import java.awt.image.*;
import java.text.AttributedCharacterIterator;
import javax.swing.*;

public class GraphicsTest {

public static void main(String[] args) {
    new GraphicsTest();
}

public GraphicsTest () {
    JFrame frame = new JFrame();
    frame.getContentPane().add(new MyPanel());
    frame.setSize(500,500);
    frame.setVisible(true);
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {}
    System.out.println("Using my graphics - expect to see 'MyGraphics' next");
    frame.paint(new MyGraphics());

}

class MyPanel extends JPanel {
    public void paint (Graphics g) {
        super.paint(g);
        System.out.println("Graphics is "+g);

        g.fillRect(10, 10, 20, 20);
    }
}

class MyGraphics extends Graphics {

    public String toString () {
        return "MyGraphics";
    }

    public Graphics create() {
        return this;
    }

    // I've left out the huge list of abstract methods from the original script
    // since they're unchanged from the defaults and don't really matter here.
}

在我的Windows系统上,输出为:

Graphics is sun.java2d.SunGraphics2D[font=javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12],color=sun.swing.PrintColorUIResource[r=51,g=51,b=51]]
Using my graphics - expect to see 'MyGraphics' next
Graphics is sun.java2d.SunGraphics2D[font=javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=plain,size=12],color=sun.swing.PrintColorUIResource[r=51,g=51,b=51]]

而在OSX下,我得到了我的预期,即:

Graphics is sun.java2d.SunGraphics2D[font=apple.laf.CUIAquaFonts$DerivedUIResourceFont[family=LucidaGrande,name=LucidaGrande,style=plain,size=13],color=javax.swing.plaf.ColorUIResource[r=0,g=0,b=0]]
Using my graphics - expect to see 'MyGraphics' next 
Graphics is MyGraphics

那么我能做些什么来确保在所有情况下我都将'MyGraphics'传递给相应的子组件?

2 个答案:

答案 0 :(得分:1)

我不确定,但我怀疑由于Windows上的Java(而不是OS X上的窗口管理器)对swing进行双缓冲,因此您不会绘制到图形,而是绘制到Graphics2D由屏幕外缓冲区提供,然后blt到您的图形。

答案 1 :(得分:1)

就是这样!如果我在调用paint之前禁用组件上的双缓冲,然后重新启用它,那么一切都按照我需要的方式工作。

RepaintManager.currentManager(frame).setDoubleBufferingEnabled(false);
frame.paint(new MyGraphics());
RepaintManager.currentManager(frame).setDoubleBufferingEnabled(true);

感谢。