Adding selection listener to GXT Grid? - java

I'm trying to add a selection listener to my GXT (Ext GWT) Grid, but I can't seem to get it to fire. I've tried many variations of this with no luck:
myGrid.addListener(Events.Select, new SelectionListener<ComponentEvent>() {
#Override
public void componentSelected(ComponentEvent ce) {
System.out.println("selected");
}
});

myGrid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<ModelData>() {
#Override
public void selectionChanged(SelectionChangedEvent<ModelData> se) {
...
}
});
Try this code

To upgrade this answer to GXT v3
grid.getSelectionModel().addSelectionChangedHandler(
new SelectionChangedHandler<ModelData>(){
#Override
public void onSelectionChanged(SelectionChangedEvent<ModelData> event) {
}
});

Try:
myGrid.addListener(Events.Select, new Listener<GridEvent<ModelData>>() {
#Override public void handleEvent(GridEvent<ModelData> be) {
System.out.println("selected");
}
});
Replacing ModelData with your model type if necessary.

Seemed to have found a workaround for this:
myGrid.addListener(Events.OnClick, new Listener<ComponentEvent>() {
#Override
public void handleEvent(ComponentEvent ce) {
// Handle the grid event
}
});
Seems like you just have to be generic about it, then you can check and cast your ComponentEvent to a GridEvent.

Do you use GXT 2.x version ? Did you check whether required events are sinked? for example like
grid.sinkEvents(Event.ONCLICK | Event.ONDBLCLICK | Event.MOUSEEVENTS);

Related

How to handle close tab in eclipse RCP 4

I want make a validation when pulse close button of tab in eclipse RCP 4 application and if some validation fails then prevent de close.
If you don't want to use part.setDirty(true) together with an ISaveHandler like greg-449 montioned, you could listen to the model events and correct things there. Something in the direction of this:
public class PreventCloseAddon {
#PostConstruct
public void init(final IEventBroker eventBroker, final EPartService partService) {
EventHandler tbrHandler = new EventHandler() {
#Override
public void handleEvent(Event event) {
if (!UIEvents.isSET(event))
return;
Object element = event.getProperty(UIEvents.EventTags.ELEMENT);
if (element instanceof MPart) {
MPart part = (MPart) element;
if (!part.isToBeRendered()) {
// ... validate here ...
part.setToBeRendered(true);
partService.activate(part);
}
}
}
};
eventBroker.subscribe(UIEvents.UIElement.TOPIC_TOBERENDERED, tbrHandler);
}
}
You should be aware that the part will be rendered again with this code.

swt section disable collapse

How can i disable collapse for section element. Client element should be enabled. I have one option, but it looks not good.
timeSettingsSection.addExpansionListener(new IExpansionListener() {
#Override
public void expansionStateChanging(ExpansionEvent e) {
}
#Override
public void expansionStateChanged(ExpansionEvent e) {
if (!e.getState()) {
timeSettingsSection.setExpanded(true);
return;
}
if (stopSection.isExpanded())
stopSection.setExpanded(false);
if (cabinTypeSection.isExpanded())
cabinTypeSection.setExpanded(false);
if (airlinesSection.isExpanded())
airlinesSection.setExpanded(false);
sectionExpanded();
useDepartTime.setFocus();
}
});
Yes it is org.eclipse.ui.forms.widgets.section
timeSettingsSection = getToolkit().createSection(mainGroup, Section.LEFT_TEXT_CLIENT_ALIGNMENT | Section.TWISTIE);
timeSettingsSection.setText("Time");
GridUtils.fillHorz(timeSettingsSection);
Composite group = getToolkit().createComposite(timeSettingsSection, SWT.NONE);
GridUtils.gridLayoutObj(group).numColumns(3).noMargins();
getToolkit().paintBordersFor(group);
timeSettingsSection.setClient(group);
I assume this is the org.eclipse.ui.forms.widgets.Section class.
If you create the section without specifying the TWISTIE or TREE_NODE styles then the section will not be collapsable.

DrawPanelOptions onFeatureAdded

