【问题标题】:JavaFX - StackPane with Pane as EventDispatcherJavaFX - 将窗格作为 EventDispatcher 的 StackPane
【发布时间】:2018-12-31 14:31:57
【问题描述】:

在事件调度程序窗格中发生鼠标按下事件。 当事件发生时,窗格应显示其组合框的上下文菜单。

如果仅将事件分配到窗格之一,则效果很好。 当事件被分配到窗格一和窗格二时,窗格一的上下文菜单不会显示。 我想这与事件尾部和事件消耗有关。

到目前为止,我还没有看过 JDK 本身的 EventDispatcher 类。

这是我目前得到的:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

/**
 *
 * @author Robert
 */
public class EventDispatcherExample extends Application {

    private Group root;
    private StackPane cStackPane;
    private Pane cPaneEventDispatcher;
    private Pane cPaneOne;
    private ComboBox cComboBox;
    private Pane cPaneTwo;

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

    @Override
    public void start(Stage primaryStage) throws Exception {
        root = new Group();

        cStackPane = new StackPane();
        cStackPane.setPrefHeight(200.0);
        cStackPane.setPrefWidth(200.0);

        cPaneEventDispatcher = new Pane();
        cPaneEventDispatcher.setPrefHeight(200.0);
        cPaneEventDispatcher.setPrefWidth(200.0);
        cPaneEventDispatcher.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                //System.out.println("Mouse pressed in Pane ED.");
                cPaneOne.fireEvent(event);
                cPaneTwo.fireEvent(event);
            }
        });

        cPaneOne = new Pane();
        cPaneOne.setPrefHeight(200.0);
        cPaneOne.setPrefWidth(200.0);
        cPaneOne.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                //System.out.println("Mouse pressed in Pane One.");
                cComboBox.show();
            }

        });
        ObservableList<String> observableList = FXCollections.observableArrayList();
        observableList.add("1");
        observableList.add("2");
        observableList.add("3");
        cComboBox = new ComboBox();
        cComboBox.setLayoutX(50.0);
        cComboBox.setLayoutY(50.0);
        cComboBox.setPrefHeight(30.0);
        cComboBox.setPrefWidth(100.0);
        cComboBox.setItems(observableList);

        cPaneTwo = new Pane();
        cPaneTwo.setPrefHeight(200.0);
        cPaneTwo.setPrefWidth(200.0);
        cPaneTwo.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                //System.out.println("Mouse pressed in Pane Two.");
                //Something will happen because of selected item in Combo Box of pane one...
            }
        });

        cPaneOne.getChildren().add(cComboBox);
        // add the nodes in reverse order
        cStackPane.getChildren().add(cPaneTwo);
        cStackPane.getChildren().add(cPaneOne);
        cStackPane.getChildren().add(cPaneEventDispatcher);
        root.getChildren().add(cStackPane);

        Scene scene = new Scene(root, 200, 200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

}

任何想法如何处理这个?

【问题讨论】:

  • 问题是你转发鼠标按下事件的顺序。当弹出菜单(如ComboBox 所示的内容)显示时,当鼠标在场景/屏幕的其他位置按下时,它会被隐藏。如果您在ComboBox 周围翻转cPaneOne.fireEventcPaneTwo.fireEvent,则鼠标按下后应该会显示。
  • 感谢您的解释。我已经尝试过翻转选项,它也可以工作,但它不能满足我的需求。更准确地说:未来的目标是当按下窗格一中的组合框时,应将事件过滤器添加到窗格二。释放组合框时,应从窗格二中删除事件过滤器。如果在第一个窗格中的组合框之外发生交互,则使用上述事件过滤器描述的逻辑应该是无效的。将窗格窗格一映像为多个控件的容器,这些控件设置窗格二的不同属性。

标签: javafx event-dispatching


【解决方案1】:

经过一些想法,我得到了一个至少可行的解决方案:

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

/**
 *
 * @author Robert
 */
public class EventDispatcherExample extends Application {

    private Group root;
    private StackPane cStackPane;
    private Pane cPaneEventDispatcher;
    private Pane cPaneOne;
    private ComboBox cComboBox;
    private boolean cComboBoxClicked = false;
    private Pane cPaneTwo;

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

    public boolean isComboBoxClicked() {
        if (cComboBoxClicked == true) {
            cComboBox.show();
        } else {
            cComboBox.hide();
        }
        return cComboBoxClicked;
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        root = new Group();

        cStackPane = new StackPane();
        cStackPane.setPrefHeight(200.0);
        cStackPane.setPrefWidth(200.0);

        cPaneEventDispatcher = new Pane();
        cPaneEventDispatcher.setPrefHeight(200.0);
        cPaneEventDispatcher.setPrefWidth(200.0);
        cPaneEventDispatcher.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                //System.out.println("Mouse pressed in Pane ED.");
                cPaneOne.fireEvent(event);
                cPaneTwo.fireEvent(event);
            }
        });

        cPaneOne = new Pane();
        cPaneOne.setPrefHeight(200.0);
        cPaneOne.setPrefWidth(200.0);
        cPaneOne.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                //System.out.println("Mouse pressed in Pane One.");

                Rectangle rect = new Rectangle(cComboBox.getLayoutX(), cComboBox.getLayoutY(),
                        cComboBox.getPrefWidth(), cComboBox.getPrefHeight());
                cComboBoxClicked = rect.contains(event.getX(), event.getY());
            }
        });

        ObservableList<String> observableList = FXCollections.observableArrayList();
        observableList.add("1");
        observableList.add("2");
        observableList.add("3");
        cComboBox = new ComboBox();
        cComboBox.setLayoutX(50.0);
        cComboBox.setLayoutY(50.0);
        cComboBox.setPrefHeight(30.0);
        cComboBox.setPrefWidth(100.0);
        cComboBox.setItems(observableList);

        cComboBox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                // if cComboBoxSelectedIndex == 1 do Color on pane two
                // if cComboBoxSelectedIndex == 2 do Size on pane two
                // if cComboBoxSelectedIndex == 3 do ...
                //System.out.println("newValue " + newValue);
            }
        });

        cPaneTwo = new Pane();
        cPaneTwo.setPrefHeight(200.0);
        cPaneTwo.setPrefWidth(200.0);
        cPaneTwo.setOnMousePressed(new EventHandler<MouseEvent>() {
            @Override
            public void handle(MouseEvent event) {
                //System.out.println("Mouse pressed in Pane Two.");

                boolean cComboBoxClicked = isComboBoxClicked();
                if (cComboBoxClicked){
                    //System.out.println("Skip code internally managed by pane two.");
                    return;
                }

                // Internal code of pane two
                //...
            }
        });

        cPaneOne.getChildren().add(cComboBox);
        // add the nodes in reverse order
        cStackPane.getChildren().add(cPaneTwo);
        cStackPane.getChildren().add(cPaneOne);
        cStackPane.getChildren().add(cPaneEventDispatcher);
        root.getChildren().add(cStackPane);

        Scene scene = new Scene(root, 200, 200);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

}

也许在其他人的时间里会出现更好的方法。 期待……

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-04
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多