Home » Eclipse Projects » Standard Widget Toolkit (SWT) » Force redraw of a canvas
Force redraw of a canvas [message #439440] |
Mon, 12 July 2004 18:19 |
Eclipse User |
|
|
|
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 08:23 |
Robert Bacs Messages: 165 Registered: July 2009 |
Senior Member |
|
|
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 20:14 |
Eclipse User |
|
|
|
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/
|
|
| |
Goto Forum:
Current Time: Fri Apr 26 06:01:21 GMT 2024
Powered by FUDForum. Page generated in 0.03277 seconds
|