We are working on our Gis application, I am using gwt-openlayers and we're creating Vaadin wrappers.
So I've extended the MapWidget and created the required layers and vector layers and added a DrawFeatureControl:
DrawFeatureOptions drawFeatureOptions = new DrawFeatureOptions();
private DrawFeature drawFeaturePoint = = new DrawFeature(vectorLayer, new PointHandler(), drawFeatureOptions);
and to catch the event:
getWidget().getDrawFeatureOptions().onFeatureAdded(new () {
#Override
public void (com.openlayers.client.feature.VectorFeature vectorFeature) {
Window.alert("Feature Added" + vectorFeature.getFID());
serverRpc.featureAdded(buildVectorFeature(vectorFeature));
}
});
for some reason this is not working; although the following which should be almost the same is working fine:
getWidget().getVectorLayer().addVectorFeatureSelectedListener(new () {
#Override
public void onFeatureSelected(FeatureSelectedEvent eventObject) {
serverRpc.featureSelected(buildVectorFeature(eventObject.getVectorFeature()));
}
});
using (addVectorFeatureAddedListener) on the vector layer will be fired everytime a Feature is added to the VectorLayer, and will not be fired when the DrawFeatureControl is used.
Can someone help me to catch the Features that are drawn using the DrawFeatureControl.
By The way I have a Cluster and BBox stratigies on the MapWidget, I don't know if this changes anything.
Are you aware that Vaadin have their own wrappers for OpenLayers to use OpenLayers in Vaadin ?
https://vaadin.com/directory#addon/openlayers-wrapper
I found it, for some reason
getDrawFeatureOptions().onFeatureAdded
doesn't do the trick, I had to inject the listener in GWT using:
getWidget().getDrawFeaturePoint().eventListeners.addListener(getWidget().getDrawFeaturePoint(), featurePointAddedlistener, EventType.VECTOR_FEATURE_ADDED, new EventHandler() {
#Override
public void onHandle(EventObject eventObject) {
FeatureAddedEvent e = new FeatureAddedEvent(eventObject);
featurePointAddedlistener.onFeatureAdded(e);
}
});

How can I disable Quick Access TextField in Eclipse RCP Application

today I changed my Eclipse IDE from 3.7 to 4.2 and my plugin-project has a new feature in the Statusbar of the UI called QuickAccess. But I dont need it, so how can I disable this feature, because the position of my button bar has changed...
For all who have the same problem, it seems that this new feature is hardcoded and can't be disabled :/ https://bugs.eclipse.org/bugs/show_bug.cgi?id=362420
Go to Help --> Install New Software
https://raw.github.com/atlanto/eclipse-4.x-filler/master/pdt_tools.eclipse-4.x-filler.update/
Install that Plugin and Restart the Eclipse. Quick Access automatically hide.
or else you have an option to hide Window --> Hide Quick Access.
Here's a post that shows a way to hide it with CSS. Verified with Eclipse 4.3
Lars Vogel just reported in his blog post "Porting Eclipse 3.x RCP application to Eclipse 4.4 – now without QuickAccess box":
Bug 411821 ([QuickAccess] Contribute SearchField through a fragment or other means)
is now solved.
Thanks to René Brandstetter:
If a RCP app doesn't provide the QuickAccess element in its model, than it will not be visible. So the default is no QuickAcces, easy enough? :)
See the commit 839ee2 for more details
Provide the "QuickAccess" via a e4 application model fragment inside of the "org.eclipse.ui.ide.application".
This removes the "QuickAccess" search field from every none "org.eclipse.ui.ide.application".
You could also hide it and make it work comparable to how it used to work in Eclipse3.7: when user presses ctrl+3 Quick Access functionality pops up (In Eclipse4.3 the ctrl+3 shortcut is still available).
Example of code you could add to your implementation of WorkbenchWindowAdvisor (for Eclipse4.3 rcp application)
private IHandlerActivation quickAccessHandlerActivation;
#Override
public void postWindowOpen() {
hideQuickAccess();
}
private void hideQuickAccess() {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
setQuickAccessVisible(window, false);
final IHandlerService service = (IHandlerService) window.getService(IHandlerService.class);
quickAccessHandlerActivation = service.activateHandler(QUICK_ACCESS_COMMAND_ID, new CustomQuickAccessHandler());
}
private void setQuickAccessVisible(IWorkbenchWindow window, boolean visible) {
if (window instanceof WorkbenchWindow) {
MTrimBar topTrim = ((WorkbenchWindow) window).getTopTrim();
for (MTrimElement element : topTrim.getChildren()) {
if (QUICK_ACCESS_ELEMENT_ID.equals(element.getElementId())) {
element.setVisible(visible);
if (visible) {
Composite control = (Composite) element.getWidget();
control.getChildren()[0].addFocusListener(new QuickAccessFocusListener());
}
break;
}
}
}
}
private class QuickAccessFocusListener implements FocusListener {
#Override
public void focusGained(FocusEvent e) {
//not interested
}
#Override
public void focusLost(FocusEvent e) {
((Control) e.widget).removeFocusListener(this);
hideQuickAccess();
}
}
private class CustomQuickAccessHandler extends AbstractHandler {
#Override
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
final IHandlerService service = (IHandlerService) window.getService(IHandlerService.class);
setQuickAccessVisible(window, true);
if (quickAccessHandlerActivation != null) {
service.deactivateHandler(quickAccessHandlerActivation);
try {
return service.executeCommand(QUICK_ACCESS_COMMAND_ID, null);
} catch (NotDefinedException e) {
} catch (NotEnabledException e) {
} catch (NotHandledException e) {
}
}
return null;
}
}

