Подтвердить что ты не робот

События мыши игнорируются на базовом слое

У меня есть два слоя (= AnchorPanes), уложенные один из другого с помощью StackPane. Таким образом, оба слоя заполняют всю сцену. Проблема в том, что только верхний уровень принимает события мыши.

Вот как строится сцена:

Layout of the Scene

Только кнопка B получает события кликов, но кнопка A отсутствует.

Button A don't Receive Click Events

Если я устанавливаю Layer B в прозрачную мышь (layerB.setMouseTransparent(true)), кнопка A принимает события мыши. Но мышь прозрачные эффекты также все дети, поэтому кнопка B не принимает события мыши больше.

Как получить кнопки A и B для получения событий мыши?

Вот полный рабочий источник:

public class LayerTest extends Application {
    @Override
    public void start(final Stage primaryStage) throws Exception {
        final Node layerA = createLayerA();
        final Node layerB = createLayerB();
        final Parent root = new StackPane(layerA, layerB);
        final Scene scene = new Scene(root);
        primaryStage.setScene(scene);
        primaryStage.setWidth(250);
        primaryStage.setHeight(200);
        primaryStage.show();
    }

    private Node createLayerA() {
        final AnchorPane layerA = new AnchorPane();
        final Button buttonA = new Button("Button A");
        AnchorPane.setLeftAnchor(buttonA, 10d);
        AnchorPane.setTopAnchor(buttonA, 10d);
        buttonA.setOnMouseClicked(e -> System.out.println("Button A clicked"));
        layerA.getChildren().setAll(buttonA);
        return layerA;
    }

    private Node createLayerB() {
        final AnchorPane layerB = new AnchorPane();
        final Button buttonB = new Button("Button B");
        AnchorPane.setRightAnchor(buttonB, 10d);
        AnchorPane.setBottomAnchor(buttonB, 10d);
        buttonB.setOnMouseClicked(e -> System.out.println("Button B clicked"));
        layerB.getChildren().setAll(buttonB);
        return layerB;
    }

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

Ответ 1

Решение

Добавьте в свой пример код следующей строки:

layerB.setPickOnBounds(false);

Это позволит мыши взаимодействовать с видимыми элементами, которые вы видите через слои ваших уложенных элементов.

Если элементы верхнего слоя перекрывают элементы нижнего слоя, нажимая на часть верхнего слоя, который перекрывает нижний слой, верхний слой будет потреблять событие мыши, а нижний слой не получит его (что, вероятно, вы хотите).

Альтернативное толкование

Если вы действительно хотели перехватить и обработать событие мыши во всех слоях, тогда см. связанные вопросы от комментариев Улука:

Описание метода

Описание метода setPickOnBounds:

Определяет, как выполняется вычисление выбора для этого node при срабатывании MouseEvent или содержит вызов функции. Если pickOnBounds истинно, то выбор вычисляется путем пересечения с границами этого node, иначе сбор вычисляется путем пересечения с геометрической формой этого node.


Панели не имеют видимого фона по умолчанию, поэтому почему они должны потреблять события мыши?

Для modena.css, таблицы стилей по умолчанию, поставляемой с JavaFX 8, у Panes на самом деле есть очень слабый затененный фон по умолчанию, поэтому они могут потреблять события мыши. Чтобы предотвратить это, вы можете либо установить для панели цвет фона панели равным null, либо установить Pane на mouseTransparent.

Это поведение изменилось между JavaFX 2 и JavaFX 8. JavaFX 2 поставляется со списком стилей по умолчанию caspian.css, который не устанавливает фон для панелей.

Ответ 2

Это не работает, потому что Событие улавливается LayerB. Вы можете установить LayerB в MouseTransparent

layerB.setMouseTransparent(true)

Но я не уверен, что кнопка b также является mousetranparent тоже после этого.

Просто попробуйте, а вы думаете о другом макете.