Binayaka Chakraborty
Binayaka Chakraborty

Reputation: 1335

Drawing a specific part of an image SWT

Currently I am working on SWT, to create the UI for our application. I have run into a quandary. I am using a canvas to draw a header, which has some images. It also needs to display the time (refreshed every second). While I have accomplished all these, the catch is that I am using a single paintListener to draw the images and the current time.

The part of the header code is as follows:

private void initHeader(){
    header = new Canvas(shell,SWT.NONE);                
    GridLayout gd = new GridLayout();               
    gd.numColumns = 1;
    gd.marginHeight = 10;
    gd.marginBottom = 10;
    gd.verticalSpacing = 0;
    header.setLayout(gd);
    header.setLayoutData(new GridData(SWT.FILL,SWT.BEGINNING,true,false));      
    header.layout();                
    //Paint listener for SDM Logo
    header.addPaintListener(new PaintListener() {
        private final Image bgLogoImage = new Image(Display.getDefault(),"resources/images/1stimage.png");
        private final Image bgLockImage = new Image(Display.getDefault(),"resources/images/2ndimage.png");
        private final Image bgHelpImage = new Image(Display.getDefault(),"resources/images/3rdimage.png");
        private final int bgImageWidth = bgHelpImage.getBounds().width;
        private final int bgImageHeight = bgHelpImage.getBounds().height;
        private final int bgLockImageWidth = bgLockImage.getBounds().width;
        private final int bgLockImageHeight = bgLockImage.getBounds().height;           

        @Override
        public void paintControl(PaintEvent e) {
            e.gc.drawImage(bgLogoImage, 0, 0);
            Point lockSize = ((Control) e.widget).getSize();
            e.gc.drawImage(bgLockImage, (lockSize.x - bgLockImageWidth) - 50, (lockSize.y
                    - bgLockImageHeight)/2);
            Point size = ((Control) e.widget).getSize();
            e.gc.drawImage(bgHelpImage, (size.x - bgImageWidth) - 10, (size.y
                    - bgImageHeight)/2);                                
            e.gc.setBackground(new Color(display,225,43,41));
            e.gc.setForeground(new Color(display,255,255,255));
            Date dNow = new Date();
            SimpleDateFormat ft = new SimpleDateFormat("MMM d,y E hh:mm:ss a");
            e.gc.drawText(ft.format(dNow), header.getClientArea().width - 350, header.getClientArea().y + 10);
        }
    });     
}

I then use a thread to update the time every second. My difficulty is two fold:

  1. Since I call header.redraw() and header.update() every second, in effect, all the images are redrawn every second. Can I avoid that anyway
  2. Since I use a gridLayout, I can't manually place the currentTime in a label in a relative position. Is there any way to do that?

Upvotes: 2

Views: 173

Answers (1)

greg-449
greg-449

Reputation: 111142

Rather than having one Canvas you could have two controls in a Composite one with the images and one with the time. Then you can just redraw the time in a listener on that control.

Do any of these need to be a Canvas? Could you not use multiple Label controls which can hold an image or text?

If you want stay with a single control you can use redraw(x, y, width, height, false) to specify the region of the control you want to redraw. In the paint listener you then call GC.getClipping to get the part of the control which needs to be redrawn and skip any draw operations that don't need to be done.

Upvotes: 2

Related Questions