Skip to main content

[JAVA2D] Why isn't there a method for drawing Point2Ds, pixels, and the like

6 replies [Last post]
Anonymous

While running some tests on a program that generates a dataset of
(x,y) pairs I decided that I would render them so I could see how the
data was distributed visually. Almost immediately I ran across an
interesting limitation:

"Except for Point2D and Dimension2D, each of the geometry classes
(geometries) implements the Shape interface, which provides a common
set of methods for describing and inspecting two-dimensional geometric
objects."

No biggie, I thought, I guess they aren't really 'shapes' so I'll just
draw them using Graphics2D. Hmmm... wait there is no method in
Graphics2D to draw them either. Ugh, that means I have to create one
pixel sized rectangles to draw points?

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
Jim Graham

It would be nice to have an RFE filed on this. There are a lot of
issues here, but at the very least the RFE would give us a place to
increase awareness of the issues, even if we don't find an acceptable
solution to put into our APIs.

There are two parts to this - whether to have Point2D implement Shape
and be possible to hand one to draw(Shape) and whether to add a new
convenience API targeted specifically at this capability.

The first part is fairly unsolvable and would probably have to be
denied due to various interactions between how the renderers handle
geometry with a moveto and nothing else, and with what one would expect
to see returned by the PathIterator of a Point2D to remain true to
various API contracts within the geom package. In particular, drawing
anything if you do draw(Point2D) would violate some rule somewhere and
represent a compromise.

With respect to a targeted and specific drawPoint() convenience API,
we'd need some input on what (hopefully "most") developers would like
to see from such a method which took into account potential
antialiasing, zooming and other transforms (which includes printing).
I'm not sure that we understand what developers want to see from such
an API that wouldn't disappoint many when they start printing their
work. But, it would provide a focus for such discussions and possible
resolution.

I'm guessing that drawMarker(x, y) might be a better name for the
convenience method because a "point" really isn't something to draw -
it's a location...?

...jim

--On Thursday, September 9, 2004 4:20 PM -0400 Gregory Pierce
wrote:
> Do I have to fill out an RFE or similar for something like this?

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

mthornton
Offline
Joined: 2003-06-10

A few more classes that implement the javax.swing.Icon interface might be appropriate. Each of the different ways of representing a point (as described earlier in this thread) could be represented by classes, plus of course the existing Icon implementation which will paint an image at the given point (although you might want to modify it to specify the position of the point relative to the image).

Jim Graham

The reason there is no method for drawing them is that they don't
describe any geometry to draw. Also, the question of what exactly the
user wants us to draw gets a little fuzzy as we introduce antialiasing,
scaling, and printing on high resolution printers to the mix.

If this were a pixel-based API then "drawing a point" would mean "turn
on the pixel at x,y coordinate.

But this is a scalable, transformable vector-based geometry API.
drawPoint primitives don't tend to exist in such APIs. I haven't done
a formal search, but a primary example is PostScript where you need at
least a moveto and also a following lineto or curveto to have anything
appear. A single moveto (which would be what a Point by itself
represents) would render nothing.

So, what do you want us to do "on or near the coordinate x,y"? Draw a
box? Draw a circle? When you scale it up or print it, the difference
between the two will become more evident.

If you're transform represents a 1:1 coordinate to pixel mapping with
only an integer translate, then fillRect(x, y, 1, 1) will best
approximate what most people expect from a drawPoint(x,y) API in a
pixel-oriented coordinate system, and may even visually approximate
what many people look for when printing such a graphic or zooming in on
it, except that it isn't centered around the coordinate.

If you'd rather they were round when you zoomed in or printed, then
drawOval() would look better, but involves more processing for the
simple case of rendering on screen at a 1:1 scale.

If keeping the box or oval centered around the coordinate is desirable
then creating a shape with origin x-0.5, y-0.5 and dimensions of 1x1
would help that, but that will also involve more processing in the
simple 1:1 unzoomed screen rendering case.

Using draw(Shape) or drawLine() is frought with problems in that the
outcome will depend on the line width and the line styles and
variations in those attributes could turn that rendering into just
about anything, especially when zoomed up to where you can tell the
difference between the various line caps. CAP_BUTT will render nothing
for a zero length line, CAP_SQUARE will render a box whose orientation
is undefined, and CAP_ROUND will render a circle.

