JavaFX MouseEvent
仅传递到不是鼠标透明的最顶层节点。我正在寻找一种将MouseEvent
传递到多个节点(鼠标是半透明的,也许是?)的方法。
在下面的示例中,我有2个部分重叠的圆圈。顶部的圆圈侦听MOUSE_CLICKED
事件以更改其颜色。底部的圆圈接收MOUSE_ENTERED
和MOUSE_EXITED
以更新其悬停属性,并在鼠标悬停于其上方时更改其颜色。
当顶部圆圈是鼠标透明的时,底部圆圈的行为符合预期,但是顶部圆圈不再接收MOUSE_CLICKED
事件。如果顶部圆圈不是鼠标透明的,则即使鼠标停留在底部圆圈的形状内,当鼠标经过顶部圆圈时,底部圆圈也会显示MOUSE_EXITED
。
是否可以同时支持两种行为?
public class MainApp extends Application {
private final Random RND = new Random();
@Override
public void start(Stage stage) throws Exception {
Circle bottomCircle = new Circle(150, 150, 100, Color.BLUE);
bottomCircle.fillProperty().bind(Bindings.when(bottomCircle.hoverProperty()).then(Color.AQUA).otherwise((Color.BLUE)));
Circle topCircle = new Circle(200, 100, 40, randColor());
topCircle.setOnMouseClicked((event) -> topCircle.setFill(randColor()));
CheckBox mouseTransparencyCheckBox = new CheckBox("Top Circle Mouse Transparency");
topCircle.mouseTransparentProperty().bind(mouseTransparencyCheckBox.selectedProperty());
Pane pane = new Pane();
pane.setPrefSize(300, 300);
pane.getChildren().addAll(mouseTransparencyCheckBox, bottomCircle, topCircle);
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
private Color randColor() {
return Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:1)
我通过一点数学就知道了。捕获发生在最上面的圈子的所有事件。如果事件是进入,移动或退出鼠标,请查看鼠标是否在底部圆圈内。
import java.util.Random;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.event.EventType;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
/**
*
* @author blj0011
*/
public class JavaFXApplication349 extends Application
{
private final Random RND = new Random();
Circle bottomCircle = new Circle(150, 150, 100, Color.BLUE);
Circle topCircle = new Circle(200, 100, 40, randColor());
MouseEvent enteredBottomCircle = new MouseEvent(MouseEvent.MOUSE_ENTERED, bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), MouseButton.NONE, 1, true, true, true, true, true, true, true, true, true, true, null);
MouseEvent exitedBottomCircle = new MouseEvent(MouseEvent.MOUSE_EXITED, bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), bottomCircle.getLayoutX(), bottomCircle.getLayoutY(), MouseButton.NONE, 1, true, true, true, true, true, true, true, true, true, true, null);
@Override
public void start(Stage stage) throws Exception
{
bottomCircle.fillProperty().bind(Bindings.when(bottomCircle.hoverProperty()).then(Color.AQUA).otherwise((Color.BLUE)));
topCircle.addEventHandler(EventType.ROOT, (event) -> {
System.out.println(event.getEventType());
if (event.getEventType() == MouseEvent.MOUSE_ENTERED || event.getEventType() == MouseEvent.MOUSE_MOVED || event.getEventType() == MouseEvent.MOUSE_EXITED) {
MouseEvent event1 = (MouseEvent) event;
if (Math.sqrt(Math.pow((event1.getSceneX() - bottomCircle.getCenterX()), 2) + Math.pow((event1.getSceneY() - bottomCircle.getCenterY()), 2)) < bottomCircle.getRadius()) {
System.out.println("entered bottom circle");
bottomCircle.fireEvent(enteredBottomCircle);
}
else {
System.out.println("exited bottom circle");
bottomCircle.fireEvent(exitedBottomCircle);
}
}
});
topCircle.setOnMouseClicked((event) -> topCircle.setFill(randColor()));
CheckBox mouseTransparencyCheckBox = new CheckBox("Top Circle Mouse Transparency");
topCircle.mouseTransparentProperty().bind(mouseTransparencyCheckBox.selectedProperty());
Pane pane = new Pane();
pane.setPrefSize(300, 300);
pane.getChildren().addAll(mouseTransparencyCheckBox, bottomCircle, topCircle);
Scene scene = new Scene(pane);
stage.setScene(scene);
stage.show();
}
private Color randColor()
{
return Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
}
public static void main(String[] args)
{
launch(args);
}
}