Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Updating images in view in background(How to update images in view in background)
Updating images in view in background [message #533483] Fri, 14 May 2010 08:41 Go to next message
vrush Mising nameFriend
Messages: 51
Registered: July 2009
Location: Pune
Member
Hi,

I'm looking forward to provide a video support within eclipse. Till now managed to have a view with continueosly updating images with endless stream.
Everything works well till this point. But when I change focus to some other view or click anywhere within the eclipse, it hangs. It cannot even come back to video view. There are no listeners in the code. I'm simply changing background images in the loop.

Here is code snippet.


public class SampleView_1 extends ViewPart {

public Canvas imageCanvas;
private Action change_image;
private Image sourceImage;
@Override
public void createPartControl(Composite parent) {
imageCanvas=new Canvas(parent, SWT.BACKGROUND | SWT.V_SCROLL | SWT.H_SCROLL);
imageCanvas.setBackgroundImage(new Image(parent.getDisplay(), "C:/Documents and Settings/All Users/Documents/My Pictures/Sample Pictures/Blue hills.jpg"));
makeActions();
contributeToActionBars();
}


private void contributeToActionBars() {
IActionBars bars = getViewSite().getActionBars();
fillLocalToolBar(bars.getToolBarManager());
}


private void fillLocalToolBar(IToolBarManager manager) {
manager.add(change_image);
}

private void makeActions() {
change_image = new Action() {
public void run() {
ChangeImage();
}
};
change_image.setText("Change Image");
change_image.setToolTipText("Change Image");
change_image.setImageDescriptor(PlatformUI.getWorkbench().ge tSharedImages().
getImageDescriptor(ISharedImages.IMG_OBJS_INFO_TSK));

}

private void ChangeImage() {
/*String path = "C:/Documents and Settings/All Users/Documents/My Pictures/Sample Pictures/";
String arr[] = new String[]{"/Blue hills.jpg","/Sunset.jpg","/Water lilies.jpg","/Winter.jpg"};

for(int i=0;i<4;i++){
imageCanvas.setBackgroundImage(new Image(imageCanvas.getDisplay(), path + arr[i]));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}*/
/* IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
IViewPart viewPart = window.getActivePage().findView(
"lcdview.views.SampleView_1");
Shell shell = viewPart.getSite().getShell();
*/
PaletteData palette[] = new PaletteData[5];
palette[0] = new PaletteData(0, 0, 0);//new PaletteData(0xff, 0xff00, 0xff0000);
palette[1] = new PaletteData(0, 0, 1);//new PaletteData(0xff00, 0xff0000, 0xff);
palette[2] = new PaletteData(0, 1, 0);//new PaletteData(0xff0000, 0xff, 0xff00);
palette[3] = new PaletteData(1, 0, 0);//new PaletteData(0xff, 0xff00, 0xff0000);
palette[4] = new PaletteData(0, 0, 1);//new PaletteData(0xff00, 0xff0000, 0xff);

int i=0;
while(true){
ImageData hueData = new ImageData(1024, 720, 24, palette[i]);
float hue = 0;
for (int x = 0; x < hueData.width; x++) {
for (int y = 0; y < hueData.height; y++) {
int pixel = palette[i].getPixel(new RGB(hue, 1f, 1f));
hueData.setPixel(x, y, pixel);
}
hue += 360f / hueData.width;
}
Image hueImage = new Image(imageCanvas.getDisplay(), hueData);
sourceImage = hueImage;
imageCanvas.setBackgroundImage(sourceImage);
imageCanvas.update();
// shell.setBackgroundImage(sourceImage);
// shell.update();
if(i%4 == 0)
i = 0;
i++;
}
}

@Override
public void setFocus() {

}

}


Stuck since long. Please provide any pointers. Badly stuck

Thanks in advance,
Vrushali.
Re: Updating images in view in background [message #533526 is a reply to message #533483] Fri, 14 May 2010 13:00 Go to previous messageGo to next message
Vijay RajFriend
Messages: 608
Registered: July 2009
Senior Member
I think this video buffer questionn was already put forward by you...

and my answer will remain same...

because you are upateing the image in gui thread it is bound to get stuck as soon as some other operations(like refresh) is needed to be done....

pls try this..
http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.sni ppets/src/org/eclipse/swt/snippets/Snippet141.java?view=co

In this the the image data is updated which in tern is reflected in the canvas..
as u can see in the snippet this is don in non ui thread.
hence does not hang the ui thread.

you have to go by this approch which is similar to video where each frame is updated.


---------------------
why, mr. Anderson, why, why do you persist?
Because I Choose To.
Regards,
Vijay
Re: Updating images in view in background [message #533536 is a reply to message #533526] Fri, 14 May 2010 13:44 Go to previous messageGo to next message
Vijay RajFriend
Messages: 608
Registered: July 2009
Senior Member
Ok i have modified the snippet for u r requirement...

Try this
/*******************************************************************************
 * Copyright (c) 2000, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.swt.snippets;

/*
 * Image example snippet: display an animated GIF
 *
 * For a list of all SWT example snippets see
 * http://www.eclipse.org/swt/snippets/
 */
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class Snippet141
{
    static Display display;

    static Shell shell;

    static GC shellGC;

    static Color shellBackground;

    // static ImageLoader loader;

    static ImageData[] imageDataArray;

    static Thread animateThread;

    static Image image;

    static final boolean useGIFBackground = false;

    public static void main(String[] args)
    {
        display = new Display();
        shell = new Shell(display);
        shell.setSize(300, 300);
        shell.open();
        shellGC = new GC(shell);
        shellBackground = shell.getBackground();

        // FileDialog dialog = new FileDialog(shell);
        // dialog.setFilterExtensions(new String[] { "*.gif" });
        String fileName = "";
        // dialog.open();
        if (fileName != null)
        {
            // loader = new ImageLoader();
            try
            {
                imageDataArray = new ImageData[] { new ImageData("c:\\Blue hills.jpg"),
                        new ImageData("c:\\Sunset.jpg"), new ImageData("c:\\Water lilies.jpg"),
                        new ImageData("c:\\Winter.jpg") };
                if (imageDataArray.length > 1)
                {
                    animateThread = new Thread("Animation")
                    {
                        @Override
                        public void run()
                        {
                            /* Create an off-screen image to draw on, and fill it with the shell background. */
                            Image offScreenImage = new Image(display, 400, 300);
                            GC offScreenImageGC = new GC(offScreenImage);
                            offScreenImageGC.setBackground(shellBackground);
                            offScreenImageGC.fillRectangle(0, 0, 400, 300);

                            try
                            {
                                /* Create the first image and draw it on the off-screen image. */
                                int imageDataIndex = 0;
                                ImageData imageData = imageDataArray[imageDataIndex];
                                if (image != null && !image.isDisposed()) image.dispose();
                                image = new Image(display, imageData);
                                offScreenImageGC.drawImage(image, 0, 0, imageData.width,
                                        imageData.height, imageData.x, imageData.y,
                                        imageData.width, imageData.height);

                                /* Now loop through the images, creating and drawing each one
                                 * on the off-screen image before drawing it on the shell. */
                                int repeatCount = 50;
                                while (repeatCount > 0)
                                {
                                    switch (imageData.disposalMethod)
                                    {
                                        case SWT.DM_FILL_BACKGROUND:
                                            /* Fill with the background color before drawing. */
                                            Color bgColor = null;
                                            // if (useGIFBackground && loader.backgroundPixel !=
                                            // -1)
                                            // {
                                            // bgColor = new Color(display, imageData.palette
                                            // .getRGB(loader.backgroundPixel));
                                            // }
                                            offScreenImageGC
                                                    .setBackground(bgColor != null ? bgColor
                                                            : shellBackground);
                                            offScreenImageGC
                                                    .fillRectangle(imageData.x, imageData.y,
                                                            imageData.width, imageData.height);
                                            if (bgColor != null) bgColor.dispose();
                                            break;
                                        case SWT.DM_FILL_PREVIOUS:
                                            /* Restore the previous image before drawing. */
                                            offScreenImageGC.drawImage(image, 0, 0,
                                                    imageData.width, imageData.height,
                                                    imageData.x, imageData.y, imageData.width,
                                                    imageData.height);
                                            break;
                                    }

                                    imageDataIndex = (imageDataIndex + 1) % imageDataArray.length;
                                    imageData = imageDataArray[imageDataIndex];
                                    image.dispose();
                                    image = new Image(display, imageData);
                                    offScreenImageGC.drawImage(image, 0, 0, imageData.width,
                                            imageData.height, imageData.x, imageData.y,
                                            imageData.width, imageData.height);

                                    /* Draw the off-screen image to the shell. */
                                    shellGC.drawImage(offScreenImage, 0, 0);

                                    /* Sleep for the specified delay time (adding commonly-used slow-down fudge factors). */
                                    try
                                    {
                                        int ms = imageData.delayTime * 10;
                                        if (ms < 20) ms += 30;
                                        if (ms < 30) ms += 10;
                                        Thread.sleep(500);
                                    }
                                    catch (InterruptedException e)
                                    {
                                    }

                                    /* If we have just drawn the last image, decrement the repeat count and start again. */
                                    if (imageDataIndex == imageDataArray.length - 1) repeatCount--;
                                }
                            }
                            catch (SWTException ex)
                            {
                                System.out.println("There was an error animating the GIF");
                            }
                            finally
                            {
                                if (offScreenImage != null && !offScreenImage.isDisposed()) offScreenImage
                                        .dispose();
                                if (offScreenImageGC != null && !offScreenImageGC.isDisposed()) offScreenImageGC
                                        .dispose();
                                if (image != null && !image.isDisposed()) image.dispose();
                            }
                        }
                    };
                    animateThread.setDaemon(true);
                    animateThread.start();
                }
            }
            catch (SWTException ex)
            {
                System.out.println("There was an error loading the GIF");
            }
        }

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


---------------------
why, mr. Anderson, why, why do you persist?
Because I Choose To.
Regards,
Vijay
Re: Updating images in view in background [message #533666 is a reply to message #533536] Sat, 15 May 2010 07:28 Go to previous messageGo to next message
vrush Mising nameFriend
Messages: 51
Registered: July 2009
Location: Pune
Member
Hi,


Thanks for your reply and modified code. I could update images. No problem in doing that.
Tried
1 - Display thread
2 - Job
3 - Thread (as shown in your example)
4 - without any thread

Problems faced
1,2 and 4 - Images updates very well but as its ongoing never ending thread, everything else looses access just the view works. And after few clicks here and there, it hangs (Obviously).
3 - org.eclipse.swt.SWTException: Invalid thread access.

I have no direction at all what should I be doing to make it run like background job.
Any help would be great. Really hoping some. Let me please know if i m missing something obvious here.


Thanks a ton,
Vrushali.
Re: Updating images in view in background [message #533673 is a reply to message #533666] Sat, 15 May 2010 09:36 Go to previous messageGo to next message
vrush Mising nameFriend
Messages: 51
Registered: July 2009
Location: Pune
Member
No Message Body
Re: Updating images in view in background [message #533692 is a reply to message #533666] Sat, 15 May 2010 16:47 Go to previous messageGo to next message
Vijay RajFriend
Messages: 608
Registered: July 2009
Senior Member
I think you are using action to start your image change process...

you create a composite in which by default this thread should start and u should put that composite on the view.

the snippet provided never hangs then why does an rcp app hang...???


---------------------
why, mr. Anderson, why, why do you persist?
Because I Choose To.
Regards,
Vijay
Re: Updating images in view in background [message #533787 is a reply to message #533666] Mon, 17 May 2010 05:12 Go to previous messageGo to next message
Praveen  is currently offline Praveen Friend
Messages: 86
Registered: July 2009
Member
vrush wrote:
> 3 - Thread (as shown in your example)
> 3 - org.eclipse.swt.SWTException: Invalid thread access.
> Any help would be great. Really hoping some. Let me please know if i m
> missing something obvious here.
The snippet provided by Vijay seems to be feasible enough for your
situation. I didn't receive any Invalid Thread Access exception during
the execution of the snippet. The deamon thread used in the example
doesn't need to be a UI thread for updating image/background on any
composite control.
Can you please post your snippet causing the invalid thread access
exception? I will be glad to assist and fix your problem.

Regards,
Praveen.
Re: Updating images in view in background [message #533856 is a reply to message #533483] Mon, 17 May 2010 09:57 Go to previous message
vrush Mising nameFriend
Messages: 51
Registered: July 2009
Location: Pune
Member
Hi,

Thanks for your replies and snippets. Finally manage to get it working by running job (background thread) for image creation and running UI thread within job to update that image on canvas.

Now images are getting displayed continuously without blocking any thing else on the IDE.

Job job = new Job("") {

@Override
protected IStatus run(IProgressMonitor monitor) {
ChangeImage();
return null;
}
};
job.schedule();


private void ChangeImage() {
while(true){
//Image creation

imageCanvas.getDisplay().asyncExec(new Runnable() {

@Override
public void run() {
imageCanvas.
setBackgroundImage(sourceImage);
imageCanvas.update();
}
});

//logic to terminate while loop
}

}


Thanks a ton Smile
Vrushali.
Previous Topic:Problem with SWT designer on Mac
Next Topic:Simulate user window resize with GridLayout?
Goto Forum:
  


Current Time: Thu Apr 18 23:05:36 GMT 2024

Powered by FUDForum. Page generated in 0.02425 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top