I have many ItemWidget which extends a Composite. If a click event is received on one of the items a change event should be fired and other item widgets should receive this event.
It tried the following:
public class ItemWidget extends Composite implements HasChangeHandlers {
FocusPanel focusPanel = new FocusPanel();
public ItemWidget() {
Label label = new Label("click me");
focusPanel.add(label);
initWidget(focusPanel);
focusPanel.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
// inform other items
fireChange();
}
});
addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent event) {
GWT.log("ChangeEvent received");
}
});
}
private void fireChange() {
GWT.log("fire event");
NativeEvent nativeEvent = Document.get().createChangeEvent();
ChangeEvent.fireNativeEvent(nativeEvent, this);
}
#Override
public HandlerRegistration addChangeHandler(ChangeHandler handler) {
return addDomHandler(handler, ChangeEvent.getType());
}
}
Using the above code only the item which is clicked receives the ChangeEvent.
How can I receive the ChangeEvent on all the other item widgets too?
Typically, when an event fires, a presenter/Activity makes the necessary changes to the other widgets.
If you want multiple copies of you widget to listen to the same event, you may be better off using the EventBus, especially if you use this pattern more than once:
How to use the GWT EventBus
Then each of your ItemWidget can fire a custom event that all copies of this widget listen to.
By looking at the API quickly I think your problem comes from your implementation of
public void fireEvent(GwtEvent<?> event)
You did not override it in your composite view. You did not create any mechanism to send the event to the other widgets.
Have a deeper look at the method fireNativeEvent
http://www.gwtproject.org/javadoc/latest/com/google/gwt/event/dom/client/DomEvent.html
When you use ChangeEvent.fireNativeEvent the second param hasHandlers should be a kind of event bus.
To do what you want to do I think you need all the items to be on this eventBus.
Related
I'm looking for some feedback/insight into the use of Javas ability to clone events.
/*create an eventhandler for the mouse click when on the imagetoview
* This event handler is bound to the mouse_clicked event
*/
imagetoview.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
//define a public override to set the functionality of the new
//mouse click event handler
#Override public void handle(MouseEvent e) {
Object clone = e.clone();
}
});
Why would I use this ability if i can access all of the event data from the original?
button.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent e) {
label.setText("Accepted");
}
});
In the code above we are defining what will happen when we press the button. This is all good but I wanna create new ActionListener and then add it to my button.
Normally in JButton I can just add ActionListener like this:
button.addActionListener(someControllerClass.createButtonListener());
In code above createButtonListener() returns ActionListener.
My question is: What is the equivalent of JButton addActionListener ?
If you want to e.g. reuse an EventHandler, define it like described in JavaFX Documentation as:
EventHandler<ActionEvent> buttonHandler = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
label.setText("Accepted");
event.consume();
}
};
You can now add your defined buttonHandler to the onAction of your button via:
button.setOnAction(buttonHandler);
And citing from the documentation providing the remove option for completeness:
To remove an event handler that was registered by a convenience method, pass null to the convenience method, for example, node1.setOnMouseDragged(null).
Resulting for you in:
button.setOnAction(null)
The documentation furthermore provides some examples how to add handler for specific events - it's a good read.
Just the same approach, but easier with lamda expressions:
button.setOnAction(event -> buttonSaveClicked());
I think this is how I should do. Creating the handler:
public EventHandler<Event> createSolButtonHandler()
{
btnSolHandler = new EventHandler<Event>() {
#Override
public void handle(Event event) {
System.out.println("Pressed!");
biddingHelperFrame.getBtnSag().setVisible(false);
}
};
return btnSolHandler;
}
Adding Handler to button:
btnSol.addEventHandler(MouseEvent.MOUSE_CLICKED, biddingHelperFrameController.createSolButtonHandler());
In my project I need to fire an event after a node was clicked in my CellTree. I solved this with the following code.
model.setSelectionHandler(new SelectionChangeEvent.Handler()
{
#Override
public void onSelectionChange(SelectionChangeEvent event)
{
//My logic is here
}
});
The problem is that this only works if the node is not selected already. Clicking the node again will not fire the event. Is there a click handler or another event which is fired after a node was clicked?
Please try with SelectionHandler api .
This can be achieved by creating your own TreeItem that implements ClickHandler
public class CustomTreeItem extends TreeItem implements ClickHandler
{
//classes logic here
#Override
public void onClick(ClickEvent event)
{
// TODO Auto-generated method stub
}
}
Sometimes I use something like this:
model.setSelectionHandler(new SelectionChangeEvent.Handler()
{
#Override
public void onSelectionChange(SelectionChangeEvent event)
{
SomeType selected = model.getSelectedObject();
if (selected != null)
{
// Logic here...
model.clear();
}
}
});
But this solution obviously removes visual feedback what was selected.
You could add a DOM handler to your CellTree using [Widget.addDomHandler](http://www.gwtproject.org/javadoc/latest/com/google/gwt/user/client/ui/Widget.html#addDomHandler(H, com.google.gwt.event.dom.client.DomEvent.Type)):
cellTree.addDomHandler(new ClickHandler()
{
#Override
public void onClick(ClickEvent event)
{
// TODO: check if a node is selected and it was clicked here
}
}, ClickEvent.getType());
Additionally you might need to prevent calling the handler twice if you use the selection handler as well and click a node.
Just a side note: Unfortunately I did not see an easy way to determine if the user actually clicked on a tree item like a bounds check for the click coordinates. So this might get a bit harder to achieve.
Suppose I want to have my program to react same way, say, navigate to next record, in response to different events, including pressing a key, clicking GUI button, selecting menu item and so on.
This was done with "actions" in Swing.
Can I materialize this concept in some program object in JavaFX?
Or I should make a porridge of interacting objects?
Action is still there in JavaFX. Example belows how to create an action, bind it to a keyboard shortcut and share between two different elements.
Button go = new Button("Go");
EventHandler<ActionEvent> goAction = new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
browser.load(location.getText(), new Runnable() {
#Override
public void run() {
System.out.println("---------------");
System.out.println(browser.getHTML());
}
});
}
};
...
MenuItem menuItem = new MenuItem("Go!");
menuItem.setAccelerator(new KeyCodeCombination(KeyCode.G, KeyCombination.CONTROL_DOWN));
go.setOnAction(goAction);
menuItem.setOnAction(goAction);
JavaFX provides many events. You also do this with setOn() method:
button.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent t) {
// code here
}
});
I need to add a key listener to my TitelAreaDialog is there any solution to do this ?
You can add a Listener to the Display by using:
Listener listener = new Listener() {
public void handleEvent(Event event) {
System.out.println(event.character);
}
}
getShell().getDisplay().addFilter(SWT.KeyDown, listener);
This will output all pressed keys without consuming the events, i.e. the underlying widgets will still register the events.
Remember to remove it again in the close() method of the Dialog:
#Override
public boolean close()
{
getShell().getDisplay().removeFilter(SWT.KeyDown, listener);
super.close();
}