I have list of stackPanes on which different fxmls are loaded. So i want to know which of the stackPane is in interactive with user. For example, if a event occurs on a fxml, then stackPane should be notified abt this event. I added mouse click event to the stackPane, but its not triggering everytime.
stackPane.setOnMouseClicked( new EventHandler<MouseEvent>(){
#Override
public void handle( MouseEvent event ){
setSelectedPane( (Pane) event.getSource() );
}
} );
Related
Is there a way to process click event in cell's widget?
I implemented custom complex cell with text and image. Wrap it with FocusPanel and declare a click handler. But CellTable and CellList intercept all events.
There is a way of doing it directly, no wrapping:
table.addCellPreviewHandler(new Handler<MyObject>() {
#Override
public void onCellPreview(CellPreviewEvent<MyObject> event) {
if ("click".equals(event.getNativeEvent().getType())) {
// do something with a click, using event.getColumn(),
// event.getIndex() and event.getValue() as necessary
}
}
});
I need to get an event fired after clicking on a grid cell. It works but fires multiple events.
My Code:
private void gridClickHandler(final boolean cardDeterminer) {
gridClickHandler = new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
int cellIndex = view.getGrid().getCellForEvent(event)
.getCellIndex(); // get clicked cell of grid
if (cardDeterminer)
oasisCardRPC(cellIndex); //rpc based on clicked cell
else
desertCardRPC(cellIndex); //rpc based on clicked cell
}
};
view.getGrid().addClickHandler(gridClickHandler);
}
The method gridClickHandler is called in an onSuccess of a RPC and calls a new RPC using a boolean passed. (it works like this: click on some widget, when success then click on grid. Grid should only fire event, when this some widget was clicked directly before)
I don't know how to create a new ClickHandler only once for the grid and still make its clickHandler only fire events, when needed.
Thanks in advance!
Use a boolean : isClickHandlerAttached
Initially false, first time you add the clickhandler put it on true. Only attach if boolean is false.
I am attempting to create a "workspace" where users can open several containers to display distinct information. These need to be moveable and sizeable (ScrollPane for example).
I have successfully created the majority of the functionality - however one thing is really causing me issues and I am not able to figure out the issue.
I created the following class:
public class WorkspaceMoveableSizeablePane extends Pane
public WorkspaceMoveableSizeablePane(Node view) {
getChildren().add(view);
init();
}
private void init() {
...set up the event handlers....
I attempt to use this pane by wrapping an existing pane like so in my WorkspaceController:
#FXML private openSampleWorkspaceNode() {
FXMLLoader loader = new FXMLLoader();
Parent node = loader.load(
this.getClass().getResource("MyView.fxml").openStream());
WorkspaceMoveableSizeablePane dn = new WorkspaceMoveableSizeablePane(node);
pane.getChildren().add(dn);
}
When I open it this way - I can size my Pane and drag it, however the children on the "node" which is an anchor pane stay in their current positions rather than get hidden.
To correct this issue, I wrapped the AnchorPane in a ScrollPane in the FXML file. This allowed the resize to happen - and as expected the portions out of bounds were not visible and the scrollbars appeared, however the drag stopped. When I attempted to track the mouse dragged event, it actually didn't fire unless I was resizing the WorkspaceMoveableSizeablePane.
//Event Listener for MouseDragged
onMouseDraggedProperty().set(event -> {
System.out.println("You are in the Mouse Dragged Event");
if(isTopSelected){
dragPaneToNewLocation(event);
}else if(isResizingHeight) {
handleResizeHeight(event);
}else if(isResizingWidth) {
handleResizeWidth(event);
}
});
I reverted my FXML to AnchorPane and changed the WorkspaceMoveableSizeablePane as follows to see if that would help:
public class WorkspaceMoveableSizeablePane extends ScrollPane
public WorkspaceMoveableSizeablePane(Node view) {
setContent(view);
init();
}
private void init() {
...set up the event handlers....
As before the resize worked, but the drag didn't. The mouse dragged event never fired. Additionally, my scroll pane was blank with nothing in it.
So I am at a loss on how to proceed with this attempt.
Is there a limitation on the event handlers of the ScrollPane? Is there a different event I should be listening for? Thanks!!
The issue was that the ScrollPane was trapping the MouseDragged event.
Added an Event Filter and all is good...
addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
if(isTopSelected){
dragPaneToNewLocation(event);
}else if(isResizingHeight) {
handleResizeHeight(event);
}else if(isResizingWidth) {
handleResizeWidth(event);
}
});
My challenge is following situation:
I want to add an invisible (opacity 0) pane over the whole application, which receives all mouse and touch events. When an event occurs it resets some kind of activity timer.
My first approach (without such pane) was adding listeners to the root pane, which worked pretty well. But... the buttons consume all events, so the timer does not get reset.
In my opinion, the glasspane solution would be a much more nicer solution, but I can't find a solution to forward received mouse and touch events to the underlying controls.
In short: the pane intercepts a mouse event (trigger to reset timer), and the underlying button gets clicked.
Any ideas please?
EDIT first solution
I came to the solution to add an EventDispatcher to my root pane, which fires an custom event, when e.g. a mouse was pressed. So no glasspane, but it works:
//this == myRootPane
final EventDispatcher originalDispatcher = this.getEventDispatcher();
EventDispatcher dispatcher = new EventDispatcher() {
#Override
public Event dispatchEvent(Event event, EventDispatchChain tail) {
if(timeoutResetEventHdlr != null) {
if(event instanceof MouseEvent) {
if(event.getEventType().equals(MouseEvent.MOUSE_PRESSED)) {
timeoutResetEventHdlr.handle(new PageTimeoutResetEvent());
}
}
}
originalDispatcher.dispatchEvent(event, tail);
return event;
}
};
this.setEventDispatcher(dispatcher);
Don't use a glass pane or muck around with the event dispatcher, use an event filter on the scene.
Filters are triggered in the event capturing phase, rather than the event bubbling phase, so you can intercept the event and take some action on it before the underlying controls consume the event.
I have a CellTable with ClickableCell. When I click on it, a popup opens and show the clicked cell table as exepected. The CellTable is added in a AbsolutePanel(Parent).
For some developpment, an another AbsolutePanel(Over) is located over the CellTable.
How can I propagate the AbsolutePanel(Over) click event on the celltable ?
I had an handler on the AbsolutePanelHandler(Over) and fired the clicked event :
absolutePanelOver.addDomHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
NativeEvent nativeEvent = Document.get().createClickEvent(0, -event.getScreenX(), event.getScreenY(),
event.getClientX(), event.getClientY(), event.isControlKeyDown(), event.isAltKeyDown(),
event.isShiftKeyDown(), event.isMetaKeyDown());
DomEvent.fireNativeEvent(nativeEvent, cellTable);
}
}, ClickEvent.getType());
Unfortunately the popup cell table is not shown. But I know that the cellTable handles the event.
Regards
Maybe I did not understand your question, but the solution seems to be much simpler.
absolutePanelOver.addDomHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
doSomething();
}
}, ClickEvent.getType());
In your CellTable you invoke the same doSomething() method when a cell is clicked. Now it does not matter whether a cell or an absolute panel is clicked - the same method will be executed.