站内搜索: 请输入搜索关键词
当前页面: 图书首页 > SWT: The Standard Widget Toolkit

4.10 Filling the Background - SWT: The Standard Widget Toolkit

Previous Section  < Day Day Up >  Next Section

4.10 Filling the Background

By default, the background color of a control is filled before a paint event is sent. This allows you to concentrate on drawing the contents of the control. Generally, this approach works well unless you need to provide a custom background. For example, if you are implementing a control that draws a list of strings, alternating the background color between each line, then there are effectively two background colors. Sometimes, there is no notion of background color for a control. For example, a control that draws an image will fill the entire client area with the pixels that make up the image. For this control, filling the area to be drawn with the background color first is completely extraneous, because it will immediately be replaced with the image content. In both these cases, drawing the background can cause the control to flicker.

If you specify the SWT.NO_BACKGROUND style when a control is created, it will not fill the background before sending a paint event. Although this style can get rid of flicker, it means that the paint listener must draw every pixel. Failure to do so will leave the pixels that were on the screen before the paint event was issued untouched. The effect is unsettling, to say the least.

4.10.1 Using SWT.NO_BACKGROUND to Reduce Flicker

The following example first creates an image, then draws it in a paint event. SWT.NO_BACKGROUND is used to stop the background from drawing. When the control is resized to be larger than the image, the area that is not filled by the image (by coincidence, also a "backwards L" shape) is filled with the background color of the control, as shown in Figure 4.9.






public static void main(String[] args) {

    Display display = new Display();

    int style = SWT.SHELL_TRIM | SWT.NO_BACKGROUND;

    final Shell shell = new Shell(display, style);

    final Image image = new Image(display, 128, 128);

    GC gc = new GC(image);

    Rectangle rect = image.getBounds();

    gc.setBackground(

        display.getSystemColor(SWT.COLOR_RED));

    gc.fillArc(0, 0, rect.width, rect.height, 0, 360);

    gc.dispose();

    shell.addListener(SWT.Paint, new Listener() {

        public void handleEvent(Event event) {

            GC gc = event.gc;

            Rectangle rect = image.getBounds();

            Rectangle client = shell.getClientArea();

            gc.drawImage(image, 0, 0);

            int width =

                Math.max(0, client.width - rect.width);

            int height =

                Math.max(0, client.height - rect.height);

            gc.fillRectangle(

                rect.width,

                0,

                width,

                client.height);

            gc.fillRectangle(

                0,

                rect.height,

                client.width,

                height);

        }

    });

    shell.setSize(250, 250);

    shell.open();

    while (!shell.isDisposed()) {

        if (!display.readAndDispatch()) display.sleep();

    }

    image.dispose();

    display.dispose();

}


Figure 4.9.

graphics/04fig09.gif


Why Isn't SWT.NO_BACKGROUND the Default?

Because there is no way of telling where the control will draw, it is not possible automatically to fill the areas that were not drawn. The choice is between drawing too much and possibly flickering or drawing too little, causing garbage to be drawn on the screen.


    Previous Section  < Day Day Up >  Next Section