Events JavaFx按钮事件冒泡
我正在从事一个在java8中使用javafx的项目。 我关注了一个奇怪的情况: 一个面板(属于javafx.scene.layout.Pane类),包含一个按钮(javafx.scene.control.button)和另一个窗格。我希望一个鼠标点击事件会被弹出到父级。但这只是我单击窗格时的情况,而不是单击按钮时的情况。下面是一个具有此行为的非常简单示例的代码。有人有解决这个问题的建议吗?我知道我可以基于窗格创建自己的按钮。。但这只是一个令人讨厌的解决办法。 干杯Events JavaFx按钮事件冒泡,events,button,javafx,pane,Events,Button,Javafx,Pane,我正在从事一个在java8中使用javafx的项目。 我关注了一个奇怪的情况: 一个面板(属于javafx.scene.layout.Pane类),包含一个按钮(javafx.scene.control.button)和另一个窗格。我希望一个鼠标点击事件会被弹出到父级。但这只是我单击窗格时的情况,而不是单击按钮时的情况。下面是一个具有此行为的非常简单示例的代码。有人有解决这个问题的建议吗?我知道我可以基于窗格创建自己的按钮。。但这只是一个令人讨厌的解决办法。 干杯 包应用; 导入javafx.a
包应用;
导入javafx.animation.TranslateTransition;
导入javafx.application.application;
导入javafx.event.event;
导入javafx.event.EventHandler;
导入javafx.stage.stage;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.image.image;
导入javafx.scene.image.ImageView;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.Pane;
导入javafx.util.Duration;
公共类主扩展应用程序{
双刻度;
@凌驾
公共无效开始(阶段primaryStage){
试一试{
BorderPane根=新的BorderPane();
场景=新场景(根,400400);
scene.getStylesheets().add(getClass().getResource(“application.css”).toExternalForm());
按钮btn=新按钮(“测试”);
btn.设置布局X(50);
窗格p2=新窗格();
p2.setPrefSize(20,20);
p2.设置样式(“-fx背景色:#440000”);
窗格p=新窗格();
p、 getChildren().add(btn);
p、 getChildren().add(p2);
根.立顶(p);
p、 setOnMouseClicked(新事件处理程序(){
@凌驾
公共无效句柄(事件){
System.out.println(“事件源”+event.getSource()+“目标”+event.getTarget());
}
});
初级阶段。场景(场景);
primaryStage.show();
}捕获(例外e){
e、 printStackTrace();
}
}
公共静态void main(字符串[]args){
发射(args);
}
}
默认情况下,按钮将使用鼠标单击事件,而窗格将不会
如果要使用父窗格事件处理程序截获按钮鼠标单击,则应使用来截获(在捕获阶段而不是冒泡阶段截获事件)
如果您需要了解捕获与冒泡的概念,请仔细阅读。多亏了jewelsea的回答,我想出了这个工作示例:
package application;
import com.oracle.jrockit.jfr.EventToken;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.event.EventType;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Main extends Application {
double curScale;
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
Button btn = new Button("test");
btn.setLayoutX(50);
Pane p2 = new Pane();
p2.setPrefSize(20,20);
p2.setStyle("-fx-background-color: #440000");
Pane p = new Pane();
p.getChildren().add(btn);
p.getChildren().add(p2);
Pane p3 = new Pane();
p3.getChildren().add(p);
root.setTop(p3);
p3.setOnMouseClicked(new EventHandler<Event>() {
@Override
public void handle(Event event) {
System.out.println("top pane got the clicked event");
}
});
// Define an event filter
EventHandler filter = new EventHandler<Event>() {
@Override
public void handle(Event event) {
System.out.println("Filtering out event " + event.getEventType() + " source " + event.getSource() + " target " + event.getTarget());
Node node = (Node) event.getTarget();
try{
Button b = (Button)event.getSource();
node.fireEvent(new MyEvent( b.getText() ));
}catch(Exception e){
node.fireEvent(new MyEvent( "pane" ));
}
event.consume();
}
};
btn.addEventFilter(MouseEvent.MOUSE_CLICKED, filter);
p2.addEventFilter(MouseEvent.MOUSE_CLICKED, filter);
p.addEventHandler(MyEvent.BUTTON_PRESSED, new MyEventHandler());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
// The Handler
class MyEventHandler implements EventHandler<MyEvent> {
@Override
public void handle(MyEvent event) {
System.out.println("MyEvent " + event.data);
}
}
// The Event
static class MyEvent extends Event {
public final static EventType<MyEvent> BUTTON_PRESSED = new EventType(ANY, "BUTTON_PRESSED");
public String data;
public MyEvent() {
this(BUTTON_PRESSED);
}
public MyEvent(String what){
this(BUTTON_PRESSED);
data = what;
}
public MyEvent(EventType<? extends Event> arg0) {
super(arg0);
}
public MyEvent(Object arg0, EventTarget arg1, EventType<? extends Event> arg2) {
super(arg0, arg1, arg2);
}
}
}
包应用;
导入com.oracle.jrockit.jfr.EventToken;
导入javafx.application.application;
导入javafx.event.event;
导入javafx.event.EventHandler;
导入javafx.event.EventTarget;
导入javafx.event.EventType;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.input.MouseEvent;
导入javafx.scene.layout.BorderPane;
导入javafx.scene.layout.Pane;
导入javafx.stage.stage;
公共类主扩展应用程序{
双刻度;
@凌驾
公共无效开始(阶段primaryStage){
试一试{
BorderPane根=新的BorderPane();
场景=新场景(根,400400);
scene.getStylesheets().add(getClass().getResource(“application.css”).toExternalForm());
按钮btn=新按钮(“测试”);
btn.设置布局X(50);
窗格p2=新窗格();
p2.setPrefSize(20,20);
p2.设置样式(“-fx背景色:#440000”);
窗格p=新窗格();
p、 getChildren().add(btn);
p、 getChildren().add(p2);
窗格p3=新窗格();
p3.getChildren().add(p);
根。setTop(p3);
p3.setOnMouseClicked(新的EventHandler(){
@凌驾
公共无效句柄(事件){
System.out.println(“顶部窗格获得点击事件”);
}
});
//定义一个事件过滤器
EventHandler筛选器=新的EventHandler(){
@凌驾
公共无效句柄(事件){
System.out.println(“过滤出事件”+event.getEventType()+“源”+event.getSource()+“目标”+event.getTarget());
Node Node=(Node)event.getTarget();
试一试{
按钮b=(按钮)事件.getSource();
firevent(新的MyEvent(b.getText());
}捕获(例外e){
node.firevent(新的MyEvent(“窗格”);
}
event.consume();
}
};
btn.addEventFilter(鼠标点击MouseEvent.MOUSE_,过滤);
p2.addEventFilter(鼠标点击MouseEvent.MOUSE_,过滤);
p、 addEventHandler(按下MyEvent.BUTTON_,新建MyEventHandler());
初级阶段。场景(场景);
primaryStage.show();
}捕获(例外e){
e、 printStackTrace();
}
}
公共静态void main(字符串[]args){
发射(args);
}
//处理者
类MyEventHandler实现EventHandler{
@凌驾
公共无效句柄(MyEvent事件){
System.out.println(“MyEvent”+事件数据);
}
}
//事件
静态类MyEvent扩展事件{
公共最终静态事件类型按钮
package application;
import com.oracle.jrockit.jfr.EventToken;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.event.EventTarget;
import javafx.event.EventType;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Main extends Application {
double curScale;
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,400,400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
Button btn = new Button("test");
btn.setLayoutX(50);
Pane p2 = new Pane();
p2.setPrefSize(20,20);
p2.setStyle("-fx-background-color: #440000");
Pane p = new Pane();
p.getChildren().add(btn);
p.getChildren().add(p2);
Pane p3 = new Pane();
p3.getChildren().add(p);
root.setTop(p3);
p3.setOnMouseClicked(new EventHandler<Event>() {
@Override
public void handle(Event event) {
System.out.println("top pane got the clicked event");
}
});
// Define an event filter
EventHandler filter = new EventHandler<Event>() {
@Override
public void handle(Event event) {
System.out.println("Filtering out event " + event.getEventType() + " source " + event.getSource() + " target " + event.getTarget());
Node node = (Node) event.getTarget();
try{
Button b = (Button)event.getSource();
node.fireEvent(new MyEvent( b.getText() ));
}catch(Exception e){
node.fireEvent(new MyEvent( "pane" ));
}
event.consume();
}
};
btn.addEventFilter(MouseEvent.MOUSE_CLICKED, filter);
p2.addEventFilter(MouseEvent.MOUSE_CLICKED, filter);
p.addEventHandler(MyEvent.BUTTON_PRESSED, new MyEventHandler());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
// The Handler
class MyEventHandler implements EventHandler<MyEvent> {
@Override
public void handle(MyEvent event) {
System.out.println("MyEvent " + event.data);
}
}
// The Event
static class MyEvent extends Event {
public final static EventType<MyEvent> BUTTON_PRESSED = new EventType(ANY, "BUTTON_PRESSED");
public String data;
public MyEvent() {
this(BUTTON_PRESSED);
}
public MyEvent(String what){
this(BUTTON_PRESSED);
data = what;
}
public MyEvent(EventType<? extends Event> arg0) {
super(arg0);
}
public MyEvent(Object arg0, EventTarget arg1, EventType<? extends Event> arg2) {
super(arg0, arg1, arg2);
}
}
}