在节点周围添加一个装饰区域,其行为类似于效果

时间:2016-07-25 15:30:28

标签: javafx-8

对于纸牌游戏,我正在写作,我创建了一个代表卡片的自定义“控件”。它可以翻转,拖动,选择,并在游戏过程中进行缩放,翻译等。

卡的一个核心功能是可以以不同方式“突出显示”。突出显示的最基本形式是在卡片周围显示一个发光的边框(动画)。

我从这里开始使用JavaFX效果(带有动画传播/半径的DropShadow),但很快就拒绝了,因为性能非常糟糕。

所以,我用卡后面的动画ImageView替换了效果(来自精灵表的基本精灵动画,带有预渲染的发光动画)。这解决了性能问题,但引入了我目前正在努力解决的许多其他问题......

因为,我不希望“锚点”成为卡片周围发光的左上角,而是卡片本身的左上角,我试图通过卡片节点偏移ImageView -X / -Y。

(不同的突出显示可以按不同的数量“扩展”节点,这不应该影响节点的位置,并且在设置节点的位置时,您根本不必关心可能不同的突出显示偏移或突出显示。 )

起初这看起来不错,但这仍然会影响整个节点的范围。例如,如果我向节点添加鼠标事件侦听器,则在单击“glow”区域时会触发,即使我将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。简单来说,它应该表现得像节点的效果......

下图显示的是我尝试构建:

enter image description here

在JavaFX中如何正确完成这样的事情? 可以正确完成吗?

1 个答案:

答案 0 :(得分:0)

setMouseTransparent(true)适用于effectView

但是,父级的边界(Pane)仍然包含effectView并生成鼠标事件。由于pickOnBounds的{​​{1}}默认设置为Regions(这是我错过的,因为一般默认情况下,根据java doc,是true)我们需要将其设置为false

然后它有效。