Home » Archived » Visual Editor (VE) » adding a component to VE (not extending the palette, actually adding component to the form in code)
adding a component to VE (not extending the palette, actually adding component to the form in code) [message #98356] |
Tue, 19 July 2005 00:46 |
Dylan Bruzenak Messages: 48 Registered: July 2009 |
Member |
|
|
Ok, I'm assuming this is simple and I'm just missing something. I hope ;)
What I'm trying to do: I have a framework that in certain circumstances
says 'hey, it would be nifty if this here JTextbox were on that there
editor'. I can create the java component(or any CompilationUnit,
sourcetype, what have you), but VE uses a EMF model, not a set of
components to draw the screen. I'd like to know how to add a certain
(arbitrary) type of component to a panel displayed in a VE editor, with
corresponding layout friendly code generation. I'd like to do this in
pure code.
Also, any inside into the VE model would be very helpful. The more I
see into the internals of eclipse the more I want to extend things.
thanks,
Dylan Bruzenak
|
|
|
Re: adding a component to VE (not extending the palette, actually adding component to the form in [message #98552 is a reply to message #98356] |
Wed, 20 July 2005 09:52 |
Joe Winchester Messages: 496 Registered: July 2009 |
Senior Member |
|
|
Hi Dylan,
> What I'm trying to do: I have a framework that in certain circumstances
> says 'hey, it would be nifty if this here JTextbox were on that there
> editor'. I can create the java component(or any CompilationUnit,
> sourcetype, what have you), but VE uses a EMF model, not a set of
> components to draw the screen. I'd like to know how to add a certain
> (arbitrary) type of component to a panel displayed in a VE editor, with
> corresponding layout friendly code generation. I'd like to do this in
> pure code.
> Also, any inside into the VE model would be very helpful. The more I
> see into the internals of eclipse the more I want to extend things.
For starters take a look at the tutorial on Extending the Visual Editor
at
http://www.eclipse.org/articles/Article-VE-Custom-Widget/cus tomwidget.html.
While this doesn't go into the EMF model in great detail it sort of is
designed to be a primer that touches the main VE subsystems and more
tutorials on each subsystem in detail are in the pipeline. We're heads
down on the 3.1 GA this week but next week we should get a breather and
more time to work on docs and tutorials.
For starters what I'd do is add a pop-up menu option and look at how
this is done in the org.eclipse.ve.jfc plugin for example that extends
the pop-up menu of JTabbedPane. Once you have the delegate there and
are in its selection event you will get an edit part. This has a model
that is a JavaObjectInstance.
Rather than dive into the JLabel child (which is kinda more complex)
let's assume you just want to set the background color. The code might be
// Get the target that we assume is a JPanel
EditPart editPart = (EditPart)
((IStructuredSelection)selection).getFirstElement();
IJavaInstance target = (IJavaInstance) editPart.getModel();
ResourceSet rset = target.eResource().getResourceSet();
// Create a color
IJavaInstance redColor =
BeanUtilities.createJavaObject("javax.swing.JLabel",rset,"java.awt.Color.red ");
// Set the color on the JPanel
EStructuralFeature colorSF =
target.eClass().eGetStructuralFeature("background");
target.eSet(colorSF,redColor);
For a JLabel on a JPanel the reason it is more complex is cause of
constraints. We don't model the AWT components as children of the
container because we need to store addition things like
GridBagConstraints (constraints are not attributes on a Component and
are part of the add(...) method. For this reason 3 objects are involved
- the JPanel, the ConstraintComponent and the JLabel. The code then
becomes the steps
1 - create the JLabel
2 - create the ConstraintComponent
3 - set the JLabel into the ConstraintComponent
4 - add the ConstraintComponent as the child of the JPanel
The following code should give a sort of overview for the steps and the
methods to use.
// Get the target that we assume is a JPanel
EditPart editPart = (EditPart)
((IStructuredSelection)selection).getFirstElement();
IJavaInstance target = (IJavaInstance) editPart.getModel();
ResourceSet rset = target.eResource().getResourceSet();
// Create the JLabel
IJavaInstance jLabel =
BeanUtilities.createJavaObject("javax.swing.JLabel",rset,(String)null);
// Create the intermediate that sits between the JPanel and the JLabel
EClass constraintCls =
rset.getEObject(JFCConstants.CLASS_CONTAINER_CONSTRAINTCOMPO NENT, true);
EFactory visualFact = JFCConstants.getFactory(constraintCls);
EObject constraintComponent =
visualFact.create(classConstraintComponent);
// Set the JLabel into the intermediate
EStructuralFeature constraintComponentSF =
JavaInstantiation.getSFeature(rset, JFCConstants.SF_CONSTRAINT_COMPONENT);
constraintComponent.eSet(constraintComponentSF,jLabel);
// Add the constraint component to the JPanel
EStructuralFeature containerChildren =
target.eClass().getEStructuralFeature("components");
((List)target.eGet(containerChildren)).add(constraintCompone nt);
I haven't compiled or tested this but it should give you a feel for what
the steps are. The work to add something when it is dropped from the
palette is done by the EditPolicy and there is a difference one per
layout manager, so put a breakpoint into FlowLayoutEditPolicy and follow
the code flow through dropping something from the palette.
Also feel free to ask questions on the ve-dev mailing list that tends to
be more for people wanting to extend the VE.
Best regards,
Joe Winchester
|
|
| |
Re: adding a component to VE (not extending the palette, actually adding component to the form in [message #98754 is a reply to message #98552] |
Wed, 20 July 2005 14:50 |
Eclipse User |
|
|
|
Originally posted by: richkulp.us.NO_SPAM.ibm.com
I'm assuming you want to do this in conjunction with the VE itself.
In that case what Joe showed you is a synopsis of how you update the EMF
model, but what he didn't show you is that these need to be done through
commands. We have the RuledCommandBuilder to do this. Plus it has to be
executed through the command stack so that the code generation works
correctly. You cannot directly update the live EMF model or things will
not work correctly, you will get bad code or no code generated.
So your popup menu would need to use a RuledCommandBuilder to build up
the commands and then using the command stack have it executed.
A good starting example would be the
CreateContentPaneObjectActionDelegate popup action. Look at the run method.
The run method creates a RuledCommandBuilder and passes it to a utility
method to create the command, and then it executes the command.
In the utility method, you do see some usage of direct setting of
properties. This is valid for any EMF object that has not yet been added
into the model. So if you building up a complicated component, you can
set any of property on that component before you actually add the
component to the model. You would then use the RuledCommandBuilder to
finally add this built-up component into the model. Once it is in the
model, all changes to it must be done through commands.
--
Thanks,
Rich Kulp
|
|
| | |
Re: adding a component to VE (not extending the palette, actually adding component to the form in [message #98856 is a reply to message #98783] |
Wed, 20 July 2005 21:55 |
Joe Winchester Messages: 496 Registered: July 2009 |
Senior Member |
|
|
Hi Dylan,
> Code references work wonders. The VE + EMF + JDT + ect... codebase is
> kind of large and hard to find specific things in, unless you know
> exactly what you are looking for. I'm looking forward to tutorials on
> the subject, although I suspect I will master many of the issues before
> they become available.
> I'm kind of surprised that it takes 11 lines of code to add a label to a
> form. Are there plans in the pipeline to simplify this api for
> extenders ?
We should provide a facade API to make it easier to use, however the
underlying tasks will still be the same. Basically in the model
everything is an IJavaInstance. Doesn't matter if it is a JButton or
Shell. Every property (getter and setter) is an EReference. If you
want to set something it is basically
aJavaInstance.eSet(eReference,anotherJavaInstance);
Every JavaInstance exists inside a resourceSet and this is just how EMF
works - it can be thought of as the working set for the document being
edited. To get the resource set from something you go
aJavaInstance.eResource().getResourceSet();
to create something you go
BeanUtilities.createJavaObject(qualifiedClassName,resourceSe t,initString);
initString is what goes in the code on the set statement, so for a color
it might be
IJavaInstance colorInstance =
BeanUtilites.createJavaObject("java.awt.Color",rSet,"java.awt.Color,red ");
to get an EReference look it up by name from the EMF class, e.g.
EReference colorRef = aJavaInstance.eClass().eGet("background");
and to set it
aJavaInstance.eSet(colorRef,colorInstance);
This updates the model that can be thought of as a sort of big graph of
objects that point to each other and have a meta layer that represents
the class or shape side.
As Rich points out though, you shouldn't ever write the kind of code as
abovce. Instead there is a class that actually simplifies the API as
well as ensures the correct Java code is generated (some people don't
want Java and use XML serialization so for them the API above works).
For RuledCommandBuilder the GEF edit domain needs to be known. There
are several ways to get this but the most common is probably that you
have a handle to a GEF edit part and use
EditDomain editDomain = EditDomain.get(anEditPart);
For the setting of the color the code would be
RuledCommandBuilder bldr = new RuledCommandBuilder(editDomain);
IJavaInstance colorInstance =
BeanUtilites.createJavaObject("java.awt.Color",rSet,"java.awt.Color,red ");
bldr.applyAttributesetting(aJavaInstance,"background",colorInstance);
You can either then execute the command directly using
editDomain.getCommandStack().execute(bldr.getCommand());
or if you are in a GEF edit policy you tend to return the command to the
tool that asked for the request and GEF then executes it based on some
mouse/keyboard gesture.
>I can always just build my own utilities, but the code is
> just a wee bit intimidating on first glance. Might scare off some of
> the more timid among us. It would be hard to do this in an
> implementation agnostic manner, I suppose. But for the purposes of
> working with the jfc model some things could be clarified. Is this in
> the pipeline ?
jfc complicates things because of the relationship between an AWT
container and its child components needing somewhere to hold the
constraint (GridBagConstraints, etc...) object. Likewise for
JTabbedPane and its children where the tabText, tabIcon and
tabTooltipText need to be held. Both use an intermediate so
unfortunately you test case is sort of a baptism of fire just cause it
is the most complex part of jfc.
> I'm looking forward to 1.1. I hope testing is going well for everyone.
Up to the wire. For the jfc example I actually would like for us to
create an example and tutorial based on your idea so please open a
bugzilla feature request for this.
Best regards,
Joe Winchester
|
|
| | | |
Re: adding a component to VE (not extending the palette, actually adding component to the form in [message #609114 is a reply to message #98356] |
Wed, 20 July 2005 09:52 |
Joe Winchester Messages: 496 Registered: July 2009 |
Senior Member |
|
|
Hi Dylan,
> What I'm trying to do: I have a framework that in certain circumstances
> says 'hey, it would be nifty if this here JTextbox were on that there
> editor'. I can create the java component(or any CompilationUnit,
> sourcetype, what have you), but VE uses a EMF model, not a set of
> components to draw the screen. I'd like to know how to add a certain
> (arbitrary) type of component to a panel displayed in a VE editor, with
> corresponding layout friendly code generation. I'd like to do this in
> pure code.
> Also, any inside into the VE model would be very helpful. The more I
> see into the internals of eclipse the more I want to extend things.
For starters take a look at the tutorial on Extending the Visual Editor
at
http://www.eclipse.org/articles/Article-VE-Custom-Widget/cus tomwidget.html
While this doesn't go into the EMF model in great detail it sort of is
designed to be a primer that touches the main VE subsystems and more
tutorials on each subsystem in detail are in the pipeline. We're heads
down on the 3.1 GA this week but next week we should get a breather and
more time to work on docs and tutorials.
For starters what I'd do is add a pop-up menu option and look at how
this is done in the org.eclipse.ve.jfc plugin for example that extends
the pop-up menu of JTabbedPane. Once you have the delegate there and
are in its selection event you will get an edit part. This has a model
that is a JavaObjectInstance.
Rather than dive into the JLabel child (which is kinda more complex)
let's assume you just want to set the background color. The code might be
// Get the target that we assume is a JPanel
EditPart editPart = (EditPart)
((IStructuredSelection)selection).getFirstElement();
IJavaInstance target = (IJavaInstance) editPart.getModel();
ResourceSet rset = target.eResource().getResourceSet();
// Create a color
IJavaInstance redColor =
BeanUtilities.createJavaObject("javax.swing.JLabel",rset,"java.awt.Color.red ");
// Set the color on the JPanel
EStructuralFeature colorSF =
target.eClass().eGetStructuralFeature("background");
target.eSet(colorSF,redColor);
For a JLabel on a JPanel the reason it is more complex is cause of
constraints. We don't model the AWT components as children of the
container because we need to store addition things like
GridBagConstraints (constraints are not attributes on a Component and
are part of the add(...) method. For this reason 3 objects are involved
- the JPanel, the ConstraintComponent and the JLabel. The code then
becomes the steps
1 - create the JLabel
2 - create the ConstraintComponent
3 - set the JLabel into the ConstraintComponent
4 - add the ConstraintComponent as the child of the JPanel
The following code should give a sort of overview for the steps and the
methods to use.
// Get the target that we assume is a JPanel
EditPart editPart = (EditPart)
((IStructuredSelection)selection).getFirstElement();
IJavaInstance target = (IJavaInstance) editPart.getModel();
ResourceSet rset = target.eResource().getResourceSet();
// Create the JLabel
IJavaInstance jLabel =
BeanUtilities.createJavaObject("javax.swing.JLabel",rset,(String)null);
// Create the intermediate that sits between the JPanel and the JLabel
EClass constraintCls =
rset.getEObject(JFCConstants.CLASS_CONTAINER_CONSTRAINTCOMPO NENT, true);
EFactory visualFact = JFCConstants.getFactory(constraintCls);
EObject constraintComponent =
visualFact.create(classConstraintComponent);
// Set the JLabel into the intermediate
EStructuralFeature constraintComponentSF =
JavaInstantiation.getSFeature(rset, JFCConstants.SF_CONSTRAINT_COMPONENT);
constraintComponent.eSet(constraintComponentSF,jLabel);
// Add the constraint component to the JPanel
EStructuralFeature containerChildren =
target.eClass().getEStructuralFeature("components");
((List)target.eGet(containerChildren)).add(constraintCompone nt);
I haven't compiled or tested this but it should give you a feel for what
the steps are. The work to add something when it is dropped from the
palette is done by the EditPolicy and there is a difference one per
layout manager, so put a breakpoint into FlowLayoutEditPolicy and follow
the code flow through dropping something from the palette.
Also feel free to ask questions on the ve-dev mailing list that tends to
be more for people wanting to extend the VE.
Best regards,
Joe Winchester
|
|
| |
Re: adding a component to VE (not extending the palette, actually adding component to the form in [message #609129 is a reply to message #98552] |
Wed, 20 July 2005 14:50 |
Eclipse User |
|
|
|
Originally posted by: richkulp.us.NO_SPAM.ibm.com
I'm assuming you want to do this in conjunction with the VE itself.
In that case what Joe showed you is a synopsis of how you update the EMF
model, but what he didn't show you is that these need to be done through
commands. We have the RuledCommandBuilder to do this. Plus it has to be
executed through the command stack so that the code generation works
correctly. You cannot directly update the live EMF model or things will
not work correctly, you will get bad code or no code generated.
So your popup menu would need to use a RuledCommandBuilder to build up
the commands and then using the command stack have it executed.
A good starting example would be the
CreateContentPaneObjectActionDelegate popup action. Look at the run method.
The run method creates a RuledCommandBuilder and passes it to a utility
method to create the command, and then it executes the command.
In the utility method, you do see some usage of direct setting of
properties. This is valid for any EMF object that has not yet been added
into the model. So if you building up a complicated component, you can
set any of property on that component before you actually add the
component to the model. You would then use the RuledCommandBuilder to
finally add this built-up component into the model. Once it is in the
model, all changes to it must be done through commands.
--
Thanks,
Rich Kulp
|
|
| | |
Re: adding a component to VE (not extending the palette, actually adding component to the form in [message #609142 is a reply to message #98783] |
Wed, 20 July 2005 21:55 |
Joe Winchester Messages: 496 Registered: July 2009 |
Senior Member |
|
|
Hi Dylan,
> Code references work wonders. The VE + EMF + JDT + ect... codebase is
> kind of large and hard to find specific things in, unless you know
> exactly what you are looking for. I'm looking forward to tutorials on
> the subject, although I suspect I will master many of the issues before
> they become available.
> I'm kind of surprised that it takes 11 lines of code to add a label to a
> form. Are there plans in the pipeline to simplify this api for
> extenders ?
We should provide a facade API to make it easier to use, however the
underlying tasks will still be the same. Basically in the model
everything is an IJavaInstance. Doesn't matter if it is a JButton or
Shell. Every property (getter and setter) is an EReference. If you
want to set something it is basically
aJavaInstance.eSet(eReference,anotherJavaInstance);
Every JavaInstance exists inside a resourceSet and this is just how EMF
works - it can be thought of as the working set for the document being
edited. To get the resource set from something you go
aJavaInstance.eResource().getResourceSet();
to create something you go
BeanUtilities.createJavaObject(qualifiedClassName,resourceSe t,initString);
initString is what goes in the code on the set statement, so for a color
it might be
IJavaInstance colorInstance =
BeanUtilites.createJavaObject("java.awt.Color",rSet,"java.awt.Color,red ");
to get an EReference look it up by name from the EMF class, e.g.
EReference colorRef = aJavaInstance.eClass().eGet("background");
and to set it
aJavaInstance.eSet(colorRef,colorInstance);
This updates the model that can be thought of as a sort of big graph of
objects that point to each other and have a meta layer that represents
the class or shape side.
As Rich points out though, you shouldn't ever write the kind of code as
abovce. Instead there is a class that actually simplifies the API as
well as ensures the correct Java code is generated (some people don't
want Java and use XML serialization so for them the API above works).
For RuledCommandBuilder the GEF edit domain needs to be known. There
are several ways to get this but the most common is probably that you
have a handle to a GEF edit part and use
EditDomain editDomain = EditDomain.get(anEditPart);
For the setting of the color the code would be
RuledCommandBuilder bldr = new RuledCommandBuilder(editDomain);
IJavaInstance colorInstance =
BeanUtilites.createJavaObject("java.awt.Color",rSet,"java.awt.Color,red ");
bldr.applyAttributesetting(aJavaInstance,"background",colorInstance);
You can either then execute the command directly using
editDomain.getCommandStack().execute(bldr.getCommand());
or if you are in a GEF edit policy you tend to return the command to the
tool that asked for the request and GEF then executes it based on some
mouse/keyboard gesture.
>I can always just build my own utilities, but the code is
> just a wee bit intimidating on first glance. Might scare off some of
> the more timid among us. It would be hard to do this in an
> implementation agnostic manner, I suppose. But for the purposes of
> working with the jfc model some things could be clarified. Is this in
> the pipeline ?
jfc complicates things because of the relationship between an AWT
container and its child components needing somewhere to hold the
constraint (GridBagConstraints, etc...) object. Likewise for
JTabbedPane and its children where the tabText, tabIcon and
tabTooltipText need to be held. Both use an intermediate so
unfortunately you test case is sort of a baptism of fire just cause it
is the most complex part of jfc.
> I'm looking forward to 1.1. I hope testing is going well for everyone.
Up to the wire. For the jfc example I actually would like for us to
create an example and tutorial based on your idea so please open a
bugzilla feature request for this.
Best regards,
Joe Winchester
|
|
| | | |
Goto Forum:
Current Time: Thu Apr 18 09:52:57 GMT 2024
Powered by FUDForum. Page generated in 0.02672 seconds
|