JavaFX - стек-панель с панелью в качестве EventDispatcher - PullRequest
0 голосов
/ 31 декабря 2018

В панели диспетчера событий происходит событие нажатия мыши.На панели должно отображаться контекстное меню его выпадающего списка, когда происходит событие.

Это прекрасно работает, если событие подключено только к первой панели.Когда событие связано с первой и второй панелями, контекстное меню первой панели не отображается.Я предполагаю, что это как-то связано с хвостом события и потреблением события.

До сих пор я не смотрел на класс EventDispatcher самого JDK.

Вот что я получилдо сих пор:

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

}

Есть идеи, как с этим справиться?

1 Ответ

0 голосов
/ 01 января 2019

После некоторых идей я получил решение, которое, по крайней мере, работает:

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

}

Возможно, лучший подход придет во время кого-то еще.С нетерпением жду ...

...