Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » forcing repaint on a control
forcing repaint on a control [message #447308] Mon, 13 December 2004 15:42 Go to next message
Mani Ghamari is currently offline Mani GhamariFriend
Messages: 33
Registered: July 2009
Member
Hi,

Is there a way of forcing an immidiate redraw on a control?
I understand that Control.update() will only process already-queued paint
requests, and Control.redraw() will only mark the entire bounds as needing
to be redrawn.
subsequent calls to redraw() and update() dont seem to have an effect either
(ignored?).

thanks,

Mani
Re: forcing repaint on a control [message #447363 is a reply to message #447308] Mon, 13 December 2004 18:26 Go to previous messageGo to next message
Steve Northover is currently offline Steve NorthoverFriend
Messages: 1636
Registered: July 2009
Senior Member
Yes, try:

control.redraw();
control.update();

Control.redraw() queues a paint request for the entire control in the
operating system. Control.update() flushes that queue().

"Mani Ghamari" <mani.ghamari@linkast.com> wrote in message
news:cpkdbd$msp$1@www.eclipse.org...
> Hi,
>
> Is there a way of forcing an immidiate redraw on a control?
> I understand that Control.update() will only process already-queued paint
> requests, and Control.redraw() will only mark the entire bounds as needing
> to be redrawn.
> subsequent calls to redraw() and update() dont seem to have an effect
either
> (ignored?).
>
> thanks,
>
> Mani
>
>
Re: forcing repaint on a control [message #447365 is a reply to message #447363] Mon, 13 December 2004 19:04 Go to previous messageGo to next message
Mani Ghamari is currently offline Mani GhamariFriend
Messages: 33
Registered: July 2009
Member
Thanks steve, but I have already tried that.

In fact, I posted this because the behaviour I am experiencing is different
than
what I would expect.

As I mentioned before, the calls to redraw and update seem to be totally
ignored.

I am using a Tracker widget to implement a rubber band for items selection.

The tracker is created on top of a composite, everytime a mouse drag is
detected.
When the tracker is resized (as well as after it is disposed) all the items
(composite's children) which intersect the tracker rechtangle are selected.

The children are custom widgets (subclasses of composite). And the selection
occures in means of changing the background color of the objects (and
setting a
isSelected flag).

My problem is that if I downsize the tracker (during the tracker resize
operation) so
that some of the items that were covered by the tracker rectangle are now
uncovered
and therefore deselected, the tracker leaves some bad traces on the child
composites.
(looks like a bug in paint instructions)

At first, I though that the resize is happening too fast for the children,
so that they
don't become a chance to redraw themselves. but this theory contradicts the
documented behaviour of SWT, because all the resize, changeSelection and
redraw/repaint
instuctions are executed synchronously (and in order) in the UI-Thread.

I tried redraw and update on all the children individually as well as on the
parent composite,
whenever the tracker is resized and when it is disposed. But none of these
calls seem to really
update the children (the bad trace marks are still visible).

I am starting to think, that these traces actually exist on (the invisible
layer of?) the tracker
control itself, but I am not familiar enough with the internal workings of
tracker. I was thinking
that maybe updating the tracker widget would do the trick, but the tracker
extends Widget,
and therefore has no reference to the actual UI-Component that is drawn on
the screen.

For more detailed information, sample code and screenshots, please see my
previous
message from 10/12/2004 ("Trackers / Rubber bands").

Thanks again,

regards,

Mani Ghamari

"Steve Northover" <steve_northover@ca.ibm.com> wrote in message
news:cpkmtp$nia$1@www.eclipse.org...
> Yes, try:
>
> control.redraw();
> control.update();
>
> Control.redraw() queues a paint request for the entire control in the
> operating system. Control.update() flushes that queue().
>
> "Mani Ghamari" <mani.ghamari@linkast.com> wrote in message
> news:cpkdbd$msp$1@www.eclipse.org...
>> Hi,
>>
>> Is there a way of forcing an immidiate redraw on a control?
>> I understand that Control.update() will only process already-queued paint
>> requests, and Control.redraw() will only mark the entire bounds as
>> needing
>> to be redrawn.
>> subsequent calls to redraw() and update() dont seem to have an effect
> either
>> (ignored?).
>>
>> thanks,
>>
>> Mani
>>
>>
>
>
Re: forcing repaint on a control - TrackerSnippet.java [message #447367 is a reply to message #447363] Mon, 13 December 2004 20:03 Go to previous messageGo to next message
Mani Ghamari is currently offline Mani GhamariFriend
Messages: 33
Registered: July 2009
Member
The following Snippet I wrote illusterates my problem....

Try selecting some of the icons with the tracker and then downsizing the
tracker,
so that some of the selected ones are again deselected...
(hold and drag the mouse on an empty area of the shell to activate the
tracker)

Any Ideas?

regards,

Mani

/* ********** TrackerSnippet.java ********** */

import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;

public class TrackerSnippet implements MouseListener,
MouseMoveListener
{
private boolean isDragging = false;
private Shell shell;

public static void main(String[] args)
{
TrackerSnippet trackerSnippet = new TrackerSnippet();
}

public TrackerSnippet()
{
Display display = new Display();
shell = new Shell(display, SWT.SHELL_TRIM);
shell.setText("TrackerSnippet");
shell.setBounds(50, 50, 500, 300);

RowLayout rl = new RowLayout(SWT.HORIZONTAL);
rl.pack = true;
rl.wrap = true;
shell.setLayout(rl);

for (int i=0; i<10; i++)
createChild(shell);

shell.addMouseListener(this);
shell.addMouseMoveListener(this);
shell.layout(true);

shell.open();

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

display.dispose();
}

private void createChild(Composite parent)
{
// Create child composite
Composite child = new Composite(parent, SWT.NONE);

child.setLayout(new FillLayout());

final Canvas iconCanvas = new Canvas(child, SWT.NO_FOCUS);

final Image icon =
parent.getDisplay().getSystemImage(SWT.ICON_WARNING);

iconCanvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
Rectangle canvasSize = iconCanvas.getBounds();
e.gc.setBackground(iconCanvas.getParent().getBackground());
e.gc.fillRectangle(e.x, e.y, e.width, e.height);
e.gc.drawImage(icon,
(int)(canvasSize.width - icon.getBounds().width)/2,
(int)(canvasSize.height -
icon.getBounds().height)/2);
}
});

// make the composite 20 pixels larger than the icon image
RowData data = new RowData(icon.getBounds().width + 20,
icon.getBounds().height + 20);
child.setLayoutData(data);

setSelected(child, false);
}

private void setSelected(Control child, boolean selected)
{
Color c = (selected)?
child.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION):
child.getParent().getBackground();

child.setBackground(c);
if (child.getClass().equals(Composite.class))
{
// Also change the background of the children (generally, the
canvas)
Control[] controls = ((Composite)child).getChildren();
for (int i=0; i<controls.length; i++)
controls[i].setBackground(c);
}
}

private void trackIt(int x, int y)
{
Tracker tracker = new Tracker(shell, SWT.RESIZE);
tracker.setRectangles (new Rectangle [] {new Rectangle (x, y, 1,
1)});
tracker.setStippled(true);

tracker.addControlListener(new ControlAdapter()
{
public void controlResized(ControlEvent e)
{
changeSelections(((Tracker)e.getSource()).getRectangles()[0] );
}
});

tracker.open ();
changeSelections(tracker.getRectangles()[0]);
tracker.dispose();

shell.redraw(); // HAS NO EFFECT!
shell.update(); // HAS NO EFFECT!

isDragging = false;
}

private void changeSelections(Rectangle selection)
{
Control[] children = shell.getChildren();
for (int i=0; i<children.length; i++)
{
if (selection.intersects(children[i].getBounds()) ||
children[i].getBounds().contains(selection.x, selection.y))
{
setSelected(children[i], true);
}
else
{
setSelected(children[i], false);
}
children[i].redraw(); //HAS NO EFFECT
children[i].update(); //HAS NO EFFECT
}
}

public void mouseDown(MouseEvent e)
{
isDragging = true;
}

public void mouseUp(MouseEvent e)
{
isDragging = false;
}

public void mouseMove(MouseEvent e)
{
if (isDragging)
trackIt(e.x, e.y);
}

public void mouseDoubleClick(MouseEvent e){}
}
/* ********** EOF TrackerSnippet.java ******** */
Re: forcing repaint on a control -WORKING TrackerSnippet.java [message #447375 is a reply to message #447367] Tue, 14 December 2004 00:20 Go to previous messageGo to next message
Mani Ghamari is currently offline Mani GhamariFriend
Messages: 33
Registered: July 2009
Member
I finally fixed the problem...

I replaced the following lines:

children[i].redraw(); //HAS NO EFFECT
children[i].update(); //HAS NO EFFECT

with:
children[i].redraw(0, 0, children[i].getBounds().width,
children[i].getBounds().height, true);

I also encountered some flickering problems which I solved by adding
SWT.NO_BACKGROUND | SWT.NO_REDRAW_RESIZE | SWT.NO_MERGE_PAINTS
to the style of the child Canvas (and also double buffering the paint
operation.)

According to the docs, I assumed that calling Control.readraw() (repaints
the entire bounds) would
be equal to calling Control.redraw(0, 0, width, height, true), which is,
quite frankly, not the case.

The documentation for Control.redraw() does not mention anything about the
children of the control.
Now I am wondering... is this the right behaviour, or a bug in
Control.redraw()?
I believe, that the documentation should be more specific in this case...

regards,

Mani

Here is the working snippet, if anyone is interrested (maybe it could become
a standard Snippet for using
trackers for rubber band selections?):

/* ************ TrackerSnippet.java ********** */

import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;

public class TrackerSnippet implements MouseListener,
MouseMoveListener
{
private boolean isDragging = false;
private Shell shell;

public static void main(String[] args)
{
TrackerSnippet trackerSnippet = new TrackerSnippet();
}

public TrackerSnippet()
{
Display display = new Display();

shell = new Shell(display, SWT.SHELL_TRIM);
shell.setText("TrackerSnippet");
shell.setBounds(50, 50, 500, 300);

RowLayout rl = new RowLayout(SWT.HORIZONTAL);
rl.pack = true;
rl.wrap = true;
shell.setLayout(rl);

for (int i=0; i<10; i++)
createChild(shell);

shell.addMouseListener(this);
shell.addMouseMoveListener(this);
shell.layout(true);
shell.open();

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

display.dispose();
}

private void createChild(Composite parent)
{
final Composite child = new Composite(parent, SWT.NONE);
child.setLayout(new FillLayout());
final Canvas iconCanvas = new Canvas(child, SWT.NO_FOCUS |
SWT.NO_REDRAW_RESIZE
|
SWT.NO_BACKGROUND
|
SWT.NO_MERGE_PAINTS);

final Image icon =
parent.getDisplay().getSystemImage(SWT.ICON_WARNING);

iconCanvas.addPaintListener(new PaintListener()
{
public void paintControl(PaintEvent e)
{
Rectangle canvasSize = iconCanvas.getBounds();
Image offscreen = new Image(iconCanvas.getDisplay(),
canvasSize.width, canvasSize.height);
GC gc = new GC(offscreen);

gc.setBackground(iconCanvas.getParent().getBackground());
gc.fillRectangle(0, 0, canvasSize.width, canvasSize.height);
gc.drawImage(icon,
(int)(canvasSize.width - icon.getBounds().width)/2,
(int)(canvasSize.height -
icon.getBounds().height)/2);

e.gc.drawImage(offscreen, 0, 0);

gc.dispose();
offscreen.dispose();
}
});
// make the composite 20 pixels larger than the icon image
RowData data = new RowData(icon.getBounds().width + 20,
icon.getBounds().height + 20);
child.setLayoutData(data);

setSelected(child, false);
}

private void setSelected(Control child, boolean selected)
{
Color c = (selected)?
child.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION):
child.getParent().getBackground();
child.setBackground(c);
if (child.getClass().equals(Composite.class))
{
// Also change the background of the children (generally, the
canvas)
Control[] controls = ((Composite)child).getChildren();
for (int i=0; i<controls.length; i++)
controls[i].setBackground(c);
}
}

