3

java8内でjavafxを使用するプロジェクトに取り組んでいます。ボタン (javafx.scene.control.Button) と別のペインを含む (javafx.scene.layout.Pane クラスの) パネル。マウスクリックイベントが親にバブルアップされることを期待しています。しかし、これはペインをクリックした場合にのみ発生し、ボタンをクリックした場合には発生しません。以下は、この動作の非常に単純な例のコードです。この問題を解決するための提案はありますか? ペインに基づいて独自のボタンを作成できることはわかっていますが、これは厄介な回避策です。乾杯

    package application;

    import javafx.animation.TranslateTransition;
    import javafx.application.Application;
    import javafx.event.Event;
    import javafx.event.EventHandler;
    import javafx.stage.Stage;
    import javafx.scene.Scene;
    import javafx.scene.control.Button;
    import javafx.scene.image.Image;
    import javafx.scene.image.ImageView;
    import javafx.scene.layout.BorderPane;
    import javafx.scene.layout.Pane;
    import javafx.util.Duration;


    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);

                root.setTop(p);

                p.setOnMouseClicked(new EventHandler<Event>() {

                    @Override
                    public void handle(Event event) {
                        System.out.println("event source " + event.getSource() + " target : " + event.getTarget());

                    }
                });

                primaryStage.setScene(scene);
                primaryStage.show();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }

        public static void main(String[] args) {
            launch(args);
        }
    }
4

2 に答える 2

9

デフォルトでは、ボタンはマウス クリック イベントを消費しますが、ペインは消費しません。

親ペインのイベント ハンドラーを使用してボタン マウスのクリックをインターセプトする場合は、イベント フィルターを使用する必要があります (バブリング フェーズではなくキャプチャ フェーズでイベントをインターセプトするため)。

キャプチャとバブリングの概念を理解する必要がある場合は、イベント処理について読んでください。

于 2014-05-21T08:57:08.327 に答える
1

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);
            }  
        }
    }
于 2014-05-21T12:00:40.613 に答える