I use SmartGWT 3.0, and I need to detect a drop of an external Label in a TreeGrid, I tried many ways to do that but none work.
In a Canvas I can do drop, but the TreeGrid doesn't detect the drop.
Is there any way to do that?
TreeGrid tileGrid = new TreeGrid();
tileGrid.setAlign(Alignment.CENTER);
tileGrid.setWidth(300);
tileGrid.setHeight(300);
tileGrid.setCanAcceptDrop(true);
tileGrid.addDropHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
Window.alert("drop");
}
});
Canvas cv = new Canvas();
cv.setBorder("1px solid #CCCCCC");
cv.setWidth(300);
cv.setHeight(300);
cv.setCanAcceptDrop(Boolean.TRUE);
cv.addDropHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
Window.alert("drop event"+event.toString());
}
});
Label lb = new Label("Drag me");
lb.setCanDrag(true);
lb.setCanDrop(true);
lb.setDragAppearance(DragAppearance.TARGET);
// added the components to a HLayout
panel.addMember(tileGrid);
panel.addMember(cv);
panel.addMember(lb);
panel.draw();
I think in the case of the canvas, it can accept everything as data dropped. In the case of the TreeGrid it expect something related to a record....
I tested with overriding
TreeGrid tileGrid2 = new TreeGrid(){
#Override
public Boolean willAcceptDrop(){
return new Boolean(true);
}
};
This in relation with this thread
And in this case The event is triggered but we get a javascript error so One solution will be to pickup the drag event from the label and create on the fly a TreeNode or something like that which could be accepted as dropped data on the grid side.
Hoping it could help....
Try
TreeGrid.addFolderDropHandler();
Related
I've been looking through GXT3's Tree API for some way to execute an action when I click or double click on a node in a tree, and I can't seem to find anything that would work.
I know TreeGrid has a CellClickHandler and CellDoubleClick handler, but there doesn't seem to be anything similar for Tree. There's the generic addHandler method inherited from Widget but this seems like it would apply to the whole tree, not a specific node.
Is there something I'm overlooking, or a different / better way to do this?
use the TreePanel's selection model:
treePanel.getSelectionModel().addSelectionChangedListener(
new SelectionChangedListener<BaseTreeModel>() {
#Override
public void selectionChanged(SelectionChangedEvent<BaseTreeModel> se) {
BaseTreeModel selectedItem = se.getSelectedItem();
// implement functionality
}
}
);
see the TreePanel API for a reference.
Use this for Single Selection
tree.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
tree.getSelectionModel().addSelectionHandler(new SelectionHandler<MenuView.MenuDto>() {
public void onSelection(SelectionEvent<MenuDto> event) {
MenuDto mnu = event.getSelectedItem();
Info.display("Tree Handler", mnu.getDescripcion());
}
});
For Multiple Selections
tree.getSelectionModel().addSelectionChangedHandler(new SelectionChangedHandler<MenuView.MenuDto>() {
public void onSelectionChanged(SelectionChangedEvent<MenuDto> event) {
List<MenuDto> mnus = event.getSelection();
Info.display("Tree Handler", mnus.get(0).getDescripcion());
}
});
Another option is to override Tree's onDoubleClick (or onClick) method:
Tree tree = new Tree<MyModel, String>(store, valueProvider){
#Override
protected void onDoubleClick(Event event) {
TreeNode<MyModel> node = findNode(event.getEventTarget().<Element> cast());
Info.display("Double Click", "You double clicked this node!");
super.onDoubleClick(event);
}
};
Figured it out.This can be achieved by using the Cell Action Tree, an implementation of which can be found here: http://www.sencha.com/examples/#ExamplePlace:cellactiontree
I need to implement drag and drop for cells in a CellTable. Following the example from the MobileWebApp I implemented a custom draggable cell:
public class DraggableCell extends AbstractCell<ProductProxy>{
interface Templates extends SafeHtmlTemplates {
#SafeHtmlTemplates.Template("<div draggable=\"true\">{0}</div>")
SafeHtml simpleTextTemplate(String text);
}
protected Templates templates = GWT.create(Templates.class);
public DraggableCell() {
super("dragstart");
}
#Override
public void render(Context context, ProductProxy value, SafeHtmlBuilder sb){
sb.append(templates.simpleTextTemplate(value.getName()));
}
#Override
public void onBrowserEvent(Context context, Element parent,
ProductProxy value, NativeEvent event,
ValueUpdater<ProductProxy> valueUpdater) {
final Integer cursorOffsetX = 0;
final Integer cursorOffsetY = 0;
if ("dragstart".equals(event.getType())) {
// Save the ID of the entity
DataTransfer dataTransfer = event.getDataTransfer();
dataTransfer.setData("text", value.getId());
SafeHtmlBuilder sb = new SafeHtmlBuilder();
sb.appendEscaped(value.getSn());
Element element = DOM.createDiv();
element.setInnerHTML(sb.toSafeHtml().asString());
// Set the helper image.
dataTransfer.setDragImage(element, cursorOffsetX, cursorOffsetY);
}
}
I use a new element for the drag image (in the MobileWebApp they just use the parent element), but unfortunately no image is displayed during the drag. I thought that maybe the new element needs to be attached to the DOM first, so I created a helperPanel and attached the element to it:
DOM.getElementById("dragHelperPanel").appendChild(element);
// Set the helper image.
dataTransfer.setDragImage(element, cursorOffsetX, cursorOffsetY);
This works fine in Firefox 6, but no luck in Chrome (using the latest stable version), so maybe this isn't the right way to do it. Any ideas? Thanks!
You can try the GWT Drag & Drop API. I have used it and its a good one even in mobile devices.
http://code.google.com/p/gwt-dnd/
Try the Demo here,
http://allen-sauer.com/com.allen_sauer.gwt.dnd.demo.DragDropDemo/DragDropDemo.html
Its quite simple to implement and don't have any issues so far for me
I have a gwt form which has about 70-100 widgets (textboxes,listboxes,custom widgets etc)
I am trying to implement the features of CUT ,COPY in this form .For this i have 2 buttons right on top of the form.
Now the problem i have is that when i click on the copy button , the widget that was focused in the form looses focus and i dont know which text to copy(or which widget was last focused before the focus getting to the copy button)
I was planning to implement blur handlers on all the widgets but i feel is a very laborious and not a good solution.
How can i get around this issue?
Thanks
Perhaps someone with a deeper insight might provide a better approach but I beleive adding blur handlers is perfectly valid. I do not quite see why you think it would be laborious, after all you don't need a different handler for each of your widgets, you can get away with only one(at most a couple for a variety of controls..), here is a very simple example,
public class CustomBlurHandler implements BlurHandler{
Object lastSource;
String text;
#Override
public void onBlur(BlurEvent event) {
if (event.getSource() instanceof TextBox) {
lastSource = event.getSource();
text = textBox.getSelectedText();
}
}
public Object getLastSource() {
return lastSource;
}
public String getText() {
return text;
}
}
and onModuleLoad :
public class Test implements EntryPoint {
CustomBlurHandler handler = new CustomBlurHandler();
public void onModuleLoad() {
TextBox text1 = new TextBox();
TextBox text2 = new TextBox();
text1.addBlurHandler(handler);
text2.addBlurHandler(handler);
Button b = new Button("Get last selected text");
b.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Window.alert(handler.getLastSource()+ " " + handler.getText());
}
});
RootPanel.get().add(text1);
RootPanel.get().add(text2);
RootPanel.get().add(b);
}
}
I'm new to GWT programming. So far I have a DialogBox which is supposed to collect a login and a password, which can if required launch another DialogBox that allows someone to create a new account.
The first of these two DialogBoxes always appears at the top left of the browser screen, and can't be dragged, although part of the definition of a DialogBox is that it can be dragged. However, the second DialogBox can be dragged about the screen without any problem.
What I'd really like is for the first DialogBox to appear in the middle of the screen & be draggable, both of which I thought would happen automatically, but there's not.
So, what things can stop a DialogBox from being draggable? There is nothing on the RootPanel yet. Does that make a difference?
Code fragments available if they help, but perhaps this general outline is enough for some pointers.
Thanks
Neil
Use dialogBox.center() This will center your DialogBox in the middle of the screen. Normally a DialogBox is by default draggable.
Just tried it out and it doens't matter if your RootPanel is empty our not. When I just show the DialogBox on ModuleLoad it is draggable and it is centered. Probably the problem is situated somewhere else.
This is the example of google itself:
public class DialogBoxExample implements EntryPoint, ClickListener {
private static class MyDialog extends DialogBox {
public MyDialog() {
// Set the dialog box's caption.
setText("My First Dialog");
// DialogBox is a SimplePanel, so you have to set its widget property to
// whatever you want its contents to be.
Button ok = new Button("OK");
ok.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
MyDialog.this.hide();
}
});
setWidget(ok);
}
}
public void onModuleLoad() {
Button b = new Button("Click me");
b.addClickListener(this);
RootPanel.get().add(b);
}
public void onClick(Widget sender) {
// Instantiate the dialog box and show it.
new MyDialog().show();
}
}
Here more information about the DialogBox.
Without seeing any of your code it's hard to tell what's going wrong. The following code works for me (ignore the missing styling...):
public void onModuleLoad() {
FlowPanel login = new FlowPanel();
Button create = new Button("create");
login.add(new TextBox());
login.add(new TextBox());
login.add(create);
create.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
final DialogBox box = new DialogBox();
FlowPanel panel = new FlowPanel();
Button close = new Button("close");
close.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
box.hide();
}
});
panel.add(new Label("some content"));
panel.add(close);
box.setWidget(panel);
box.center();
}
});
DialogBox firstBox = new DialogBox(false, true);
firstBox.setWidget(login);
firstBox.center();
}
Both boxes are draggable and shown in the center of your browser window.
Looks like you're overriding this method in Widget:
public void fireEvent(GwtEvent<?> event) {
if (handlerManager != null) {
handlerManager.fireEvent(event);
}
}
In Widget, handlerManager refers to a private HandlerManager.
Either add super.fireEvent(event) to your method or as you have done rename it.
Well, with vast amounts of trial and error I have found the problem, which was just this: I had a method in an object I'd based on DialogBox called fireEvent, which looked like this:
public void fireEvent(GwtEvent<?> event)
{
handlerManager.fireEvent(event);
}
Then, when a button was clicked on the DialogBox, an event would be created and sent off to the handlerManager to be fired properly.
And it turns out that if I change it to this (LoginEvent is a custom-built event):
public void fireEvent(LoginEvent event)
{
handlerManager.fireEvent(event);
}
... or to this ....
public void fireAnEvent(GwtEvent<?> event)
{
handlerManager.fireEvent(event);
}
the DialogBox is draggable. However, if the method begins with the line
public void fireEvent(GwtEvent<?> event)
then the result is a DialogBox which can't be dragged.
I'm a bit unsettled by this, because I can't fathom a reason why my choice of name of a method should affect the draggability of a DialogBox, or why using a base class (GwtEvent) instead of a custom class that extends it should affect the draggability. And I suspect there are dozens of similar pitfalls for a naive novice like me.
(Expecting the DialogBox to centre itself was simply my mistake.)
I have been really struggling to get Drag and Drop working in GWT. Last 3 days, I was trying to create a basic drag and drop application and failed. Currently I can drag it around, but I am unable to drop to any location.
How can we solve it? Do we need to modify onDragEnd - I am under the impression that unless I specifically have to do something, I dont have to? I am quite confused.
Also, how do I limit the drop to any single area? I do understand that we can do it using DropController. But I have defined the panels using UiBinder, so how do I get that panel back to link in the DropController? i.e. RootPanel.get() gives me the basic root panel and not the actual panel I want. I tried RootPanel.get("field-id"), but that is showing null even if that id is available. What am I doing wrong?
The code I have written is as follows:
public class TestPanel extends Composite implements
DragHandler, HasMouseDownHandlers, HasMouseUpHandlers, HasMouseMoveHandlers, HasMouseOutHandlers {
interface Binder extends UiBinder<Widget, TestPanel> { }
private static final Binder binder = GWT.create(Binder.class);
#UiField AbsolutePanel absolutePanel;
private PickupDragController TestDragController;
private Image img = new Image("./testicon.png");
public TestPanel(){
initWidget(binder.createAndBindUi(this));
absolutePanel.add(img);
TestDragController = new PickupDragController(RootPanel.get(), false);
AbsolutePositionDropController dropController = new AbsolutePositionDropController(
RootPanel.get());
TestDragController.registerDropController(dropController);
TestDragController.addDragHandler(this);
TestDragController.makeDraggable(this, getDragHandle());
}
private Widget getDragHandle() {
return img;
}
#Override
public void onDragEnd(DragEndEvent event) { }
#Override
public void onDragStart(DragStartEvent event) { }
#Override
public void onPreviewDragEnd(DragEndEvent event) throws VetoDragException { }
#Override
public void onPreviewDragStart(DragStartEvent event) throws VetoDragException { }
#Override
public HandlerRegistration addMouseDownHandler(MouseDownHandler handler) {
return addDomHandler(handler, MouseDownEvent.getType());
}
#Override
public HandlerRegistration addMouseUpHandler(MouseUpHandler handler) {
return addDomHandler(handler, MouseUpEvent.getType());
}
#Override
public HandlerRegistration addMouseMoveHandler(MouseMoveHandler handler) {
return addDomHandler(handler, MouseMoveEvent.getType());
}
#Override
public HandlerRegistration addMouseOutHandler(MouseOutHandler handler) {
return addDomHandler(handler, MouseOutEvent.getType());
}
}
and the testpanel uibinder looks like the following:
<g:AbsolutePanel ui:field="absolutePanel" styleName="{style.panel}">
</g:AbsolutePanel>
If somebody can help me out, I will be very much obliged.
K
P.S: To explain more: I was able to solve the first question by updating onDragEnd as the following:
#Override
public void onDragEnd(DragEndEvent event) {
DragContext context = event.getContext();
RootPanel.get().add(context.draggable, context.desiredDraggableX, context.desiredDraggableY);
}
but, I am not sure whether this is the correct solution - since I think I should not be doing the positioning myself.
If you're new to GWT dnd, why don't you try the working demo ?
There is a lot of examples and all the source code is available.
(And no, you're not supposed to do the positionning yourself)
You have to add a DragOverHandler on the drop target(s): even if it does nothing, it defines the component as a drop target.
Of course, you still need to define the DropHandler too on this component (and optionally, DragEnterHandler and DragLeaveHandler for visual feedback, in general).
The DragEndHandler is called even if the target isn't reached (drag abandoned in a non-drop area), it is used to change the state of the dragged object, you might need to set a way for the DropHandler to communicate success on dropping to the DragEndHandler (shared variable, EventBus, etc.).