I’m trying to create a generic graphics export tool which works by implementing the Graphics interface and intercepts and interprets the calls to its various methods. However although I can do this successfully for a single component my Graphics class is being replaced when I use it on a component which contains other components. Strangely this only happens on Windows and Linux. On OSX it works fine.
Can anyone suggest how I can ensure that it’s my original Graphics class which is passed to all subcomponents?
I’ve got a short script which demonstrates the fundamental problem. When I explicitly call paint using an instance of MyGraphics I don’t see MyGraphics in the JPanel – just 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. }
On my windows system the output is:
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]]
whereas under OSX I get what I expected, which is:
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
So what I can I do to ensure that in all cases I get ‘MyGraphics’ passed to the appropriate subcomponents?
I don’t know for sure, but I suspect that as swing is double-buffered by Java on Windows (rather than by the window manager on OS X), you won’t draw to your graphics, but to the Graphics2D provided by the off-screen buffer, then blt to your graphics.