Hooking a GWT event onto an element in an external iframe

I am writing a GWT app that involves interacting with an external document in an iframe. As a proof of concept, I am trying to attach a click handler to a button.
The following works in javascript
var iframe = document.getElementById("rawJSIFrame");
var doc = iframe.contentDocument;
var body = doc.body;
var button = doc.getElementsByTagName("input").namedItem("submit");
button.onclick = function() {
alert("Clicked!");
};
Trying to do the equivalent in GWT, I did the following:
public void addClickHandlerToSubmitButton(String buttonElementName, ClickHandler clickHandler) {
IFrameElement iframe = IFrameElement.as(frame.getElement());
Document frameDocument = getIFrameDocument(iframe);
if (frameDocument != null) {
Element buttonElement = finder(frameDocument).tag("input").name(buttonElementName).findOne();
ElementWrapper wrapper = new ElementWrapper(buttonElement);
HandlerRegistration handlerRegistration = wrapper.addClickHandler(clickHandler);
}
}
private native Document getIFrameDocument(IFrameElement iframe)/*-{
return iframe.contentDocument;
}-*/;
The following is the ElementWrapper class:
public class ElementWrapper extends Widget implements HasClickHandlers {
public ElementWrapper(Element theElement) {
setElement(theElement);
}
public HandlerRegistration addClickHandler(ClickHandler handler) {
return addDomHandler(handler, ClickEvent.getType());
}
}
The code to find the button works fine but the actual click event handler is not getting invoked. Has anybody had a similar issue before, and how did you resolve it?
Thanks in advance,
Tin
Hilbrand is right about the problem being that the GWT method onAttach() was not called.
I implemented your original solution, adding the following method to ElementWrapper:
public void onAttach() {
super.onAttach();
}
And called added wrapper.onAttach() after the ElementWrapper is created. Works like a charm!
I expect the problem is that the GWT method onAttach() is not called when you use the wrapping as in your first example. You can try to use the static wrap method on the Button widget. Although to use this the input must be of type button. Or have a look at the implementation of the wrap method. Here is the modified code when using the wrap method:
Element buttonElement = finder(frameDocument).tag("input").name(buttonElementName).findOne();
Button button = Button.wrap(buttonElement);
HandlerRegistration handlerRegistration = button.addClickHandler(clickHandler);
After researching this further, I found that the iframe is irrelevant. The same behaviour doesn't work on a normal button on the host page.
I basically fixed it by using JSNI to replicate part of GWT's event handling mechanism. The following works:
Element buttonElement = DOM.getElementById("externalButton");
new CustomElementWrapper(buttonElement).addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
Window.alert("GWT hooked into button");
}
});
Where CustomElementWrapper is:
public class CustomElementWrapper extends Widget implements HasClickHandlers {
private ClickEventManager clickEventManager;
public CustomElementWrapper(Element theElement) {
setElement(theElement);
clickEventManager = new ClickEventManager(theElement);
}
public HandlerRegistration addClickHandler(ClickHandler handler) {
//The 'right' way of doing this would be the code below. However, this doesn't work
// A bug in GWT?
//
// return addDomHandler(handler, ClickEvent.getType());
return clickEventManager.registerClickHandler(handler);
}
void invokeClickHandler() {
clickEventManager.invokeClickHandler();
}
public boolean isClickHandlerRegistered() {
return clickEventManager.isClickHandlerRegistered();
}
}
Finally, the ClickEventManager, where the actual work happens is:
public class ClickEventManager {
private boolean clickHandlerRegistered = false;
private ClickHandler clickHandler;
private Element element;
public ClickEventManager(Element element) {
this.element = element;
}
public void invokeClickHandler() {
//This shouldn't really be null but we are bypassing GWT's native event mechanism
//so we can't create an event
clickHandler.onClick(null);
}
public boolean isClickHandlerRegistered() {
return clickHandlerRegistered;
}
HandlerRegistration registerClickHandler(ClickHandler handler) {
clickHandler = handler;
if (!clickHandlerRegistered) {
registerClickHandlerInJS(element);
clickHandlerRegistered = true;
}
return new HandlerRegistration() {
public void removeHandler() {
//For now, we don't support the removal of handlers
throw new UnsupportedOperationException();
}
};
}
private native void registerClickHandlerInJS(Element element)/*-{
element.__clickManager = this;
element.onclick
= function() {
var cm = this.__clickManager;
cm.#com.talktactics.agent2.client.widgets.ClickEventManager::invokeClickHandler()();
}
}-*/;
}
Personally, I hate this solution because I appear to be duplicating GWT's event handling and quite possibly introducing nasty javascript memory leaks. Any ideas on why my first post doesn't work (remembering that the iframe aspect is a red herring), would be appreciated.
Thanks,
Tin
You may find this helpful:
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.ui.AbsolutePanel;
public class DirectPanel extends AbsolutePanel implements HasClickHandlers {
public DirectPanel(Element elem) {
super(elem.<com.google.gwt.user.client.Element> cast());
onAttach();
}
#Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
return addDomHandler(handler, ClickEvent.getType());
}
}
You will then be able to make arbitrary containers into widget containers:
Element root = Document.get().getElementById("target");
DirectPanel p = new DirectPanel(root);
Button register = new Button("Register");
register.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
// ...
}
});
p.add(register);
And bind events to arbitrary elements:
Element root = Document.get().getElementById("target");
DirectPanel p = new DirectPanel(root);
p.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
// ...
}
});
Specifically in your case, try this:
IFrameElement frm = Document.get().createIFrameElement();
Document d = frm.getContentDocument();
NodeList<Element> inputs = d.getElementsByTagName("input");
InputElement target = null;
for(int i = 0; i < inputs.getLength(); ++i) {
Element e = inputs.getItem(0);
if (e.getNodeName().equals("submit")) {
target = InputElement.as(e);
break;
}
}
if (target != null) {
DirectPanel p = new DirectPanel(target);
p.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
// TODO Auto-generated method stub
}
});
}
It's always mystified me that GWT makes doing this so difficult and poorly documented.
Instead of using iframes i suggest you simply make a http request from GWT via com.google.gwt.http.client.RequestBuilder. Like so:
private void getHtml(String url) {
RequestBuilder rb = new RequestBuilder(RequestBuilder.GET, url);
rb.setCallback(new RequestCallback() {
#Override
public void onResponseReceived(Request request, Response response) {
HTMLPanel html = new HTMLPanel(response.getText());
// Now you have a widget with the requested page
// thus you may do whatever you want with it.
}
#Override
public void onError(Request request, Throwable exception) {
Log.error("error " + exception);
}
});
try {
rb.send();
} catch (RequestException e) {
Log.error("error " + e);
}
}
You could use JSNI to reuse your JavaScript piece of code. Your javascript code would call a gwt method on an object that would throw it on behalf of the button in the iframe.
As to why GWT code does not work -- I guess that is because they use some layer on top of regular browser events that probably cannot span more than 1 frame. That's just a guess though. You could file this as a feature/bug request agains GWT team. If I am right your code looks just fine.
Please see my previous answer. A slight modification to your original solution will make it work.

Categories

Resources