Adding mouse event for secondary mouse button Javafx - java

so i have this anchorpane where i wish to add a mouse listner for the Secondary mouse key ive tried the following but i keep getting an error anyone know what the problem is?
mainDisplayPanel.addEventHandler(MouseButton.SECONDARY, new EventHandler<MouseButton>() {
#Override
public void handle(MouseButton event) {
System.out.Println("Works");
}
});
for the record i have also tried this:
mainDisplayPanel.addEventHandler(MouseButton.SECONDARY, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
System.out.println("WOrks");
}
});
Stack trace:
Bound mismatch: The generic method addEventHandler(EventType,
EventHandler) of type Node is not applicable for the
arguments (MouseButton, new EventHandler(){}). The
inferred type MouseButton&Event is not a valid substitute for the
bounded parameter
And the other:
Bound mismatch: The type MouseButton is not a valid substitute for the bounded parameter of the type EventHandler

There is no EventType based on MouseButton.SECONDARY. You need to check the MouseEvent itself:
mainDisplayPanel.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if (event.getButton() == MouseButton.SECONDARY) {
System.out.println("Works");
}
}
});

Related

How can I write my code more efficiently for use with different types of JavaFX GUI components?

I am making a basic JavaFX GUI, where I would like a label to change when I am hovering over different types of GUI components.
For example below, I want my label to change text from 'Bored' to 'Hovered!' when I hover over either a ComboBox, TextField, Button, Circle etc
Instead of repeating the same code over again, I am guessing I could create a method with the object as the input argument, but I can't seem to quite get it right.
Essentially, is there an elegant way I can adapt this code so that it can be reusable for all types of different JavaFX GUI components?
The following code currently does exactly what I describe, but is something that I would like to be more efficient.
Thanks.
comboBox.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.HAND);
label.setText("Hovered!");
}
});
comboBox.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.MOVE);
label.setText("Bored");
}
});
textField.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.HAND);
label.setText("Hovered!");
}
});
textField.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.MOVE);
label.setText("Bored");
}
});
button.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.HAND);
label.setText("Hovered!");
}
});
button.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.MOVE);
label.setText("Bored");
}
});
circle.setOnMouseEntered(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.HAND);
label.setText("Hovered!");
}
});
circle.setOnMouseExited(new EventHandler<MouseEvent>() {
#Override public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.MOVE);
label.setText("Bored");
}
});
You can easily use a helper method to register all those listeners. Furthermore you can reuse the listeners, since they contain the same code for all of the nodes:
private static void registerListeners(final Label label, Node... nodes) {
final EventHandler<MouseEvent> enteredHandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.HAND);
label.setText("Hovered!");
}
};
final EventHandler<MouseEvent> exitedHandler = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
label.setCursor(Cursor.MOVE);
label.setText("Bored");
}
};
// add listeners to all nodes
for (Node n : nodes) {
n.setOnMouseEntered(enteredHandler);
n.setOnMouseExited(exitedHandler);
}
}
registerListeners(label, comboBox, textField, button);
Note that you cannot handle the MOUSE_ENTERED and the MOUSE_EXITED event on a parent node, since the event is not passed through the hierarchy. The only way to make this work for arbitrary children would be to handle the MOUSE_MOVED event on the parent. In this case you cannot be sure the intersected node is one of the nodes you want to allow. It could be a child. Therefore you need to iterate through the hierarchy yourself:
commonAncestor.setOnMouseEntered(evt -> {
Node n = evt.getPickResult().getIntersectedNode();
while (n != commonAncestor) {
if (checkNode(n)) {
label.setCursor(Cursor.HAND);
label.setText("Hovered!");
return;
}
n = n.getParent();
}
label.setCursor(Cursor.MOVE);
label.setText("Bored");
});
I don't really know if this was the best answer. But you can try this:
#Override
public void initialize(URL location, ResourceBundle resources) {
combobox.setOnMouseEntered(this);
combobox.setOnMouseExited(this);
textfield.setOnMouseEntered(this);
textfield.setOnMouseExited(this);
button.setOnMouseEntered(this);
button.setOnMouseExited(this);
}
#Override
public void handle(MouseEvent event) {
switch (event.getEventType().getName()){
case "MOUSE_ENTERED":
label.setCursor(Cursor.HAND);
label.setText("Hovered!");
break;
case "MOUSE_EXITED":
label.setCursor(Cursor.MOVE);
label.setText("Bored");
break;
}
}
Your controller must implement EventHandler

JavaFX button not responding on first click

