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
Related
Need to catch MouseOutEvent when mouse leaves grid. Tried this:
grid.addHandler(new MouseOutHandler() {
#Override
public void onMouseOut(MouseOutEvent event) {
...
}
}, MouseOutEvent.getType());
but it fires on every cell in grid. Any help ?
First, use addDomHandler instead.
grid.addDomHandler(new MouseOutHandler() {
#Override
public void onMouseOut(MouseOutEvent event) {
...
}
}, MouseOutEvent.getType());
The difference is that addHandler does not wire the event up to the dom, but addDomHandler does. This seems to not always be required since once the event is wired up, it need not be done again, but as a good practice, every time you add a dom event handler to a widget, you should always use addDomHandler (or directly call sinkEvents, etc).
Okay, the real question asked was that too many events are going off, instead of just the general 'did the mouse leave the grid' event.
To handle this, check if the eventTarget of the event is the grid's own element. You are getting many events since you are getting all mouseout events for every element that is inside the grid, but just need to filter this down to the specific ones you are interested in.
This will look something like this:
grid.addDomHandler(new MouseOutHandler() {
#Override
public void onMouseOut(MouseOutEvent event) {
//check event target of the event
Element target = (Element) event.getNativeEvent().getEventTarget();
if (grid.getElement().equals(target) {
// the mouse has left the entire grid
// ...
}
}
}, MouseOutEvent.getType());
Solution came from jQuery via JSNI:
private native void addMouseLeaveHandler(Element element) /*-{
$wnd.$(element).mouseleave(function(){
....
});
}-*/;
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
}
}
}
});
does anyone know how to trigger the "Show More" functionality of a GWT CellTree programmatically, without having to click on the Show More button?
My aim is to implement a kind of pager that increments the number of elements displayed when the user scrolls down a ScollPanel, so it would be something like:
//inside pager class
onScroll(ScrollEvent)
{
//here I would call CellTree's show more
}
I've been looking the CellTree and CellTreeNodeView classes code but I couldn't find a clear way to do it.
I know the class CellTreeNodeView has a showMore function which is the one who performs this action, but I don't know how to get it called from another class. I'd need a CellTreeNodeView object, and dont' know how to get it.
Thanks!
It is a package protected method in a package protected class CellTreeNodeView i.e only code in com.google.gwt.user.cellview.client can invoke it.
void showMore()
Extremely hacky solution
1) The only way around it is . Copy CellTreeNodeView and CellTree into your code base (maintain the package )
2) Change the accessors to public to allow you to invoke showMore as per your requirement.
3) Ensure you test for all possible flows.
4) Ensure the copied classes in your code base appear in a higher classpath hieararchy to GWT Compiler than gwt-user jar thus ensuring your modified classes get picked up rather than original ones.
Finally I got it working exactly as I wanted, and without having to copy the code from the protected original GWT.
The point was firing the same event as the "Show more" button, so I created a fake onMouseDown event, and triggered it with the show more button as the target:
final ScrollPanel sp = new ScrollPanel();
sp.addScrollHandler(new ScrollHandler() {
#Override
public void onScroll(ScrollEvent event)
{
int maxScrollBottom = sp.getWidget().getOffsetHeight()
- sp.getOffsetHeight();
if (sp.getVerticalScrollPosition() >= maxScrollBottom) {
NativeEvent clickEvent = Document.get().createMouseDownEvent(0,0,0,0,0,false,false,false,false,0);
Element target = (Element) cellTree.getCellTree().getElement().getLastChild().getFirstChild().getLastChild();
target.dispatchEvent(clickEvent);
}
}
});
Thank you a lot, anyway! :D
My workaround is this one:
public static void makeShowMoreVisible(Element element, boolean isVisible) {
ArrayList<Element> result = new ArrayList<Element>();
findShowMore(result, element);
for (Element elt : result) {
if (isVisible) {
element.getStyle().clearDisplay();
} else {
element.getStyle().setDisplay(Display.NONE);
}
}
}
private static void findShowMore(ArrayList res, Element element) {
String c;
if (element == null) {
return;
}
if (element.getInnerText().equals("Show more")) {
res.add(element);
}
for (int i = 0; i < DOM.getChildCount(element); i++) {
Element child = DOM.getChild(element, i);
findShowMore(res, child);
}
}
I am currently developing a paint-like application for GWT. I would like to add a mouse handler that runs when the user drags the mouse across the canvas(like making a square,etc;), the problem is that I'm not surewhat handler to use. Looking through the handlers implemented in canvas has lead me to some hints, but the documentation as to what event the apply to is scant.
Does anyone know how I should implement it? Thanks.
There is no "dragging" handler. You imlement "dragging" with MouseDown, MouseMove and MouseUp events.
class YourWidget extends Composite
{
#UiField
Canvas yourCanvas;
private boolean dragging;
private HandlerRegistration mouseMove;
#UiHandler("yourCanvas")
void onMouseDown(MouseDownEvent e) {
dragging = true;
// do other stuff related to starting of "dragging"
mouseMove = yourCanvas.addMouseMoveHandler(new MouseMoveHandler(){
public void onMouseMove(MouseMoveEvent e) {
// ...do stuff that you need when "dragging"
}
});
}
#UiHandler("yourCanvas")
void onMouseUp(MouseUpEvent e) {
if (dragging){
// do other stuff related to stopping of "dragging"
dragging = false;
mouseMove.remove(); // in earlier versions of GWT
//mouseMove.removeHandler(); //in later versions of GWT
}
}
}
I've messed around with this as well and produced this little thing awhile ago:
http://alpha2.colorboxthing.appspot.com/#/
I basically wrapped whatever I needed with a FocusPanel. In my case it was a FlowPanel.
From that program in my UiBinder:
<g:FocusPanel ui:field="boxFocus" styleName="{style.boxFocus}">
<g:FlowPanel ui:field="boxPanel" styleName="{style.boxFocus}"></g:FlowPanel>
</g:FocusPanel>
How I use the focus panel (display.getBoxFocus() seen below just gets the FocusPanel above):
display.getBoxFocus().addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
}
});
display.getBoxFocus().addMouseDownHandler(new MouseDownHandler() {
#Override
public void onMouseDown(MouseDownEvent event) {
}
});
display.getBoxFocus().addMouseMoveHandler(new MouseMoveHandler() {
#Override
public void onMouseMove(MouseMoveEvent event) {
}
});
display.getBoxFocus().addMouseUpHandler(new MouseUpHandler() {
#Override
public void onMouseUp(MouseUpEvent event) {
}
});
// etc!
To answer your question about what handler to use for "dragging" I haven't found a single handler to do that for me. Instead I used a MouseDownHandler, MouseMoveHandler, and a MouseUpHandler.
Use the MouseDownHandler to set a flag that determines when the users mouse is down. I do this so that when MouseMoveHandler is called it knows if it should do anything or not. Finally use MouseUpHandler to toggle that flag if the user has the mouse down or not.
There have been some flaws with this method (if the user drags their mouse off of the FocusPanel), but because my application was just a fun side project I haven't concerned myself with it too much. Add in other handlers to fix that if it becomes a big issue.
I have implemented my own editor and added a code completion functionality to it. My content assistant is registered in source viewer configuration like this:
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
if (assistant == null) {
assistant = new ContentAssistant();
assistant.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
assistant.setContentAssistProcessor(getMyAssistProcessor(),
MyPartitionScanner.DESIRED_PARTITION_FOR_MY_ASSISTANCE);
assistant.enableAutoActivation(true);
assistant.setAutoActivationDelay(500);
assistant.setProposalPopupOrientation(IContentAssistant.PROPOSAL_OVERLAY);
assistant.setContextInformationPopupOrientation(IContentAssistant.CONTEXT_INFO_ABOVE);
}
return assistant;
}
When I press Ctrl + SPACE inside the desired partition, the completion popup appears and works as expected.
And here's my question.. How do I implement/register a documentation popup that appears next to completion popup? (For example in java editor)
Well,
I'll answear the question myself ;-)
You have to add this line
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
to the configuration above. Then when creating CompletionProposals, the eighth (last) parameter called additionalProposalInfo of the constructor is the text, which will be shown in the documentation popup.
new CompletionProposal(replacementString,
replacementOffset,
replacementLength,
cursorPosition,
image,
displayString,
contextInformation,
additionalProposalInfo);
More information about can be found here.
Easy, isn't it.. if you know how to do it ;)
For the styled information box (just like in JDT).
The DefaultInformationControl instance need to received a HTMLTextPresenter.
import org.eclipse.jface.internal.text.html.HTMLTextPresenter;
public class MyConfiguration extends SourceViewerConfiguration {
[...]
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
if (assistant == null) {
[...]
assistant.setInformationControlCreator(getInformationControlCreator(sourceViewer));
}
return assistant;
}
#Override
public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
return new IInformationControlCreator() {
public IInformationControl createInformationControl(Shell parent) {
return new DefaultInformationControl(parent,new HTMLTextPresenter(false));
}
};
}
}
Proposals can then use basic HTML tags in the string from method getAdditionalProposalInfo().
public class MyProposal implements ICompletionProposal {
[...]
#Override
public String getAdditionalProposalInfo() {
return "<b>Hello</b> <i>World</i>!";
}
}