【问题标题】:Custom Node painting in JavaFXJavaFX 中的自定义节点绘制
【发布时间】:2014-06-12 12:36:25
【问题描述】:

在 PySide 中,您可以覆盖 QWidgetpaintEvent() 方法来控制小部件在屏幕上的绘制方式。 JavaFX 中是否有 Node 的等价物?


在上下文中:我需要一种在屏幕上显示自定义图像格式的方法。不断转换我的格式和 JavaFX 的 Image 以便我可以在 ImageView 中显示它对我来说太慢了,而且更混乱。

我看过ImageView.javaCanvas.java,但没有运气。 ImageView 正在使用 css,而 Canvas 似乎正在使用已弃用的 impl_ 方法做一些事情,我没有找到相关文档。

谢谢!

【问题讨论】:

  • 我不确定您所说的“ImageView 正在使用 css”是什么意思。您可以使用WritableImage 作为提供给ImageView 的图像,或者使用Canvas 及其GraphicsContextGraphicsContext 有大量用于绘制图像的公共 API。
  • 图片格式是什么?
  • @James_D @Kyllopardiun 我没有深入阅读它,但似乎ImageView 通过使用-fx-image CSS 属性设置自身样式来显示其图像,但实际的绘画是在其他地方完成的。它可能在impl_ 方法之一中,但没有文档我无法理解它们。我有一个代表图像数据的ints 数组。这是我正在开发的图像编辑器;我可以更新图像视图以反映图像数据更改的速度是这里的一个问题,这就是为什么我不想一直在两种格式之间进行转换。
  • 我不懂冰糕,讨论 CSS 和 impl_ 方法似乎无关紧要。如果你有一个数组 ints 是表示图像数据的缓冲区,为什么不能像 James_D 建议的那样使用 WritableImage (writableImage.getPixelWriter().setPixels(...))?

标签: user-interface javafx paint paintevent


【解决方案1】:

一般来说,JavaFX 中的绘制机制已转向更加基于事件的方法。要遵循 JavaFX 方式,您可能应该查看 TimelineAnimationTimer 并且仅在实际图像数据更改时更新显示。

但是,如果您愿意,可以在 JavaFX 中使用旧的 Swing 方式:

public class MyPane extends Pane {
    private final Canvas canvas;

    public MyPane() {
        canvas = new Canvas(getWidth(), getHeight());
        getChildren().add(canvas);
        widthProperty().addListener(e -> canvas.setWidth(getWidth()));
        heightProperty().addListener(e -> canvas.setHeight(getHeight()));
    }

    @Override
    protected void layoutChildren() {
        super.layoutChildren();

        GraphicsContext gc = canvas.getGraphicsContext2D();

        gc.clearRect(0, 0, getWidth(), getHeight());

        gc.setFill(Color.RED);
        gc.fillRect(10, 10, getWidth() - 20, getHeight() - 20);

        // Paint your custom image here:
        gc.drawImage(someImage, 0, 0);
    }
}

上面的代码就是这个 Swing 代码的等价物:

public class MyPanel extends JPanel {
    private static final long serialVersionUID = -969772195113348076L;

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.clearRect(0, 0, getWidth(), getHeight());

        g.setColor(java.awt.Color.RED);
        g.fillRect(10, 10, getWidth() - 20, getHeight() - 20);

        // Paint your custom image here:
        g.drawImage(someImage, 0, 0, null);
    }
}

【讨论】:

  • 这会将整个画布保存在内存中,而不是像paintComponent
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-25
  • 1970-01-01
  • 2014-12-03
  • 1970-01-01
  • 2018-11-26
  • 1970-01-01
  • 2017-10-11
相关资源
最近更新 更多