public void handle(){
submit.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
LoginConnection login = new LoginConnection();
boolean pass = login.login(usernameField.getText(), passwordField.getText());
if(pass)
flip(SceneNames.Main);
else
invalLoginMessage.setOpacity(1.00);
}
});
register.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
flip(SceneNames.Register);
}
});
}
When i click on submit or register, it takes two click for it to do anything. How do i fix this?
What happens is that on first click it adds the handlers specified in the method and on second and consecutive clicks, it uses the handlers. To fix it just create separate methods to add through fxml or scene builder.

JavaFx: Access an object from Event handler

I want to make a program in JavaFX that contains a button which, when clicked, a circle gets created and added to an ArrayList of shapes. The following is my code:
createCircleBtn.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
Circle circle1 = new Circle();
shapes.add(circle1);
circle1.setCenterX(event.getX());
circle1.setCenterY(event.getY());
circle1.setOnMouseDragged(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
// doesn't work because "circle1" must be declared final (constant)
circle1.setCenterX(event.getX());
// "this" doesn't refer to "circle1"
this.setCenterY(event.getY());
}
});
mainPane.getChildren().add(circle1);
}
});
My question is - How can I access "circle1" from inside handle method?
In JavaScript we use e.currentTarget.
I'm unable to declare "circle1" final because I will need to change it afterwards.
Nowhere in the code you show do you reassign circle1, so you can just declare it as final:
createCircleBtn.setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
final Circle circle1 = new Circle();
shapes.add(circle1);
circle1.setCenterX(event.getX());
circle1.setCenterY(event.getY());
circle1.setOnMouseDragged(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
circle1.setCenterX(event.getX());
}
});
mainPane.getChildren().add(circle1);
}
});
Note that in Java 8 your code would compile just as you have it, because circle1 is effectively final (meaning that it is only assigned once and is never reassigned).
Use event.getSource(), by this can write a common event handler for multiple cicrles without worrying which exact one was clicked:
EventHandler<MouseEvent> handler = new EventHandler<>()
{
#Override
public void handle( MouseEvent event )
{
if (event.getSource() instanceof Circle) { // to be on safe side, you may
// remove this if-statement
// if you are sure
Circle c = (Circle) event.getSource();
c.setCenterX( event.getX() );
}
}
};
// use it on multiple circles
circle1.setOnMouseDragged(handler);
circle2.setOnMouseDragged(handler);
...
circleN.setOnMouseDragged(handler);

chartMouseListener and MouseListener

Why at first works chartMouseClicked (JFreeChart library), and already then mouseClicked?
boolean isDoubleClicked = false;
chartPanel.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent me) {
if (me.getClickCount() == 2 &&) {
isDoubleClicked = true;
}
}
#Override
public void mousePressed(MouseEvent me) {}
#Override
public void mouseReleased(MouseEvent me) {}
#Override
public void mouseEntered(MouseEvent me) {}
#Override
public void mouseExited(MouseEvent me) {}
});
chartPanel.addChartMouseListener(new ChartMouseListener() {
#Override
public void chartMouseClicked(ChartMouseEvent cme) {
if (isDoubleClicked)
System.out.println("Double clicked!");
}
#Override
public void chartMouseMoved(ChartMouseEvent cme) {}
});
So, System.out.println("Double clicked!"); not works. How to correct it?
You have two different listener objects here, one is a MouseListener instance (that listens to mouse events on the panel) and the other is a ChartMouseListener instance (that listens to mouse events on the chart in the panel). They are registered in separate listener lists, and the isDoubleClicked field from one object isn't visible to the other object.
The reason that ChartMouseListener is separate from MouseListener is that JFreeChart creates its own events that contain additional information about the entity in a chart that is "underneath" the mouse pointer.
To add up on #DavidGilbert, you can also use ChartMouseEvent.getTrigger().getClickCount() to detect double-click in the chart.

Adding click event to JavaFX TableCell

I have TableView and I want my program to doSomething() when user clicks on a cell. After searching on Internet (stackoverflow included), I found this.
Tried that method, but I got a compile error on these code :
EventHandler click = new EventHandler() {
public void handle(MouseEvent t) {
System.out.println("CLICKED");
}
};
NetBeans asked me to override all abscract method, so I did it.
EventHandler click = new EventHandler() {
#Override
public void handle(MouseEvent t) {
System.out.println("CLICKED");
}
};
Still got same error :
error: method does not override or implement a method from a supertype
If I remove #Override annotation, I got :
error: <anonymous pengamatan.penginderaan.FXMLDocumentController$4> is not abstract and does not override abstract method handle(Event) in EventHandler
Any help? Thank you.
You can try:
cell.addEventFilter(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
System.out.println("cell clicked!");
}
});
found here
Found the solution! Here is the code :
....
import javafx.scene.input.MouseEvent;
....
....
EventHandler click = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent t) {
if(t.getClickCount()>1) {
System.out.println("DOUBLE CLICK");
}
}
};
....
Hope it helps. Thank you.

Categories