Добавьте декоративную область вокруг узла, которая ведет себя как эффект.

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

Одной из основных особенностей карты является то, что ее можно «подсветить» по-разному. Самая простая форма выделения — это отображение светящейся рамки (анимированной) вокруг карты.

Я начал с эффектов JavaFX здесь (DropShadow с анимированным распространением/радиусом), но быстро отказался от этого, потому что производительность оказалась очень плохой.

Итак, я заменил эффект анимированным ImageView «за» картой (базовая анимация спрайта из листа спрайтов с предварительно обработанной анимацией свечения). Это решает проблему с производительностью, но создает множество других проблем, которые я сейчас пытаюсь решить...

Поскольку я не хочу, чтобы «точка привязки» была в верхнем левом углу свечения вокруг карты, а в верхнем левом углу самой карты, я попытался сместить ImageView в узле карты на -X/ -Ю.

(Различные блики могут «расширять» узел на разную величину, это не должно влиять на расположение узла, и при установке местоположения узла вам вообще не нужно заботиться о потенциально отличающихся смещениях бликов или бликах.)

Сначала это выглядело хорошо, но это все еще влияет на границы всего узла. Например, если я добавляю к узлу прослушиватель событий мыши, он срабатывает при щелчке в области «свечения», даже если я установил для ImageView прозрачность мыши. Мне пришлось бы создать «прокси» методы для всех методов событий на пользовательском узле и перенаправить их на «внутренний» узел карты. Что, конечно, возможно, но, честно говоря, это не то решение, которое я надеюсь найти.

Текущий узел карты имеет в основном следующую структуру:

   public class Card extends Pane {

        // the view that will contain the border glow (blue area in image below)
        private ImageView effectView;

        // stand-in for the rest of the card stuff (image etc)
        private Rectangle placeholderForCardContent;

        public Card() {
            effectView = new ImageView();
            effectView.setMouseTransparent(true);

            placeholderForCardContent = new Rectangle();

            getChildren().addAll(effectView, placeholderForCardContent);
        }

        @Override
        protected void layoutChildren() {
            // offsets are defined by the current highlight
            effectView.setLayoutX(-50); 
            effectView.setLayoutY(-50);
            effectView.setFitWidth(getWidth() + 100);
            effectView.setFitHeight(getHeight() + 100);

            placeholderForCardContent.setLayoutX(0);
            placeholderForCardContent.setLayoutY(0);
            placeholderForCardContent.setWidth(getWidth());
            placeholderForCardContent.setHeight(getHeight());
        }
    }

Пример: new Card().setOnMouseClick() и т.п. должны воздействовать только на область, в настоящее время равную placeHolderForCardContent, но не распространяться на effectView. Просто он должен вести себя как эффект узла...

На следующем изображении показано, как я пытаюсь построить:

введите здесь описание изображения

Как правильно сделать что-то подобное в JavaFX? Можно ли это сделать правильно?


person Roman Flückiger    schedule 25.07.2016    source источник


Ответы (1)


setMouseTransparent(true) правильно работает для effectView.

Однако границы родителя (Pane) по-прежнему включают effectView и генерируют событие мыши. И поскольку pickOnBounds для Regions по умолчанию установлено на true (это то, что я пропустил, поскольку общее значение по умолчанию, согласно java doc, равно false), нам нужно установить его на false.

Тогда это работает.

person Roman Flückiger    schedule 25.07.2016