private void trackIt(int x, int y)
{
Tracker tracker = new Tracker(shell, SWT.RESIZE);
tracker.setRectangles (new Rectangle [] {new Rectangle (x, y, 1,
1)});
tracker.setStippled(false);
tracker.addControlListener(new ControlAdapter()
{
public void controlResized(ControlEvent e)
{
changeSelections(((Tracker)e.getSource()).getRectangles()[0] );
}
});

tracker.open ();
changeSelections(tracker.getRectangles()[0]);
tracker.dispose();
isDragging = false;
}

private void changeSelections(Rectangle selection)
{
Control[] children = shell.getChildren();
for (int i=0; i<children.length; i++)
{
if (selection.intersects(children[i].getBounds()) ||
children[i].getBounds().contains(selection.x, selection.y))
{
setSelected(children[i], true);
}
else
{
setSelected(children[i], false);
}
//Redraw the child control
children[i].redraw(0, 0, children[i].getBounds().width,
children[i].getBounds().height, true);
}
}

public void mouseDown(MouseEvent e)
{
isDragging = true;
}

public void mouseUp(MouseEvent e)
{
isDragging = false;
}

public void mouseMove(MouseEvent e)
{
if (isDragging)
trackIt(e.x, e.y);
}

public void mouseDoubleClick(MouseEvent e){}
}

