Skip to main content

A few small improvements to java.awt.geom.Rectangle2D etc..

7 replies [Last post]
soupdragon
Offline
Joined: 2006-01-07
Points: 0

new Rectangle2D.Double(x, y, w, h)

Is a bit ugly, and I've had a lot of grief from import management tools. Hows about a set of static factory methods with differently typed arguments? Should include ones with Point2D and Dimension2D arguments as well as X, Y, W, H.

This goes for the whole set of java.awt.geom objects, really. Point2D, Line2D etc..

Modification methods are a bit sparse too. How about something like:

public void setSize(Dimension2D newSize, int gravity);

And some translate methods would be nice.

OK, it's sugar but it helps the medicine go down.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
sunflar
Offline
Joined: 2005-10-28
Points: 0

It's interesting to note that with the advent of language-level enums, a lot more cases of "inner types" will start appearing and will likely cause the same confusion in the development tools as these public inner geom classes. Hopefully this will mean that the tools will fix bugs and so the geom.Float/Double problems will disappear over time.

flar
Offline
Joined: 2003-06-11
Points: 0

What kind of problems have you had with these constructors and import managment tools? A constructor is essentially the most strongly typed statement you can make in an OO language.

Is it the fact that this is an inner class? Or the fact that all of the inner classes are named similarly below the parent class? If you always include the parent class in the construction, as in your example, then the line of code reads unambiguously and should be properly parsed by any properly written tool, unless I'm missing something.

Static factory methods would probably end up even more verbose: [b]Rectangle2D.createDouble(x, y, w, h)[/b]?

soupdragon
Offline
Joined: 2006-01-07
Points: 0

It's using the inner class constructor that caused problem. One release of Netbeans I was using consistently treated java.awt.geom.Rectangle2D as a package, and converted Rectangle2D.Double to Double (a hastle when there were real Doubles about), which was less than helpful. I think it's better at it now. Static methods wouldn't be any less verbose, but they aren't such weird syntax.

Mainly I just think it's ugly, explicitly creating inner class items. The whole point of having inner classes is to hide them. And the factory routines could be discriminated by argument type, so you could have create(double, double,double, double), create(float, float,float, float) and create (int, int, int, int).

Either Rectangle2D.Double should be a class in it's own right or we shouldn't have to know about it.

flar
Offline
Joined: 2003-06-11
Points: 0

One problem with relying on the types of arguments in Java is that all integer primitive types can be cast to float and a float can be cast to a double so the rules of choosing an overloaded method will prefer a float version of a method to a double version if it is available and none of the arguments are doubles. This could cause problems with invoking create(0x7fffffff, ...) which will use the float factory even though the MAX_INTEGER value cannot be expressed as a float. (Even worse, using long arguments will still choose the float version of the factory despite the much greater disparity in precision.)

If the name is createFloat() or createDouble() then the programmer is more aware of what precision they are ending up with. That, in and of itself, will not suddenly make all programmers aware that they should use a double version when constructing from ints, but for those that are aware of the issue, they are less likely to be surprised by the standard rules of method parameter overloading.

soupdragon
Offline
Joined: 2006-01-07
Points: 0

Well, there is, as it happens an [b]int[/b] based class which extends Rectangle2D, namely java.awt.Rectangle so an int base factory would catch that. To elminate the problem altogether it would be easy to create a long valued version.

sunflar
Offline
Joined: 2005-10-28
Points: 0

An integer variant does solve the problem for Rectangle and Point, but not for the other geom classes which only have float and double variants, but even there ...

The problem gets a little more complicated when the arguments are of mixed type. If some arguments are integer and some are float, then double is the only type that can represent both types without loss of precision, but the compiler would choose an all-float method signature in that case.

Also, while double is a safer bet than float when faced with integers, it may be overkill and would use twice the storage. So, if we see such a mix (or a set of ints when there are only Float/Double subclasses) should we be safe and choose a double representation, or space conscious and choose a float representation? If we have only float/double factories and leave it to the compiler it will choose the float variant every time which could be bad news for some programs. It is hard for the implementation to really know how "safe" the integer values that will be fed to it may be. Even if it inspected the values at runtime, it doesn't know if the contents will remain within the range where floats can represent integers without loss of precision as future operations are performed on the returned object. And we will also have to deal with the compiler choosing the float variant in cases of mixed types without any way for the implementation to affect that decision. The implementation will only see the values after the compiler decided how to coerce them to a uniform type.

In the end, the developers are best positioned to understand their applications and the potential ranges of the data and so I tend to prefer to let them choose the storage types that best suit their needs. This may simply mean that the factory methods should have type-specific names so that the developers aren't taken unawares by the language design choices for argument promotion, but I was just trying to point out that factory methods have their own issues in this design space and so aren't an obvious and straight-forward solution.

soupdragon
Offline
Joined: 2006-01-07
Points: 0

> An integer variant does solve the problem for
> Rectangle and Point, but not for the other geom
> classes which only have float and double variants,

Easy enough to put in a int argumented method which calls the double one.

And maybe there [i]should[/i] be int variants of these classes.

> Also, while double is a safer bet than float when
> faced with integers, it may be overkill and would use
> twice the storage.

And, in practise, it's extremely unlikely that integers
that large will be used with these classes.

> I tend to prefer to let
> them choose the storage types that best suit their
> needs.

Which they can do perfectly well (in the rare case when it's likely to be an issue) by casting an argument or two.