Skip to main content



      Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Force redraw of a canvas
Force redraw of a canvas [message #439440] Mon, 12 July 2004 14:19 Go to next message
Eclipse UserFriend
Originally posted by: offline.atshawdot.ca

I'm doing some complex image generation in a separate thread that calls
a listener event on my main class when it's complete.

The main class has a Display --> Shell --> Canvas with the canvas
having a custom paintListener that draws an Image (also owned by the
main class) on it.

When the image generation thread is complete, what I had in mind was to
replace the exising image (disposing of it first) and then ideally the
canvas would redraw itself.

The thing is, if I call the canvas.redraw() directly, I get a thread
exception. If I call it indirectly (by setting a flag and checking for
it in the event loop) I have to interact with the form somehow before
it will redraw.

How do I change the image in the canvas? Is there a better way than
this?

If there is anyone who can tell me a better way to do this... Hell, a
better way to do ANYthing that this code does, please let me know.
Thanks.

=== code follows ===
/*
* Created on 10-Jul-2004
*/
package edu.aimedia.ui;

import org.eclipse.swt.*

/**
*
* @author offline
*/
public class FractalApp implements IterationListener {

Image img;

Display display;

Shell shell;

Canvas imgCanvas;

boolean redraw = false;

public static void main(String[] args) {
new FractalApp();
}

public FractalApp() {
display = new Display();
shell = new Shell(display);
shell.setLayout(null);
imgCanvas = new Canvas(shell, SWT.NONE);
imgCanvas.setSize(600, 600);
//MandelbrotFractal frac = new MandelbrotFractal(600, 600);
RGB startCol =
display.getSystemColor(SWT.COLOR_DARK_BLUE).getRGB();
RGB endCol =
display.getSystemColor(SWT.COLOR_MAGENTA).getRGB();
RGB[] colours = PaletteManager.createColourArray(startCol,
endCol, 8);
PaletteData palette =
PaletteManager.getInstance().createPalette(
"basic", PaletteManager.WEB_SAFE);
ImageData dat = new ImageData(imgCanvas.getBounds().width,
imgCanvas.getBounds().height, 8, palette);
for (int i = 0; i < dat.width; i++) {
for (int j = 0; j < dat.height; j++) {
int pval = i * dat.height + j;
pval %= 255;
dat.setPixel(i, j, pval);
}
}
img = new Image(display, dat);
imgCanvas.addPaintListener(new PaintListener() {
/*
* (non-Javadoc)
*
* @see
org.eclipse.swt.events.PaintListener#paintControl(org.eclips e.swt.event
s.PaintEvent)
*/
public void paintControl(PaintEvent e) {
Rectangle r = e.gc.getClipping();
e.gc.drawImage(img, r.x, r.y, r.width,
r.height, r.x, r.y, r.width, r.height);
System.out.println(r.toString());
}
});
Mandelbrot m = new Mandelbrot(210, dat.width, dat.height,
new Complex(-2.2, -1.5), new Complex(1, 1.5), palette);
m.addIterationListener(this);
m.generateFractal();
shell.pack();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
if (redraw) {
imgCanvas.redraw();
redraw = false;
}
display.sleep();
}
img.dispose();
display.dispose();
}

/*
* (non-Javadoc)
*
* @see
edu.aimedia.fractals.IterationListener#imageUpdated(edu.aime dia.fractal
s.ComplexFractal)
*/
public void imageUpdated(ComplexFractal source) {
// synchronized (this) {
if (source.isReady())
System.out.println("Updating img " +
img.toString());
img = new Image(display, source.getFractal());
System.out.println("img updated: " +
img.toString());
redraw = true;
display.post(new Event());
// }
}
}

=== end code ===

