How to add click handler to GWT ImageResource cell? - gwt

Please help me out with this problem.
I have this code below,I actually want to insert an image into a GWT datagrid and add a click handler to the image. But it is not responding to clicks, pls what do you think might be the problem?
This is the Resource interface
public interface Resources extends ClientBundle {
#Source("delete.png")
ImageResource getDeleteImage();
#Source("edit.png")
ImageResource getEditImage();
}
Below is the ImageResource Cell that I coded, but it is not responding to clicks.
DataGrid<AccountDTO> dataGrid = new DataGrid<AccountDTO>();
Column<AccountDTO, ImageResource>delete = new Column<AccountDTO, ImageResource>(new ImageResourceCell()) {
#Override
public ImageResource getValue(AccountDTO object) {
return resources.getDeleteImage();
}
};
delete.setFieldUpdater(new FieldUpdater<AccountDTO, ImageResource>() {
#Override
public void update(int arg0, AccountDTO object, ImageResource resource) {
Window.alert(object.getId() + "" + object.getChargeAccount());
dataProvider.getList().remove(object);
dataProvider.refresh();
dataGrid.redraw();
}
dataGrid.addColumn(delete, "");
dataGrid.setColumnWidth(delete, 3.0, Unit.EM)

In the same way you have use a custom cell by extending AbstractCell for cell table you would extend ClickableTextCell (have a look a this answer). But as you are using image in your cell it gets tricky. This tutorial worked for us.

This is an old question, but there is a much simpler solution than suggested in the other answer.
datagrid.addCellPreviewHandler(new Handler<AccountDTO>() {
#Override
public void onCellPreview(CellPreviewEvent<AccountDTO> event) {
if ("click".equals(event.getNativeEvent().getType())) {
if (event.getColumn() == datagrid.getColumnIndex(myImageColumn)) {
AccountDTO account = event.getValue();
// Do what you need with a click
}
}
}
});

Related

ClickHandler doesn't fire in jquery-mobile header & footer

after hours of searching and trying, I decided to ask here.
JqmHeader.java
public class JqmHeader extends ComplexPanel {
public JqmHeader() {
setElement(DOM.createDiv());
getElement().setAttribute("data-role", "header");
}
public void add(Widget widget) {
super.add(widget, getElement());
}
}
JqmPage.java
public class JqmPage extends ComplexPanel {
...
public JqmPage(String id) {
setElement(Document.get().createDivElement());
getElement().setAttribute("data-role", "page");
getElement().setAttribute("data-url", id);
RootPanel.get().add(page);
render(page.getId());
}
private native void render(String id) /*-{
$wnd.$("#" + id).page();
}-*/;
...
}
MyPage.java extends JqmPage.java
...
JqmHeader header = new JqmHeader();
Button b = new Button("TestButton");
b.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Window.alert("TestButton clicked");
}
});
header.add(b);
this.add(header);
...
My Problem
So, my Problem is, that the ClickHandler from the Button in the header bar doesn't fire. If I add the Button not to the header, but to the "RootPage", like
this.add(b)
, everything works.
I think it must lie at the jquery-mobile header implementation. Are there any workarounds /ideas?
Thanks from Berlin,
Alex
JQuery Mobile swallows the events on headers so they are not propagated to GWT. What I did in solving this for jqm4gwt (https://github.com/sksamuel/jqm4gwt) was to have a general listener on the page level and then compare event source. If it was a button in the header then I fire that event on the button manually.
Take a look at bindHeaderEvents in https://github.com/sksamuel/jqm4gwt/blob/master/src/main/java/com/sksamuel/jqm4gwt/JQMPage.java
Also, the jqm4gwt project might be a good solution for you to save you having to invent all these widgets yourself.
If you want to take a look at a pure GWT solution for building mobile apps you could take a look at http://www.m-gwt.com

Click Handlers for Trees in GXT 3?

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

gwt:adding clickhandler to ImageResource cell

I want to add an image to my celltable , for that i use imageResouce as below
interface Resources extends ClientBundle {
#Source("close.png")
ImageResource getImageResource();
}
Resources resources = GWT.create(Resources.class);
deleteJobColumn = new Column<EmployerJobs, ImageResource>(new ImageResourceCell()) {
#Override
public ImageResource getValue(EmployerJobs object) {
return resources.getImageResource();
}
};
Its working perfectly fine , i am getting image in my celltable but Now i want to add clickhandler to that image ,For that i am using field Updater like below
display.getListJobsWidget().getDeleteJobColumn().setFieldUpdater(
new FieldUpdater<EmployerJobs, ImageResource>() {
public void update(int index, EmployerJobs employerJobs,
ImageResource value) {
Window.alert("Hello");
}
});
so now when i click on that above image cell it should say "Hello", but its not doing any thing .. Any solution ..
Thanks
ImageResourceCell doesn't have any wiring to call the ValueUpdater, it is just designed to draw the image and be done with it.
You have a few ways you can change this:
Subclass ImageResourceCell and override onBrowserEvent - take a look at ButtonCell to see how this can work
Use a different cell class instead, like ActionCell - this doesn't take any data from the client, but will let you pass in a delegate isntead, which will be run when the thing is clicked. Use the ActionCell(SafeHtml,Delegate<C>) constructor to pass in your image, in the form of html
Build a new cell, subclassing AbstractCell, borrowing the render code from ImageResourceCell and the event code from ButtonCell or ActionCell to keep your code as generic and reusable as possible.
An example for the first solution provided by Colin. I found it a bit tricky to override getConsumedEvents but seems to work well.
public class ClickableImageResourceCell extends ImageResourceCell{
public ClickableImageResourceCell(){
super();
}
#Override
public Set<String> getConsumedEvents() {
Set<String> set = new HashSet<String>();
set.add("click");
return set;
}
#Override
public void onBrowserEvent(com.google.gwt.cell.client.Cell.Context context, Element parent, ImageResource value, NativeEvent event, ValueUpdater<ImageResource> valueUpdater) {
super.onBrowserEvent(context, parent, value, event, valueUpdater);
if ("click".equals(event.getType())) {
EventTarget eventTarget = event.getEventTarget();
if (!Element.is(eventTarget)) {
return;
}
if (parent.getFirstChildElement().isOrHasChild(Element.as(eventTarget))) {
// Ignore clicks that occur outside of the main element.
keyDown(context, parent, value, event, valueUpdater);
}
}
}
protected void keyDown(Context context, Element parent, ImageResource value,
NativeEvent event, ValueUpdater<ImageResource> valueUpdater) {
if (valueUpdater != null) {
valueUpdater.update(value);
}
}
}

Gwt form question

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);
}
}

Drag and Drop in GWT using gwt dnd

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.).