Home » Eclipse Projects » GEF » How do I create Figures that look like SWT controls?
How do I create Figures that look like SWT controls? [message #144220] |
Fri, 23 July 2004 15:27  |
Eclipse User |
|
|
|
How do I create Figures that look like SWT controls? I'm trying to
write something similar to SWT Designer, where users can arrange
controls to layout a user interface. I do not want the controls to be
interactive in any way (receive focus, etc...), I just want them to look
as close to native widgets as possible. How can this be accomplished?
Thank you.
- Sean
|
|
| | |
Re: How do I create Figures that look like SWT controls? [message #146390 is a reply to message #144647] |
Tue, 03 August 2004 18:30   |
Eclipse User |
|
|
|
Thank you. That was enough to get me going in the right direction. One
thing I can't figure out, is what I should use for the parent of the SWT
control when it is created. Doesn't the SWT control have to be visible
somewhere for me to steal a copy of it's graphics? Does the following
code look right, or am I missing some things? What should go in place
of the ?????'s:
protected IFigure createFigure() {
Figure f1 = new Figure() {
protected void paintFigure(Graphics graphics) {
org.eclipse.swt.widgets.Button button = new
org.eclipse.swt.widgets.Button(?????, SWT.BORDER);
button.setText("Hello");
button.setSize(getClientArea().width, getClientArea().height);
GC gc = new GC(button);
Image image = new Image(Display.getDefault(),
getClientArea().width, getClientArea().height);
gc.copyArea(image, 0, 0); // Copy picture of SWT control to image
graphics.drawImage(image, 0, 0); // draw picture onto figure
gc.dispose();
image.dispose();
button.dispose();
}
};
f1.setOpaque(true);
f1.setLayoutManager(new XYLayout());
return f1;
}
?? Thanks.
-= Sean
Randy Hudson wrote:
> SWT designer takes pictures of real SWT controls using:
>
> gc = new GC(theControl);
> image = new Image(...);
> gc.copyArea(image, ....)
>
> "Sean Neeley" <sean.neeley@dbcsoftware.com> wrote in message
> news:cdrovu$1p1$1@eclipse.org...
>
>>How do I create Figures that look like SWT controls? I'm trying to
>>write something similar to SWT Designer, where users can arrange
>>controls to layout a user interface. I do not want the controls to be
>>interactive in any way (receive focus, etc...), I just want them to look
>>as close to native widgets as possible. How can this be accomplished?
>>Thank you.
>>
>>- Sean
>
>
>
|
|
|
Re: How do I create Figures that look like SWT controls? [message #146983 is a reply to message #146390] |
Mon, 09 August 2004 15:45   |
Eclipse User |
|
|
|
Well, unfortunately I did not get much help on this so I had to figure
out most everything on my own. Anyway, I have it all working really
well right now. I would like to post my code so that if anyone else
tries this, they do not waste 2 days like I did. Good times.
- Sean
/**
* @author Sean Neeley
*
*/
public class SWTControlFigure extends Label {
private FigureCanvas canvas;
private int width = 0, height = 0;
private Image image;
SWTControlFigure(RootEditPart editpart) {
super();
canvas = (FigureCanvas) editpart.getViewer().getControl();
setOpaque(true);
setLayoutManager(new XYLayout());
}
protected void paintFigure(Graphics g) {
// next line reduces flicker, may want to use white for text fields
g.setBackgroundColor(Display.getDefault().getSystemColor(SWT .COLOR_WIDGET_BACKGROUND));
super.paintFigure(g);
if (image != null) {
Rectangle r = getBounds();
g.drawImage(image, r.x, r.y); // draw picture of swt control onto
figure
}
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.IFigure#removeNotify()
*/
public void removeNotify() {
super.removeNotify();
if (image != null) {
image.dispose();
image = null;
}
}
/* (non-Javadoc)
* @see org.eclipse.draw2d.Figure#layout()
*/
protected void layout() {
if (isVisible()) {
width = getClientArea().width;
height = getClientArea().height;
if (image != null) {
image.dispose();
image = null;
}
// Create any SWT control here
org.eclipse.swt.widgets.Button button = new
org.eclipse.swt.widgets.Button(canvas, SWT.NONE);
button.addPaintListener(new SWTPaintListener());
button.setText("Hello");
Point p1 = new Point(0, 0);
translateToAbsolute(p1); // coordinates returned are negative if
canvas is scrolled
button.setBounds(getBounds().x + p1.x, getBounds().y + p1.y, width,
height);
button.moveAbove(null); // necessary
}
super.layout();
}
private class SWTPaintListener implements PaintListener {
public void paintControl(PaintEvent e) {
image = new Image(canvas.getDisplay(), width, height);
e.gc.copyArea(image, 0, 0);
final Control source = (Control) e.getSource();
try {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
source.dispose();
}
});
}
catch(Exception e1) { }
repaint();
}
}
}
|
|
|
Re: How do I create Figures that look like SWT controls? [message #147033 is a reply to message #146983] |
Mon, 09 August 2004 22:34   |
Eclipse User |
|
|
|
Originally posted by: none.us.ibm.com
IFigure.removeNotify() will only get called if you remove the figure. If
you just close your editor, figures are not removed, they just get garbage
collected. So the code below will leak an SWT Image. EditPart.deactivate()
is guaranteed to be called, so you could use it to call some dispose API on
your figure to tell it to stop updating.
"Sean Neeley" <sean.neeley@dbcsoftware.com> wrote in message
news:cf8k52$ath$1@eclipse.org...
> Well, unfortunately I did not get much help on this so I had to figure
> out most everything on my own. Anyway, I have it all working really
> well right now. I would like to post my code so that if anyone else
> tries this, they do not waste 2 days like I did. Good times.
>
> - Sean
>
> /**
> * @author Sean Neeley
> *
> */
> public class SWTControlFigure extends Label {
>
> private FigureCanvas canvas;
> private int width = 0, height = 0;
> private Image image;
>
> SWTControlFigure(RootEditPart editpart) {
> super();
> canvas = (FigureCanvas) editpart.getViewer().getControl();
> setOpaque(true);
> setLayoutManager(new XYLayout());
> }
>
> protected void paintFigure(Graphics g) {
> // next line reduces flicker, may want to use white for text fields
>
>
g.setBackgroundColor(Display.getDefault().getSystemColor(SWT .COLOR_WIDGET_BA
CKGROUND));
>
> super.paintFigure(g);
> if (image != null) {
> Rectangle r = getBounds();
> g.drawImage(image, r.x, r.y); // draw picture of swt control onto
> figure
> }
> }
>
> /* (non-Javadoc)
> * @see org.eclipse.draw2d.IFigure#removeNotify()
> */
> public void removeNotify() {
> super.removeNotify();
> if (image != null) {
> image.dispose();
> image = null;
> }
> }
>
> /* (non-Javadoc)
> * @see org.eclipse.draw2d.Figure#layout()
> */
> protected void layout() {
> if (isVisible()) {
> width = getClientArea().width;
> height = getClientArea().height;
> if (image != null) {
> image.dispose();
> image = null;
> }
> // Create any SWT control here
> org.eclipse.swt.widgets.Button button = new
> org.eclipse.swt.widgets.Button(canvas, SWT.NONE);
> button.addPaintListener(new SWTPaintListener());
> button.setText("Hello");
> Point p1 = new Point(0, 0);
> translateToAbsolute(p1); // coordinates returned are negative if
> canvas is scrolled
> button.setBounds(getBounds().x + p1.x, getBounds().y + p1.y, width,
> height);
> button.moveAbove(null); // necessary
> }
> super.layout();
> }
>
> private class SWTPaintListener implements PaintListener {
> public void paintControl(PaintEvent e) {
> image = new Image(canvas.getDisplay(), width, height);
> e.gc.copyArea(image, 0, 0);
> final Control source = (Control) e.getSource();
> try {
> Display.getDefault().asyncExec(new Runnable() {
> public void run() {
> source.dispose();
> }
> });
> }
> catch(Exception e1) { }
> repaint();
> }
> }
>
> }
|
|
|
Re: How do I create Figures that look like SWT controls? [message #147094 is a reply to message #147033] |
Tue, 10 August 2004 10:47   |
Eclipse User |
|
|
|
Thank you Randy!
- Sean
Randy Hudson wrote:
> IFigure.removeNotify() will only get called if you remove the figure. If
> you just close your editor, figures are not removed, they just get garbage
> collected. So the code below will leak an SWT Image. EditPart.deactivate()
> is guaranteed to be called, so you could use it to call some dispose API on
> your figure to tell it to stop updating.
>
> "Sean Neeley" <sean.neeley@dbcsoftware.com> wrote in message
> news:cf8k52$ath$1@eclipse.org...
>
>>Well, unfortunately I did not get much help on this so I had to figure
>>out most everything on my own. Anyway, I have it all working really
>>well right now. I would like to post my code so that if anyone else
>>tries this, they do not waste 2 days like I did. Good times.
>>
>>- Sean
>>
>>/**
>> * @author Sean Neeley
>> *
>> */
>>public class SWTControlFigure extends Label {
>>
>>private FigureCanvas canvas;
>>private int width = 0, height = 0;
>>private Image image;
>>
>>SWTControlFigure(RootEditPart editpart) {
>> super();
>> canvas = (FigureCanvas) editpart.getViewer().getControl();
>>setOpaque(true);
>>setLayoutManager(new XYLayout());
>>}
>>
>>protected void paintFigure(Graphics g) {
>> // next line reduces flicker, may want to use white for text fields
>>
>>
>
> g.setBackgroundColor(Display.getDefault().getSystemColor(SWT .COLOR_WIDGET_BA
> CKGROUND));
>
>> super.paintFigure(g);
>>if (image != null) {
>> Rectangle r = getBounds();
>> g.drawImage(image, r.x, r.y); // draw picture of swt control onto
>>figure
>>}
>>}
>>
>>/* (non-Javadoc)
>> * @see org.eclipse.draw2d.IFigure#removeNotify()
>> */
>>public void removeNotify() {
>> super.removeNotify();
>> if (image != null) {
>> image.dispose();
>> image = null;
>> }
>>}
>>
>>/* (non-Javadoc)
>> * @see org.eclipse.draw2d.Figure#layout()
>> */
>>protected void layout() {
>> if (isVisible()) {
>> width = getClientArea().width;
>> height = getClientArea().height;
>> if (image != null) {
>> image.dispose();
>> image = null;
>> }
>> // Create any SWT control here
>> org.eclipse.swt.widgets.Button button = new
>>org.eclipse.swt.widgets.Button(canvas, SWT.NONE);
>> button.addPaintListener(new SWTPaintListener());
>> button.setText("Hello");
>>Point p1 = new Point(0, 0);
>>translateToAbsolute(p1); // coordinates returned are negative if
>>canvas is scrolled
>>button.setBounds(getBounds().x + p1.x, getBounds().y + p1.y, width,
>>height);
>>button.moveAbove(null); // necessary
>>}
>> super.layout();
>>}
>>
>>private class SWTPaintListener implements PaintListener {
>> public void paintControl(PaintEvent e) {
>>image = new Image(canvas.getDisplay(), width, height);
>>e.gc.copyArea(image, 0, 0);
>>final Control source = (Control) e.getSource();
>>try {
>> Display.getDefault().asyncExec(new Runnable() {
>>public void run() {
>> source.dispose();
>>}
>> });
>>}
>>catch(Exception e1) { }
>>repaint();
>> }
>>}
>>
>>}
>
>
>
|
|
|
Re: How do I create Figures that look like SWT controls? [message #165333 is a reply to message #147094] |
Mon, 24 January 2005 07:09   |
Eclipse User |
|
|
|
Originally posted by: marlu942.student.liu.se
Hi Sean,
I'm using your code for displaying SWT-controls as GEF figures.
The only problem is, if half of the SWT widget is offscreen when I
scrape the graphics, I end up with garbage on the half of the image
where the widget was offscreen.
Is this a known error?
Regards,
Marcus Ludvigson
Sean Neeley wrote:
> Thank you Randy!
>
> - Sean
>
> Randy Hudson wrote:
>
>> IFigure.removeNotify() will only get called if you remove the figure. If
>> you just close your editor, figures are not removed, they just get
>> garbage
>> collected. So the code below will leak an SWT Image.
>> EditPart.deactivate()
>> is guaranteed to be called, so you could use it to call some dispose
>> API on
>> your figure to tell it to stop updating.
>>
>> "Sean Neeley" <sean.neeley@dbcsoftware.com> wrote in message
>> news:cf8k52$ath$1@eclipse.org...
>>
>>> Well, unfortunately I did not get much help on this so I had to figure
>>> out most everything on my own. Anyway, I have it all working really
>>> well right now. I would like to post my code so that if anyone else
>>> tries this, they do not waste 2 days like I did. Good times.
>>>
>>> - Sean
>>>
>>> /**
>>> * @author Sean Neeley
>>> *
>>> */
>>> public class SWTControlFigure extends Label {
>>>
>>> private FigureCanvas canvas;
>>> private int width = 0, height = 0;
>>> private Image image;
>>>
>>> SWTControlFigure(RootEditPart editpart) {
>>> super();
>>> canvas = (FigureCanvas) editpart.getViewer().getControl();
>>> setOpaque(true);
>>> setLayoutManager(new XYLayout());
>>> }
>>>
>>> protected void paintFigure(Graphics g) {
>>> // next line reduces flicker, may want to use white for text fields
>>>
>>>
>>
>> g.setBackgroundColor(Display.getDefault().getSystemColor(SWT .COLOR_WIDGET_BA
>>
>> CKGROUND));
>>
>>> super.paintFigure(g);
>>> if (image != null) {
>>> Rectangle r = getBounds();
>>> g.drawImage(image, r.x, r.y); // draw picture of swt control onto
>>> figure
>>> }
>>> }
>>>
>>> /* (non-Javadoc)
>>> * @see org.eclipse.draw2d.IFigure#removeNotify()
>>> */
>>> public void removeNotify() {
>>> super.removeNotify();
>>> if (image != null) {
>>> image.dispose();
>>> image = null;
>>> }
>>> }
>>>
>>> /* (non-Javadoc)
>>> * @see org.eclipse.draw2d.Figure#layout()
>>> */
>>> protected void layout() {
>>> if (isVisible()) {
>>> width = getClientArea().width;
>>> height = getClientArea().height;
>>> if (image != null) {
>>> image.dispose();
>>> image = null;
>>> }
>>> // Create any SWT control here
>>> org.eclipse.swt.widgets.Button button = new
>>> org.eclipse.swt.widgets.Button(canvas, SWT.NONE);
>>> button.addPaintListener(new SWTPaintListener());
>>> button.setText("Hello");
>>> Point p1 = new Point(0, 0);
>>> translateToAbsolute(p1); // coordinates returned are negative if
>>> canvas is scrolled
>>> button.setBounds(getBounds().x + p1.x, getBounds().y + p1.y, width,
>>> height);
>>> button.moveAbove(null); // necessary
>>> }
>>> super.layout();
>>> }
>>>
>>> private class SWTPaintListener implements PaintListener {
>>> public void paintControl(PaintEvent e) {
>>> image = new Image(canvas.getDisplay(), width, height);
>>> e.gc.copyArea(image, 0, 0);
>>> final Control source = (Control) e.getSource();
>>> try {
>>> Display.getDefault().asyncExec(new Runnable() {
>>> public void run() {
>>> source.dispose();
>>> }
>>> });
>>> }
>>> catch(Exception e1) { }
>>> repaint();
>>> }
>>> }
>>>
>>> }
>>
>>
>>
>>
|
|
| | |
Re: How do I create Figures that look like SWT controls? [message #165570 is a reply to message #165341] |
Tue, 25 January 2005 15:24  |
Eclipse User |
|
|
|
Originally posted by: marlu942.student.liu.se
Hi!
Sean Neeley gave me some hints on how to solve this problem in a private
respons.
"Parts of SWT controls that are not visible cannot be scraped. It is a
limitation of SWT. If it was not a problem, I would be scraping
everything offscreen for performance. The solution, is to re-scrape
when a control is moved (add a figure listener), and when the figure
canvas is scrolled (add listener on figure canvas's viewport). I found
a way to further optimize this code, so that widgets aren't scraped
unnecessarily, by comparing the clipping rectangle of the swt widget in
the paintControl() method, with the widgets bounds and keeping around a
'needs_scraped' flag."
I implemented his suggestions with a listener on the figure canvas's
viewport, as my figures does not move:
<snip>
public class ButtonFigure extends UIElementFigure {
private FigureCanvas canvas;
private Image image;
private String name;
private boolean needsReScrape = true;
public ButtonFigure(RootEditPart editpart){
super();
canvas = (FigureCanvas) editpart.getViewer().getControl();
Viewport viewPort = canvas.getViewport();
viewPort.addFigureListener(new FigureListener() {
public void figureMoved(IFigure source) {
if (needsReScrape) layout();
}
});
setLayoutManager(new XYLayout());
}
public void setName(String name) {
this.name = name;
}
protected void paintFigure(Graphics g) {
g.setBackgroundColor(Display.getDefault().getSystemColor(SWT .COLOR_WIDGET_BACKGROUND));
super.paintFigure(g);
if (image != null) {
Rectangle r = getBounds();
g.drawImage(image, r.x, r.y); // draw picture of swt
control onto figure
}
}
/*
* Should be called when the editpart is disposed.
*/
public void dispose() {
if (image != null) {
image.dispose();
image = null;
}
}
/*
* @see org.eclipse.draw2d.Figure#layout()
*/
protected void layout() {
if (image != null) {
image.dispose();
image = null;
}
// Create any SWT control here
org.eclipse.swt.widgets.Button button = new
org.eclipse.swt.widgets.Button(canvas, SWT.CENTER | SWT.PUSH);
button.addPaintListener(new SWTPaintListener());
button.setText(name);
Point p1 = new Point(0, 0);
translateToAbsolute(p1);
button.setBounds(getBounds().x + p1.x, getBounds().y + p1.y,
sizeBounds.width+2,sizeBounds.height+2);
button.moveAbove(null);
super.layout();
}
private class SWTPaintListener implements PaintListener {
public void paintControl(PaintEvent e) {
if (e.width >= sizeBounds.width && e.height >=
sizeBounds.height){
needsReScrape = false;
} else {
needsReScrape = true;
}
image = new Image(canvas.getDisplay(), sizeBounds.width,
sizeBounds.height);
e.gc.copyArea(image, 0, 0);
final Control source = (Control) e.getSource();
try {
Display.getDefault().asyncExec(new Runnable() {
public void run() {
source.dispose();
}
});
}
catch(Exception e1) { }
repaint();
}
}
}
Hope this helps.
Regards
/Marcus
FreeGroup wrote:
>
>
> Hi,
>
> I have the same behaviour :-(
>
> 1. Open an editor with a this 'system' drawn button
> (button should bee out of editor scroll area.)
> 2. Resize the editor or scroll to the button.
> 3. The button is corrupted.
>
> The code fits perfect to my requirements if the 'bug' possible
> to fix.
>
>
> greetings
>
> Andreas
>
> Marcus Ludvigson wrote:
>
>> Hi Sean,
>>
>> I'm using your code for displaying SWT-controls as GEF figures.
>> The only problem is, if half of the SWT widget is offscreen when I
>> scrape the graphics, I end up with garbage on the half of the image
>> where the widget was offscreen.
>>
>> Is this a known error?
>>
>> Regards,
>> Marcus Ludvigson
>>
>>
>> Sean Neeley wrote:
|
|
|
Goto Forum:
Current Time: Sun Jun 08 14:31:14 EDT 2025
Powered by FUDForum. Page generated in 0.16111 seconds
|