Should Canvas have been Image subclass instead of Node?

Jeff Martin jeff at reportmill.com
Wed Apr 23 16:34:47 UTC 2014


That's a nice solution - though in real world code I worry that the endDrawing snapshotting would be triggered more often than necessary.

I still think there is no compelling reason for Canvas to be a Node, and there is a significant drawback if you want to reuse the same Canvas many times in your scene graph.

I think it's appropriate to think of the basic Canvas functionality as a "Procedural Image" - it is used to create an Image from code instead of a file. Just because the most common case might be to stuff it in an ImageView, doesn't mean that it should be a Node for convenience. If you agree that the Image class shouldn't be a Node, you should feel the same way about Canvas.

I also think this would be easy to fix in a backward compatible way. A future release could simply add a "CanvasImage" class which had a GraphicsContext - then Canvas could remain, but simply embed a CanvasImage. Though for practical purposes, I think most developers would simply use CanvasImage with ImageView from then on.

jeff


On Apr 23, 2014, at 10:37 AM, Scott Palmer <swpalmer at gmail.com> wrote:

> Here's a quick hack based on using snapshots to make something like a
> Canvas that you can reuse in many places within the Scene.  By
> subclassing WritableImage it comes out to being pretty close to what
> you were talking about.  As you mentioned, using snapshots isn't
> ideal, but I wonder how far from ideal this really is?  Having to
> remember to make the snapshot is just one call.
> 
> public class CanvasImage extends WritableImage {
> 
> private final Canvas canvas;
> private final SnapshotParameters snapshotParams;
> 
> public CanvasImage(int width, int height) {
> super(width, height);
> canvas = new Canvas(width, height);
> snapshotParams = new SnapshotParameters();
> snapshotParams.setFill(Color.TRANSPARENT);
> }
> 
> public GraphicsContext beginDrawing() {
> return canvas.getGraphicsContext2D();
> }
> 
> public void endDrawing() {
> canvas.snapshot(snapshotParams, this);
> }
> }
> 
> Cheers,
> 
> Scott
> 
> On Tue, Apr 22, 2014 at 7:01 PM, Scott Palmer <swpalmer at gmail.com> wrote:
>> It would be great if you could get a Graphics context for drawing into a
>> WritableImage instead of having to deal with snapshots. But I suppose you
>> could build something like that based on Canvas that would update an image.
>> 
>> Scott
>> 
>> On Apr 22, 2014 6:52 PM, "Jeff Martin" <jeff at reportmill.com> wrote:
>>> 
>>> Just by using it as an ImageView.Image.
>>> 
>>> jeff
>>> 
>>> 
>>> On Apr 22, 2014, at 5:43 PM, John C. Turnbull <ozemale at ozemail.com.au>
>>> wrote:
>>> 
>>>> How would you (easily) use it in the scenegraph if it wasn't a Node?
>>>> 
>>>> -----Original Message-----
>>>> From: openjfx-dev [mailto:openjfx-dev-bounces at openjdk.java.net] On
>>>> Behalf Of
>>>> Jeff Martin
>>>> Sent: Wednesday, April 23, 2014 8:16 AM
>>>> To: openjfx-dev at openjdk.java.net Mailing
>>>> Subject: Should Canvas have been Image subclass instead of Node?
>>>> 
>>>> I have a case where I need to draw to a canvas and reuse it in multiple
>>>> nodes. My non-optimal work-around is to take a snapshot and use that,
>>>> but it
>>>> makes me wonder if Canvas should have been an Image subclass or if
>>>> WritableImage should get it's own getGraphicsContext() method.
>>>> 
>>>> jeff=
>>>> 
>>> 
>> 



More information about the openjfx-dev mailing list