Given all of these considerations, it seems easier to just let the
developer use the rendering that will describe what they want to
appear. Of the choices, fillRect() is the most expedient for screen
rendering and has some a specific rendering definition that is easy to
work with, though not centered around the coordinate if that is
important to you...

...jim

--On Thursday, September 9, 2004 2:49 PM -0400 Gregory Pierce
wrote:

> While running some tests on a program that generates a dataset of
> (x,y) pairs I decided that I would render them so I could see how the
> data was distributed visually. Almost immediately I ran across an
> interesting limitation:
>
> "Except for Point2D and Dimension2D, each of the geometry classes
> (geometries) implements the Shape interface, which provides a common
> set of methods for describing and inspecting two-dimensional geometric
> objects."
>
> No biggie, I thought, I guess they aren't really 'shapes' so I'll just
> draw them using Graphics2D. Hmmm... wait there is no method in
> Graphics2D to draw them either. Ugh, that means I have to create one
> pixel sized rectangles to draw points?
>
> =====================================================================
> ====== To unsubscribe, send email to listserv@java.sun.com and
> include in the body of the message "signoff JAVA2D-INTEREST". For
> general help, send email to listserv@java.sun.com and include in the
> body of the message "help".

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Chet Haase

Right - there's no API for drawing points explicitly. We could add
something
like this as a convenience in some future release, but in the meantime
it should be a pretty easy constraint to work around.

You don't need to "create" rects or anything else; you just need to
draw a one-pixel rect or line to do what you want.

if you have a point (x, y), drawing a pixel at that point should be as
easy as:
Graphics.drawLine(x, y, x, y);
or
Graphics.drawRect(x, y, 0, 0);
or
Graphics.fillRect(x, y, 1, 1);

Chet.

Gregory Pierce wrote:

>While running some tests on a program that generates a dataset of
>(x,y) pairs I decided that I would render them so I could see how the
>data was distributed visually. Almost immediately I ran across an
>interesting limitation:
>
>"Except for Point2D and Dimension2D, each of the geometry classes
>(geometries) implements the Shape interface, which provides a common
>set of methods for describing and inspecting two-dimensional geometric
>objects."
>
>No biggie, I thought, I guess they aren't really 'shapes' so I'll just
>draw them using Graphics2D. Hmmm... wait there is no method in
>Graphics2D to draw them either. Ugh, that means I have to create one
>pixel sized rectangles to draw points?
>
>===========================================================================
>To unsubscribe, send email to listserv@java.sun.com and include in the body
>of the message "signoff JAVA2D-INTEREST". For general help, send email to
>listserv@java.sun.com and include in the body of the message "help".
>
>

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Gregory Pierce

Do I have to fill out an RFE or similar for something like this?

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".

Chet Haase

An RFE never hurts. We're aware of this issue, but filing an RFE
ensures that
it will stay on our minds (it doesn't ensure a fix; we have to weigh the
pros of utility methods against the cons of API bloat, but it will at least
keep the issue alive).

By the way, my previous suggestions on how to draw a pixel were ignoring
important performance implications (silly me):

Graphics.fillRect()

is really the best and only way you should accomplish a simple pixel drawing
command. drawLine() tends to have more overhead because lines can have
attributes associated with them that we need to check. drawRect() is
essentially
four drawLine() commands (or at least extra logic to eliminate redundant
lines), so that's not the way to go either.

fillRect() is your friend. Just think of a single point as a very small
rect.

Chet.

Gregory Pierce wrote:

>Do I have to fill out an RFE or similar for something like this?
>
>===========================================================================
>To unsubscribe, send email to listserv@java.sun.com and include in the body
>of the message "signoff JAVA2D-INTEREST". For general help, send email to
>listserv@java.sun.com and include in the body of the message "help".
>
>

===========================================================================
To unsubscribe, send email to listserv@java.sun.com and include in the body
of the message "signoff JAVA2D-INTEREST". For general help, send email to
listserv@java.sun.com and include in the body of the message "help".