Bug 146604 - Direct instantiation of SWTGraphics in DeferredUpdateManager
Summary: Direct instantiation of SWTGraphics in DeferredUpdateManager
Status: NEW
Alias: None
Product: GEF
Classification: Tools
Component: GEF-Legacy Draw2d (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Anthony Hunter CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 159892 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-06-12 11:29 EDT by Peter Severin CLA
Modified: 2013-10-17 09:44 EDT (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Severin CLA 2006-06-12 11:29:46 EDT
The plug-in that I am developing uses Java2D to perform the drawing. To enable the Draw2D use Java2D transparently, I am implementing the Graphics interface and plugging it in through an implementation of GraphicsSource and a modified (through subclassing) version of LightweightSystem. Our own code is depending on our specific implementation of Graphics interface to be able to use more advanced features of Java2D.

The above construction works just fine in previous stable versions of GEF/Draw2D for Eclipse 3.1. However with the latest versions it breaks due to the following code in DeferredUpdateManager:

void paint(GC gc) {
    SWTGraphics graphics = new SWTGraphics(gc);
    if (!updating) {
        /**
         * If a paint occurs not as part of an update, we should notify that the region
         * is being painted. Otherwise, notification already occurs in repairDamage().
         */
        HashMap map = new HashMap();
        Rectangle rect = graphics.getClip(new Rectangle());
        map.put(root, rect);
        firePainting(rect, map);
    }
    root.paint(graphics);
    graphics.dispose();
}

The above code creates directly an instance of SWTGraphics without using the GraphicsSource indirection and thus breaks the abstraction. A fix for this should allow the use of an alternative Graphics implementation.
Comment 1 Steven R. Shaw CLA 2006-06-12 11:39:40 EDT
This is an easy fix to implement, but it is an api change to expose the graphics creation.  I guess the question is - how likely is it that an existing client has implemented the method signature createGraphics on an overriden DeferredUpdateManager class?
Comment 2 Peter Severin CLA 2006-06-12 12:13:00 EDT
Yes, a createGraphics method in DeferredUpdateManager would do the trick. 

The ideal solution should delegate this to the GraphicsSource interface. A Java2D based Graphics implementation works a bit differently as it draws on a BufferedImage which is at the end is transferred to the SWT drawing context. This means that I should add some workaround into the Java2dGraphics.dispose() method (because the DeferredUpdateManager calls this at the end of its paint method) to do it instead of doing it in the GraphicsSource.flushGraphics as before. Perhaps a clean solution can be considered for Eclipse 3.2.1
Comment 3 Randy Hudson CLA 2006-06-12 12:48:59 EDT
(In reply to comment #2)
> Yes, a createGraphics method in DeferredUpdateManager would do the trick. 

But then you have to subclass the updatemanager, which is bogus. That's the whole point of the graphicssource: to avoid subclassing.

We could change paint(GC) to do an instanceof NativeGraphicsSource check. If it is native, create the SWTGraphics. Otherwise, call super#paint(GC), which will use the client's GraphicsSource.

Unfortunately, GraphicsSource is an interface instead of a class, so we can't add getGraphics(GC).
Comment 4 Peter Severin CLA 2006-06-14 16:16:51 EDT
(In reply to comment #3)
> We could change paint(GC) to do an instanceof NativeGraphicsSource check. If it
> is native, create the SWTGraphics. Otherwise, call super#paint(GC), which will
> use the client's GraphicsSource.

It looks like a good compromise. Just please make sure that the super#paint(GC) works as expected. I've tried to override the LightweightSystem#paint(GC) method to make it function like it was in previous versions:

public void paint(GC gc) {
	manager.performUpdate(new Rectangle(gc.getClipping()));
}

It didn't work and I was getting a white area that wasn't repainting. I believe the super#paint(GC) will be equivalent to the above.
Comment 5 Tom Crockett CLA 2006-10-05 12:11:20 EDT
*** Bug 159892 has been marked as a duplicate of this bug. ***
Comment 6 Alexander Nyßen CLA 2013-10-17 09:44:56 EDT
Unset target milestone as the specified one is already passed.