JavaFx Перекрывающиеся события мыши - PullRequest
0 голосов
/ 30 декабря 2018

Я пытаюсь создать интерфейс настольной игры, где пользователь может переключаться между несколькими эпохами, каждая из которых имеет свою собственную доску.Для этого я создаю 4 разные платы, каждая на своей панели, и переключаю видимость узлов и отключаю неиспользуемые узлы.У меня проблема с обработчиками событий мыши, которые я использую, чтобы увидеть, где пользователь нажимает только на верхний слой, последний, который был обработан.Обработчики событий внизу не работают, даже если они включены.Вот что я написал:

static EventHandler<MouseEvent> eventMouseClickRoad = new EventHandler<MouseEvent>() { 
    @Override 
    public void handle(MouseEvent e) { 
        final Shape innerShape = (Shape) (e.getTarget());
        System.out.println("click");
        Color color = (Color) innerShape.getFill();
        if(color.getOpacity() != 1)
        {
            innerShape.setFill(Color.RED);
            //and do the data treatment
        }
    }
}; 


public void boardControler(Vector2DList sideList,PointList hexEdge,Pane groupPane,float scaleX, float scaleY, float buttonSize)
{
    //set road button
    for(Vector2D v : sideList.getVectorList()){
    Path mypath = new Path(new MoveTo(v.getP1().getX(),v.getP1().getY()),new LineTo(v.getP2().getX(),v.getP2().getY()));
    groupPane.getChildren().add(mypath);
    }
    for(Vector2D v : sideList.getVectorList()){
        float midX=(v.getP1().getX()+v.getP2().getX())/2;
        float diffY=v.getP1().getY()-v.getP2().getY();
        float diffX=v.getP1().getX()-v.getP2().getX();
        Rectangle rectangle = new Rectangle(midX-buttonSize/2,midY-Math.abs(diffY)+buttonSize+(Math.abs(diffY)-scaleY/4),buttonSize,(scaleY/2)-(buttonSize*2));
        rectangle.setRotate(Math.toDegrees(Math.atan(diffY/diffX))+90);
        rectangle.setFill(Color.TRANSPARENT);
        rectangle.addEventFilter(MouseEvent.MOUSE_ENTERED, Event.eventMouseEntered);
        rectangle.addEventFilter(MouseEvent.MOUSE_EXITED, Event.eventMouseExit);
        rectangle.addEventFilter(MouseEvent.MOUSE_CLICKED, Event.eventMouseClickRoad);
        groupPane.getChildren().add(rectangle);
    }
}

И это то, что я использую для переключения используемой платы: отключить

for(Node n : groupPane2.getChildren())
{
    n.setDisable(true);
    n.setManaged(false);
    n.setVisible(false);
}

, чтобы включить

for(Node n : groupPane2.getChildren())
{
    n.setDisable(false);
    n.setManaged(true);
    n.setVisible(true);
}

1 Ответ

0 голосов
/ 30 декабря 2018

Возможно, использование StackPane будет решением здесь.Ваш вопрос не содержит большого количества кода, чтобы показать весь ваш контекст, но MCVE ниже может помочь продемонстрировать идею.

По сути, мы создаем StackPane в качестве корневого контейнера отображения для всех ваших досок.,Ваши "доски" могут быть чем угодно, Pane, другим StackPane или VBox, как в моем примере.Это должно позволить вам продолжать использовать любую систему раскладки, в которой вы сейчас находитесь.

Следует отметить, что на каждой доске должен быть установлен фон, или нижние доски будут просвечивать и принимать события мыши..

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Separator;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class StackPaneSample extends Application {

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

    private static StackPane stackPane = new StackPane();

    @Override
    public void start(Stage primaryStage) {

        // Simple interface
        VBox root = new VBox(5);
        root.setPadding(new Insets(10));
        root.setAlignment(Pos.CENTER);

        // Create our StackPane
        stackPane.setStyle("-fx-border-color: black");
        VBox.setVgrow(stackPane, Priority.ALWAYS);

        // Let's create 3 "boards" for our StackPane. A background color seems necessary to hide layers below the top one
        VBox board1 = new VBox() {{
            setStyle("-fx-background-color: whitesmoke");
            setAlignment(Pos.CENTER);
            setUserData("Board #1");
            getChildren().add(new Label((String) getUserData()));
        }};
        VBox board2 = new VBox() {{
            setStyle("-fx-background-color: whitesmoke");
            setAlignment(Pos.CENTER);
            setUserData("Board #2");
            getChildren().add(new Label((String) getUserData()));
        }};
        VBox board3 = new VBox() {{
            setStyle("-fx-background-color: whitesmoke");
            setAlignment(Pos.CENTER);
            setUserData("Board #3");
            getChildren().add(new Label((String) getUserData()));
        }};
        stackPane.getChildren().add(board1);
        stackPane.getChildren().add(board2);
        stackPane.getChildren().add(board3);

        // Create three buttons that will switch between the boards
        Button btnBoard1 = new Button("Board #1");
        Button btnBoard2 = new Button("Board #2");
        Button btnBoard3 = new Button("Board #3");
        HBox hbButtons = new HBox(20) {{
            setAlignment(Pos.CENTER);
            setPadding(new Insets(5));
            getChildren().addAll(btnBoard1, btnBoard2, btnBoard3);
        }};

        // Finish out layout
        root.getChildren().addAll(
                stackPane,
                new Separator(Orientation.HORIZONTAL),
                hbButtons
        );

        // ** Now let's add our functionality **

        // Print out which board has been clicked upon
        // We need to first cast our List to VBox
        for (Node vbox : stackPane.getChildren()) {
            vbox.setOnMouseClicked(event -> System.out.println("Clicked on " + vbox.getUserData()));
        }

        // Set the buttons to set the top board
        btnBoard1.setOnAction(event -> selectBoard(board1));
        btnBoard2.setOnAction(event -> selectBoard(board2));
        btnBoard3.setOnAction(event -> selectBoard(board3));

        // Show the Stage
        primaryStage.setWidth(400);
        primaryStage.setHeight(300);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }

    // Method to remove the board and readd it, placing it on top of all others.
    private static void selectBoard(VBox board) {
        stackPane.getChildren().remove(board);
        stackPane.getChildren().add(board);
    }
}

Результат:

screenshot


Я, по общему признанию, не знаком с декартовыми координатами, которые вы упоминаете в своем комментарии, так что, возможно, это не сработает для вас.Добавление большего количества кода / контекста к вашему вопросу может помочь нам лучше сузить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...