Home » Eclipse Projects » GEF » Moving figures using GEF drag and drop (minimal example)
Moving figures using GEF drag and drop (minimal example) [message #23487] |
Thu, 03 October 2002 15:31 |
Alexandre Vermeerbergen Messages: 110 Registered: July 2009 |
Senior Member |
|
|
Hello,
I am trying to build a minimal example of a GEF editor with simple figures
which can be moved using drag & drop.
My problem is that the drag and drop feedback (my figure is a
RectangleFigure) work fine, but I cannot drop my figure at any location in
the editor (I have a 'forbiden icon' .
My "root" edit part is defined by this code:
============================================================ =====
public class HelloTopEditPart extends AbstractGraphicalEditPart {
protected IFigure createFigure() { // borrowed to logical diagram editor
code...
Figure f = new FreeformLayer();
f.setLayoutManager(new FreeformLayout());
f.setBorder(new MarginBorder(5));
f.setOpaque(true);
return f;
}
protected void createEditPolicies() {
installEditPolicy(EditPolicy.CONTAINER_ROLE, new
HelloContainerEditPolicy());
installEditPolicy(EditPolicy.LAYOUT_ROLE, null);
installEditPolicy(EditPolicy.NODE_ROLE, null);
installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, null);
installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, null);
installEditPolicy(EditPolicy.COMPONENT_ROLE, new
RootComponentEditPolicy());
}
protected List getModelChildren() {
List children = ((HelloModel)getModel()).getNodes(); // a four-elements
java.util.Vector
return children;
}
public DragTracker getDragTracker(Request req) { return new
MarqueeDragTracker(); }
}
============================================================ =====
Given that my HelloContainerEditPolicy() is just a class that implements
ContainerEditPolicy, returning null for both abstract methods
getCreateCommand() and getDeleteCommand(). The code for HelloEditPart, which
are the EditParts used to represent the four figures in our editor is the
following:
============================================================ =====
public class HelloEditPart extends AbstractGraphicalEditPart {
protected IFigure createFigure() {
RectangleFigure rectangle = new RectangleFigure();
Point location = new Point(s_instanceCount*10,s_instanceCount*10);
rectangle.setLocation(location);
return rectangle;
}
protected void createEditPolicies() {
installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, null);
installEditPolicy(EditPolicy.NODE_ROLE, null);
installEditPolicy(EditPolicy.PRIMARY_DRAG_ROLE, new
NonResizableEditPolicy());
}
}
============================================================ =====
Somehow, I imagine that I cannot drop my figures because I have not said
anywere what are the acceptable drop locations. Yet I would have imagined
that by default, a container EditPart would accept any drops, at least to
move figures that have a NonResizableEditPolicy...
Anyone here could help me finding out what I am missing to move by
drag&dropping my figures?
best regards,
Alex.
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #23530 is a reply to message #23487] |
Thu, 03 October 2002 16:33 |
Eclipse User |
|
|
|
Originally posted by: hudsonr.us.eye-bee-em.com
> protected void createEditPolicies() {
> installEditPolicy(EditPolicy.CONTAINER_ROLE, new
> HelloContainerEditPolicy());
ContainerEditPolicy in the CONTAINER_ROLE is actually not involved in
graphical interaction and targeting. The purpose of this role is to do
things that *only* involve the model, such as deleting a child from a
parent. The idea is that you might want to reuse this policy in the
TreeViewer. Also, while layouts on a container might change, this policy
probably would stay the same.
> installEditPolicy(EditPolicy.LAYOUT_ROLE, null);
> installEditPolicy(EditPolicy.NODE_ROLE, null);
> installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, null);
This is the one you need for targeting and for dealing with mouse locations.
You set it to null, so you don't get targeting.
> installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, null);
> installEditPolicy(EditPolicy.COMPONENT_ROLE, new
> RootComponentEditPolicy());
> }
> ============================================================ =====
>
> Somehow, I imagine that I cannot drop my figures because I have not said
> anywere what are the acceptable drop locations. Yet I would have imagined
Right, you do this by EditPolicy.getTargetEditPart(Request).
LayoutEditPolicies do this for you for certain requests like CREATE and ADD.
This method should really be considered a boolean method, asking if the
EditPolicy's host is the target for the Request. 99% of the time the
EditPolicy will return either NULL or its host EditPart.
> that by default, a container EditPart would accept any drops, at least to
Any AbstractEditPart has support for children, so this is not the default.
Targeting for other operations is completely different. For example when
creating connections, only "nodes" are targetable.
> move figures that have a NonResizableEditPolicy...
>
> Anyone here could help me finding out what I am missing to move by
> drag&dropping my figures?
>
> best regards,
>
> Alex.
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #23657 is a reply to message #23530] |
Fri, 04 October 2002 14:36 |
Alexandre Vermeerbergen Messages: 110 Registered: July 2009 |
Senior Member |
|
|
Randy:
I am still blocked in my attempt to allow moving node through drag & drop...
I read your previous answer and tried to apply what you recommend:
> > installEditPolicy(EditPolicy.LAYOUT_ROLE, null);
> > installEditPolicy(EditPolicy.NODE_ROLE, null);
> > installEditPolicy(EditPolicy.GRAPHICAL_NODE_ROLE, null);
> This is the one you need for targeting and for dealing with mouse
locations.
> You set it to null, so you don't get targeting.
Okay, so I created the following layout policy:
============================================================ =====
public class HelloXYLayoutEditPolicy extends XYLayoutEditPolicy {
protected Command createAddCommand(EditPart child, Object constraint) {
return null;
}
protected Command createChangeConstraintCommand(EditPart child, Object
constraint) {
return null;
}
protected Command getCreateCommand(CreateRequest request) {
return null;
}
protected EditPolicy createChildEditPolicy(EditPart child) {
return new NonResizableEditPolicy(); // rendundant with children
EditPart's createEditPolicies()...why?
}
protected Command getDeleteDependantCommand(Request request) {
return null;
}
public EditPart getTargetEditPart(Request request) {
EditPart targetEditPart = getHost(); // I guessed that...
return targetEditPart;
}
}
============================================================ =====
and I replaced the 'installEditPolicy(EditPolicy.LAYOUT_ROLE, null);' in my
'HelloTopEditPart.createEditPolicies()' (code in the first post of this
news-thread) by the following line:
installEditPolicy(EditPolicy.LAYOUT_ROLE, new HelloXYLayoutEditPolicy());
But the result is that when I try to move a node by drag & dropping, I have
a null pointer exception in class XYLayoutEditPolicy, in method
getConstraintFor(), to be more precise, the null pointer is located in GEF
source code here:
============================================================ =====
protected Object getConstraintFor(ChangeBoundsRequest request,
GraphicalEditPart child) {
Rectangle rect = child.getFigure().getBounds().getCopy();
rect = request.getTransformedRectangle(rect);
rect.translate(getLayoutOrigin().getNegated());
if (RequestConstants.REQ_MOVE_CHILDREN.equals(request.getType() )) {
Rectangle cons = (Rectangle)getCurrentConstraintFor(child);
rect.setSize(cons.width, cons.height); // NULL POINTER HERE BECAUSE
cons=null !!!
}
if (RequestConstants.REQ_RESIZE_CHILDREN.equals(request.getType ())) {
Dimension minSize = getMinimumSizeFor(child);
if (rect.width < minSize.width)
rect.width = minSize.width;
if (rect.height < minSize.height)
rect.height = minSize.height;
}
return getConstraintFor(rect);
}
============================================================ =====
Okay, so it appears that for some reason I do not understand,
getCurrentConstraintFor() returns null for my child EditPart node. As a
reminder, these nodes are a 'RectangleFigure()' figure, and their parent is
a FreeformLayer (code shown is first post of this newsthread).
I tried to fix the null pointer by overridding the getCurrentConstraintFor()
in my HelloXYLayoutEditPolicy class: I return a new Rectangle: the null
pointer exception does not shows up, but this time the
getMoveChildrenCommand() always returns an
org.eclipse.gef.commands.UnexecutableCommand!!! (I made several tentative
with various rectangle sizes, no success)
I am afraid I need a little bit more hints to be able to allow moving with
nodes by drag & drop with my 'minimal GEF example'.
Any help appreciated,
Alex.
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #23700 is a reply to message #23657] |
Fri, 04 October 2002 15:23 |
Eclipse User |
|
|
|
Originally posted by: hudsonr.us.eye-bee-em.com
> protected EditPolicy createChildEditPolicy(EditPart child) {
> return new NonResizableEditPolicy(); // rendundant with children
> EditPart's createEditPolicies()...why?
> }
Because the layout on the parent container determines the manner in which
the children can be resized. For example, in a Grid Layout the resize
behavior might be to snap to cells. Or perhaps resize isn't allowed in a
given layout.
You should probably remove your childs call to set the edit policy.
> Rectangle cons = (Rectangle)getCurrentConstraintFor(child);
> rect.setSize(cons.width, cons.height); // NULL POINTER HERE BECAUSE
> cons=null !!!
protected Rectangle getCurrentConstraintFor(GraphicalEditPart child){
IFigure fig = child.getFigure();
return (Rectangle)fig.getParent().getLayoutManager().getConstraint( fig);
}
getCurrentConstraintFor() gets the constraint from the Layout manager, not
by getting the current bounds of the figure. This is because a constraint
of Rectangle(x, y, -1, -1) can be used to mean "size the child to be its
preferredSize()". Moving that child has to maintain the original width and
height in the *constraint*, not the original width and height of the figures
bounds.
You are getting null because you aren't setting a constraint for the child.
You are likely just setting the Figure's bounds instead. Look at the
refreshVisuals() method in the Logic Example.
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #24835 is a reply to message #23700] |
Mon, 07 October 2002 13:03 |
Alexandre Vermeerbergen Messages: 110 Registered: July 2009 |
Senior Member |
|
|
Randy:
I followed your instructions: I followed the refreshVisual() example of the
Logical Diagram editor, and then I understood that I had to return a
non-null value from XYLayoutEditPolicy.createChangeConstraintCommand()
.... and this non-null value is a Command, so I had to add command support to
my "hello GEF" example, and then I had to add a property change system to
make sure my edit part was notified when my model's coordinate when changed
by the command, so that refreshVisual() is called !
My "move rectangles using GEF and drag&drop" example works, but I do not
consider it quite minimal:
- it makes use of commands
- makes sures of property listeners
- I had to "pollute" my model with figure's location.
Isn't it possible to simply further by asking the figures to hold the node's
positions and find a way so that they would call automagically
refreshVisual() when moved...?
Sure, I understand that all that complexity might be useful when dealing
with real-world GEF applications, where you need to save the figures's
locations, but for a "minimal example", that's lots of details...
Could I simplify further using another LayoutManager?
Alex.
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #25039 is a reply to message #24835] |
Mon, 07 October 2002 15:52 |
Eclipse User |
|
|
|
Originally posted by: hudsonr.us.eye-bee-em.com
>
> My "move rectangles using GEF and drag&drop" example works, but I do not
> consider it quite minimal:
> - it makes use of commands
Commands are a fundamental part of GEF. Why would you not want to use
commands? If you just start reaching in and manipulating Figures and
EditParts directly, you end up with very tightly coupled code, and probably
run into problems down the road when you want to modify from the model from
outside the Graphicaviewer.
> - makes sures of property listeners
You can use any notification mechanism you want.
> - I had to "pollute" my model with figure's location.
Why would you allow the user to move things if the locations aren't
persisted?
> Could I simplify further using another LayoutManager?
Sure, if you don't want to be able to move the objects, you could use a
FlowLayout or similar layout. Then you don't need to store the locations in
your model.
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #25566 is a reply to message #25039] |
Tue, 08 October 2002 14:14 |
Alexandre Vermeerbergen Messages: 110 Registered: July 2009 |
Senior Member |
|
|
"Randy Hudson" <hudsonr@us.eye-bee-em.com> wrote in message
news:ans99e$p8r$1@rogue.oti.com...
> ...
> Commands are a fundamental part of GEF. Why would you not want to use
> commands? If you just start reaching in and manipulating Figures and
> EditParts directly, you end up with very tightly coupled code, and
probably
> run into problems down the road when you want to modify from the model
from
> outside the Graphicaviewer.
Okay, I'll use commands in my "minimal" example.
> > - makes sures of property listeners
> You can use any notification mechanism you want.
Okay, I keep the one I used in the example...
> > - I had to "pollute" my model with figure's location.
> Why would you allow the user to move things if the locations aren't
> persisted?
I want to answer to this question: my initial dream was to save locations
directly into the IFigure object associated to the EditPart representing my
node... unfortunately, it did not work, so I polluted my model. Yes I can
imagine a way to have a "clean model" (without graph coordinates & sizes),
and a "GEF dual model" associated to my model to keep such geometrical
informations in memory...
> > Could I simplify further using another LayoutManager?
> Sure, if you don't want to be able to move the objects, you could use a
> FlowLayout or similar layout. Then you don't need to store the locations
in
> your model
So we have no smaller choice here (I was dreaming of a windows manager
transparently keeping locations) for the example. Okay.
Thank you very much for all these answers!
Alex.
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #25754 is a reply to message #25566] |
Tue, 08 October 2002 16:31 |
Eclipse User |
|
|
|
Originally posted by: edisontooNOSPAM.yahoo.com.sg
Hi,
> I want to answer to this question: my initial dream was to save locations
> directly into the IFigure object associated to the EditPart representing my
> node... unfortunately, it did not work, so I polluted my model. Yes I can
> imagine a way to have a "clean model" (without graph coordinates & sizes),
> and a "GEF dual model" associated to my model to keep such geometrical
> informations in memory...
If you really do not want to store geometric information, you can still
save the locations directly into the IFigure object by doing the following
1) For all requests that affects geometric info, create commands that
modify the IFigure instead of the model.
2) To do that, you need a way to get a IFigure from a model, since the
some requests pass in the model object rather the EditPart.
3) Since you have to implement the GraphicPartFactory interface, that
would be a good place to store a map from model object to EditPart.
The trick therefore is how you write your Command. Of course you will
still have to worry about inventing geometric information when you load
your model. ;)
Hope this helps.
Cheers,
Edison
|
|
| |
Re: Moving figures using GEF drag and drop (minimal example) [message #26267 is a reply to message #25754] |
Wed, 09 October 2002 14:36 |
Eclipse User |
|
|
|
Originally posted by: hudsonr.us.eye-bee-em.com
"Edison Too" <edisontooNOSPAM@yahoo.com.sg> wrote in message
news:3DA3084E.1080104@yahoo.com.sg...
> Hi,
>
> > I want to answer to this question: my initial dream was to save
locations
> > directly into the IFigure object associated to the EditPart representing
my
> > node... unfortunately, it did not work, so I polluted my model. Yes I
can
> > imagine a way to have a "clean model" (without graph coordinates &
sizes),
> > and a "GEF dual model" associated to my model to keep such geometrical
> > informations in memory...
>
> If you really do not want to store geometric information, you can still
> save the locations directly into the IFigure object by doing the following
>
> 1) For all requests that affects geometric info, create commands that
> modify the IFigure instead of the model.
This is bad programming if the purpose of the example is to be
instructional. When the user deletes the object, the EditPart and Figure
are lost, so you will lose the information. What both of you are describing
is a split *model*, where the model consists of "pure" model objects, like
UML classes and attributes, and also a "view" model, which records which
classes are being viewed in a diagram and where they are located. Even in
this split approach, both parts still make up the overall "model", and the
Figures and EditParts are external to the model.
> 2) To do that, you need a way to get a IFigure from a model, since the
> some requests pass in the model object rather the EditPart.
Do they? I though most passed the editparts.
> 3) Since you have to implement the GraphicPartFactory interface, that
> would be a good place to store a map from model object to EditPart.
>
> The trick therefore is how you write your Command. Of course you will
> still have to worry about inventing geometric information when you load
> your model. ;)
Exactly. Allowing the user to move stuff and then not persisting it does
not help people write applications that do.
> Hope this helps.
>
> Cheers,
> Edison
>
|
|
|
Re: Moving figures using GEF drag and drop (minimal example) [message #26614 is a reply to message #26267] |
Wed, 09 October 2002 15:45 |
Alexandre Vermeerbergen Messages: 110 Registered: July 2009 |
Senior Member |
|
|
Randy:
"Randy Hudson" <hudsonr@us.eye-bee-em.com> wrote in message
news:ao1di7$r1a$1@rogue.oti.com...
> ...
> This is bad programming if the purpose of the example is to be
> instructional. When the user deletes the object, the EditPart and Figure
> are lost, so you will lose the information. What both of you are
describing
> is a split *model*, where the model consists of "pure" model objects, like
> UML classes and attributes, and also a "view" model, which records which
> classes are being viewed in a diagram and where they are located. Even in
> this split approach, both parts still make up the overall "model", and the
> Figures and EditParts are external to the model.
> ...
Agreed, now everything is clear. I will apply this "clean model"+"view
model" to my Hello Gef #1 example when I'll time to do it.
Thank you very much for this clarification.
|
|
|
Goto Forum:
Current Time: Sat Dec 21 12:27:49 GMT 2024
Powered by FUDForum. Page generated in 0.05658 seconds
|