在 JavaFX 中将 BlendMode 添加到裁剪节点

Posted

技术标签:

【中文标题】在 JavaFX 中将 BlendMode 添加到裁剪节点【英文标题】:Adding a BlendMode to a Clipped Node in JavaFX 【发布时间】:2018-05-26 18:40:23 【问题描述】:

有没有办法将 BlendMode(或 Blend 效果)添加到已裁剪的节点?似乎如果我尝试将剪辑添加到已设置 BlendMode 的节点,则 BlendMode 会被剪辑覆盖并且不再正常工作。一些重现问题的示例代码:

package display.fx.demo;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.effect.BlendMode;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class BlendModeClipProblem extends Application 
    public Rectangle blueRect = new Rectangle(0, 0, 30, 30);
    public Rectangle redRect = new Rectangle(15, 15, 30, 30);

    @Override
    public void start(final Stage stage)
            throws Exception 
        final Pane pane = new Pane();
        final Scene scene = new Scene(pane);
        pane.getChildren().add(blueRect);
        pane.getChildren().add(redRect);

        blueRect.setFill(Color.BLUE);
        redRect.setFill(Color.RED);

        redRect.setBlendMode(BlendMode.ADD);

        // Comment this next line to see blending
        redRect.setClip(new Rectangle(15, 15, 20, 20));

        stage.setScene(scene);
        stage.show();
    

【问题讨论】:

【参考方案1】:

试试这样的(使用缓存矩形)

@Override
    public void start(final Stage stage)
            throws Exception 
        final Pane pane = new Pane();
        final Scene scene = new Scene(pane);
        pane.getChildren().add(blueRect);
        pane.getChildren().add(redRect);

        blueRect.setFill(Color.BLUE);
        redRect.setFill(Color.RED);

        redRect.setBlendMode(BlendMode.ADD);

        redRect.setCache(true);
        redRect.setCacheHint(CacheHint.QUALITY);

        redRect.setClip(new Rectangle(15, 15, 20, 20));

        stage.setScene(scene);
        stage.show();
    

【讨论】:

这行得通!但是,我不确定为什么这应该起作用,而不是非缓存版本。 AFAIK,缓存应该只是通过将节点的位图版本存储在内存中来提高渲染速度,而不是重新渲染节点和每个效果。缓存版本和非缓存版本之间的这种不一致是否表明 JavaFX 本身存在错误? 是的,我也认为 JAVAFX 中存在故障,每当在swing 中发生这种情况时,我们可以调用repaint(),但在 JavaFx 中我使用缓存,因为我们不能显式调用 repaint()

以上是关于在 JavaFX 中将 BlendMode 添加到裁剪节点的主要内容,如果未能解决你的问题,请参考以下文章

在 JavaFX 中将元素动态添加到固定大小的 GridPane

如何在 JavaFX 中将 CheckBox 添加到 TableView

我可以在 JavaFX 中将自签名证书添加到我的 WebEngine 以连接到 https Web 服务器吗?

JavaFX 动态地将标签添加到窗格,在 fxml 文件中定义

SpriteKit:如何使用 blendMode 在图层中打孔

如何在对话框中将事件侦听器绑定到JavaFX TextFields。当字段为空时,“确定”按钮将被禁用,反之亦然