Question

Still looking for a solution

I have the following problem: I use SWT GC to draw figures contained in GraphNodes to a Zest Graph. As far as Linux and MacOS are concerned, everything works fine. But when I run my jar on Windows the nodes look very odd. The color is not painted correctly and there is no transparency (achieved via setAlpha() of GC).

Here are two screenshots to illustrate my problem:

Linux:

enter image description here

Windows:

enter image description here

EDIT:

I just created this working "mini" example to test out. If anybody has an idea, why the rectangle is black on windows, I would highly appreciate an answer. Here is the back.png image: This is the <code>back.png</code>

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.ToolbarLayout;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.zest.core.widgets.Graph;
import org.eclipse.zest.core.widgets.GraphNode;
import org.eclipse.zest.core.widgets.IContainer;

public class MiniExample
{
    public static void main(String[] args)
    {
        Display display = Display.getDefault();
        Shell shell = new Shell(display);

        Graph graph = new Graph(shell, SWT.NONE);
        graph.setSize(100, 100);

        CustomFigure fig = new CustomFigure(new Label());
        fig.setSize(-1, -1);
        CustomNode node = new CustomNode(graph, SWT.NONE, fig);
        node.setLocation(5, 5);

        shell.pack();
        shell.open();

        while(!shell.isDisposed())
        {
            if(!display.readAndDispatch())
                display.sleep();
        }
    }

    /* Minimal helper class for the figure */
    static class CustomFigure extends Figure
    {
        private Image background = new Image(Display.getDefault(), "back.png");
        private GC gcBack = new GC(background);
        private Label all = new Label(background);
        private Color blau =  new Color(Display.getDefault(), 19, 59, 94);

        public CustomFigure(Label label)
        {
            ToolbarLayout layout = new ToolbarLayout();
            setLayoutManager(layout);
            setMiddle(3);
            add(all);
        }

        /* The problem has to occur somewhere here... */
        public void setMiddle(int value)
        {
            gcBack.setBackground(blau);
            gcBack.setForeground(blau);
            gcBack.setAlpha(255);

            /* color background blue and draw the nr of connections */
            gcBack.drawRoundRectangle(6, 6, 15, 15, 3, 3);
            gcBack.fillRoundRectangle(6, 6, 15, 15, 3, 3);
            gcBack.setForeground(ColorConstants.white);
            gcBack.drawText(value+"", 9, 6, true);

            gcBack.setAlpha(255);

            all.repaint();
        }
    }

    /* Minimal helper class for the node */
    static class CustomNode extends GraphNode
    {
        public CustomNode(IContainer graphModel, int style, CustomFigure figure)
        {
            super(graphModel, style, figure);
        }
        @Override
        protected IFigure createFigureForModel()
        {
            return (IFigure) this.getData();
        }
    }
}
Was it helpful?

Solution

It is definitely your background image what causes the problem. I have run some tests with the following example. I used a pure white background image enter image description here and your background image enter image description here. All is fine with the white background image, but if I use your background image only black colors are painted. It is most likely a bug in SWT.

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class MiniExample {
    public static void main( String[] args ) {
        Display display = Display.getDefault();
        Shell shell = new Shell( display );

        ACanvas canvas = new ACanvas( shell, SWT.None );
        canvas.setSize( 150, 150 );

        shell.pack();
        shell.open();

        while( !shell.isDisposed() ) {
            if( !display.readAndDispatch() )
                display.sleep();
        }
    }

static class ACanvas extends Canvas {

    public ACanvas( Composite parent, int style ) {
        super( parent, style );

        this.addPaintListener( new PaintListener() {

            @Override
            public void paintControl( PaintEvent arg0 ) {
                int value = 5;
                Image background = new Image( Display.getDefault(), "back2.png" );
                GC gcBack = new GC( background );
                //Color blue = Display.getDefault().getSystemColor( SWT.COLOR_BLUE );
                Color blue = new Color( Display.getDefault(), 0, 0, 255 );

                gcBack.setBackground( blue );
                gcBack.setForeground( blue );
                gcBack.setAlpha( 255 );

                gcBack.drawRoundRectangle( 6, 6, 15, 15, 3, 3 );
                gcBack.fillRoundRectangle( 6, 6, 15, 15, 3, 3 );

                gcBack.setForeground( Display.getDefault().getSystemColor( SWT.COLOR_WHITE ) );
                gcBack.drawText( value + "", 9, 6, true );

                gcBack.setAlpha( 255 );

                arg0.gc.drawImage( background, 0, 0 );
            }

        } );
    }

}

}

OTHER TIPS

The gray image used in your program and the white image posted by Tobias Willig are significantly different:

Gray:

Image Width: 28 Image Length: 28
Bitdepth (Bits/Sample): 1
Channels (Samples/Pixel): 1
Pixel depth (Pixel Depth): 1
Colour Type (Photometric Interpretation): PALETTED COLOUR (1 colours, 0 transparent)
Image filter: Single row per byte filter
Interlacing: No interlacing
Compression Scheme: Deflate method 8, 32k window
Resolution: 2835, 2835 (pixels per meter)
FillOrder: msb-to-lsb
Byte Order: Network (Big Endian)
Number of text strings: 0 of 0

White:

Image Width: 28 Image Length: 28
Bitdepth (Bits/Sample): 8
Channels (Samples/Pixel): 3
Pixel depth (Pixel Depth): 24
Colour Type (Photometric Interpretation): RGB
Image filter: Single row per byte filter
Interlacing: No interlacing
Compression Scheme: Deflate method 8, 32k window
Resolution: 2835, 2835 (pixels per meter)
FillOrder: msb-to-lsb
Byte Order: Network (Big Endian)
Number of text strings: 0 of 0

As you can see, the Colour Type of the gray image contains only 1 colour, whereas the one of the white image is RGB.

So it's definately the image that's causing your problems.

swt color are context dependent, you should not take a color from a gc and use it in another

Did you check if you run out of handles in Windows? AFAIK SWT is using a handle from the OS in every instance of Font, Color, Image, etc. so you can even bring your application in trouble by not reusing certain objects (or dispose the old ones; a difference to AWT/Swing). And afaik Linux and probably Mac OS don't have such a terrible behaviour when it comes to "running out of handles"...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top