/* *********** EOF TrackerSnippet.java ********* */
Re: forcing repaint on a control [message #447649 is a reply to message #447363] Wed, 15 December 2004 22:18 Go to previous message
Steve Northover is currently offline Steve NorthoverFriend
Messages: 1636
Registered: July 2009
Senior Member
Control.redraw() redraws only the control, not all of the children. Please
enter a problem report for the pixel corruption causes by your use of
Tracker.

"Steve Northover" <steve_northover@ca.ibm.com> wrote in message
news:cpkmtp$nia$1@www.eclipse.org...
> Yes, try:
>
> control.redraw();
> control.update();
>
> Control.redraw() queues a paint request for the entire control in the
> operating system. Control.update() flushes that queue().
>
> "Mani Ghamari" <mani.ghamari@linkast.com> wrote in message
> news:cpkdbd$msp$1@www.eclipse.org...
> > Hi,
> >
> > Is there a way of forcing an immidiate redraw on a control?
> > I understand that Control.update() will only process already-queued
paint
> > requests, and Control.redraw() will only mark the entire bounds as
needing
> > to be redrawn.
> > subsequent calls to redraw() and update() dont seem to have an effect
> either
> > (ignored?).
> >
> > thanks,
> >
> > Mani
> >
> >
>
>
Previous Topic:Purpose of Display.setAppName
Next Topic:WizardSelectionPage example?
Goto Forum:
  


Current Time: Tue Apr 23 10:36:52 GMT 2024

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

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

Back to the top