--
Chris R.
=======
http://offlineblog.com/
Re: Force redraw of a canvas [message #439523 is a reply to message #439440] Tue, 13 July 2004 04:23 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

The correct way to do this is to update your canvas in an asyncExec().
Eliminate the redraw flag and use the following method:

public void imageUpdated(ComplexFractal source) {
// synchronized (this) {
if (source.isReady())
System.out.println("Updating img " +
img.toString());
img = new Image(display, source.getFractal());
System.out.println("img updated: " +
img.toString());
display.asynExec(new Runnable() {
public void run(){
imgCanvas.redraw();
}
}
}

Regards,
Boby



"Chris R." <offline@atshawdot.ca> wrote in message
news:Xns95247D36CBB1Aofflineshawca@204.138.98.10...
> I'm doing some complex image generation in a separate thread that calls
> a listener event on my main class when it's complete.
>
> The main class has a Display --> Shell --> Canvas with the canvas
> having a custom paintListener that draws an Image (also owned by the
> main class) on it.
>
> When the image generation thread is complete, what I had in mind was to
> replace the exising image (disposing of it first) and then ideally the
> canvas would redraw itself.
>
> The thing is, if I call the canvas.redraw() directly, I get a thread
> exception. If I call it indirectly (by setting a flag and checking for
> it in the event loop) I have to interact with the form somehow before
> it will redraw.
>
> How do I change the image in the canvas? Is there a better way than
> this?
>
> If there is anyone who can tell me a better way to do this... Hell, a
> better way to do ANYthing that this code does, please let me know.
> Thanks.
>
> === code follows ===
> /*
> * Created on 10-Jul-2004
> */
> package edu.aimedia.ui;
>
> import org.eclipse.swt.*
>
> /**
> *
> * @author offline
> */
> public class FractalApp implements IterationListener {
>
> Image img;
>
> Display display;
>
> Shell shell;
>
> Canvas imgCanvas;
>
> boolean redraw = false;
>
> public static void main(String[] args) {
> new FractalApp();
> }
>
> public FractalApp() {
> display = new Display();
> shell = new Shell(display);
> shell.setLayout(null);
> imgCanvas = new Canvas(shell, SWT.NONE);
> imgCanvas.setSize(600, 600);
> //MandelbrotFractal frac = new MandelbrotFractal(600, 600);
> RGB startCol =
> display.getSystemColor(SWT.COLOR_DARK_BLUE).getRGB();
> RGB endCol =
> display.getSystemColor(SWT.COLOR_MAGENTA).getRGB();
> RGB[] colours = PaletteManager.createColourArray(startCol,
> endCol, 8);
> PaletteData palette =
> PaletteManager.getInstance().createPalette(
> "basic", PaletteManager.WEB_SAFE);
> ImageData dat = new ImageData(imgCanvas.getBounds().width,
> imgCanvas.getBounds().height, 8, palette);
> for (int i = 0; i < dat.width; i++) {
> for (int j = 0; j < dat.height; j++) {
> int pval = i * dat.height + j;
> pval %= 255;
> dat.setPixel(i, j, pval);
> }
> }
> img = new Image(display, dat);
> imgCanvas.addPaintListener(new PaintListener() {
> /*
> * (non-Javadoc)
> *
> * @see
> org.eclipse.swt.events.PaintListener#paintControl(org.eclips e.swt.event
> s.PaintEvent)
> */
> public void paintControl(PaintEvent e) {
> Rectangle r = e.gc.getClipping();
> e.gc.drawImage(img, r.x, r.y, r.width,
> r.height, r.x, r.y, r.width, r.height);
> System.out.println(r.toString());
> }
> });
> Mandelbrot m = new Mandelbrot(210, dat.width, dat.height,
> new Complex(-2.2, -1.5), new Complex(1, 1.5), palette);
> m.addIterationListener(this);
> m.generateFractal();
> shell.pack();
> shell.open();
> while (!shell.isDisposed()) {
> if (!display.readAndDispatch())
> if (redraw) {
> imgCanvas.redraw();
> redraw = false;
> }
> display.sleep();
> }
> img.dispose();
> display.dispose();
> }
>
> /*
> * (non-Javadoc)
> *
> * @see
> edu.aimedia.fractals.IterationListener#imageUpdated(edu.aime dia.fractal
> s.ComplexFractal)
> */
> public void imageUpdated(ComplexFractal source) {
> // synchronized (this) {
> if (source.isReady())
> System.out.println("Updating img " +
> img.toString());
> img = new Image(display, source.getFractal());
> System.out.println("img updated: " +
> img.toString());
> redraw = true;
> display.post(new Event());
> // }
> }
> }
>
> === end code ===
>
> --
> Chris R.
> =======
> http://offlineblog.com/
Re: Force redraw of a canvas [message #439576 is a reply to message #439523] Tue, 13 July 2004 16:14 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: offline.atshawdot.ca

"Robert Bacs" <boby@zerosoft.ro> wrote in
news:cd064u$doo$1@eclipse.org:

> Hi,
>
> The correct way to do this is to update your canvas in an
> asyncExec(). Eliminate the redraw flag and use the following
> method:
>
> public void imageUpdated(ComplexFractal source) {
> // synchronized (this) {
> if (source.isReady())
> System.out.println("Updating img " +
> img.toString());
> img = new Image(display, source.getFractal());
> System.out.println("img updated: " +
> img.toString());
> display.asynExec(new Runnable() {
> public void run(){
> imgCanvas.redraw();
> }
> }
> }
>

Thanks for the assist, I'll get right on that.

I guess it's probably found somewhere, but can someone tell me where in
the reams of *highly* disorganized SWT documentation on the net this
info might be found? Or, is there a book on SWT programming that I
should check out?

--
Chris R.
=======
http://offlineblog.com/
Re: Force redraw of a canvas [message #439597 is a reply to message #439576] Wed, 14 July 2004 10:23 Go to previous message
Eclipse UserFriend
It is in the SWT FAQ:

http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/plat form-swt-home/faq.html#uithread

There is a list of books on the SWT Developers page:

http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/plat form-swt-home/dev.html#docs


"Chris R." <offline@atshawdot.ca> wrote in message
news:Xns952590C5A98A7offlineshawca@204.138.98.10...
> "Robert Bacs" <boby@zerosoft.ro> wrote in
> news:cd064u$doo$1@eclipse.org:
>
> > Hi,
> >
> > The correct way to do this is to update your canvas in an
> > asyncExec(). Eliminate the redraw flag and use the following
> > method:
> >
> > public void imageUpdated(ComplexFractal source) {
> > // synchronized (this) {
> > if (source.isReady())
> > System.out.println("Updating img " +
> > img.toString());
> > img = new Image(display, source.getFractal());
> > System.out.println("img updated: " +
> > img.toString());
> > display.asynExec(new Runnable() {
> > public void run(){
> > imgCanvas.redraw();
> > }
> > }
> > }
> >
>
> Thanks for the assist, I'll get right on that.
>
> I guess it's probably found somewhere, but can someone tell me where in
> the reams of *highly* disorganized SWT documentation on the net this
> info might be found? Or, is there a book on SWT programming that I
> should check out?
>
> --
> Chris R.
> =======
> http://offlineblog.com/
Previous Topic:Standalone Vs Eclipse Platform Using SWT
Next Topic:What SWT component replaces the JInternalFrame
Goto Forum:
  


Current Time: Mon Jul 07 12:57:44 EDT 2025

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

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

Back to the top