Skip to main content

Subpixel anti-aliasing: enable it programmatically for Swing components

13 replies [Last post]
chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

Hi,

Having read:
http://weblogs.java.net/blog/chet/archive/2005/06/phils_font_fixe.html

...and having downloaded Mustang b44, browsed the source, and read through the JavaDocs, I can't see how to enable subpixel anti-aliasing when it's not "inherited" from the desktop. I'm using Windows 2000, and am trying to create a simple "Hello World" JFrame with a few JLabels and JButtons to try this feature out.

I can see how text should be rendered on a surface such as a JPanel by overriding paintComponent() and the Graphics2D object, but I can't see how to force other components (labels, buttons, tables, and so on) to use this.

When looking through src.zip with the Mustang snapshots, I can see (roughly) how desktop properties are picked up upon and stored in the look-and-feels UIDefaults, but the property names, values, and types are somewhat unclear and appear to be Sun-specific... I looked at:

com.sun.java.swing.plaf.windows.WindowsLookAndFeel
com.sun.java.swing.SwingUtilities2

How can I force this to be enabled for all Swing components?

- Chris

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

> Although I did not mention it before we are already
> adding a mechanism
> to expose access to the same desktop info that Swing
> is currently using so
> you can find out what Swing will be doing. It will be
> a Map of all the hints
> Swing will use.

Good news!

> >java.awt.Font::isSystemTextAntiAliasingRenderingHintS
> upported
>
> So this is an API you'd like to return false on W2K
> because
> the O/S can't do it, so you know it'll never be used
> by Swing by default
> I actually suppose you mean SubPixelAA .. since
> pretty much everyone
> will return true if you include greyscale.

Good guess, my suggested method names above are awful! ;-)

> But how will you use that information?
> It sounds as if you are thinking that may be the user
> would like
> LCD text if he could have it.
>
> As well as being arguably being a distinct request
> from a way
> to tell Swing what to use, it
>
> This brings me to one question which your final
> sentence/paragraph
> touches on. How do you, the developer, expect to know
> what your user wants ?
>
> A couple of observations might help frame that
> question:
>
> * There's no way we can find out (short of asking the
> user with
> a UI dialog) if they have an LCD with a DVI
> connector, which is
> what is needed for LCD text to be useful.
>
> * there is another blog conversation going on at :
>
> http://weblogs.java.net/blog/chet/archive/2005/07/lcd_
> text_how_do.html
>
> where at least one user expresses a personal dislike
> for AA text.

To answer all of the above, you guessed correctly about what I was thinking. I had in mind something like an application preferences window, where there'd be a checkbox or drop-down enumeration of text modes. That's obviously the application developer's responsibility to provide such a feature, and in no way anything that could feasibly be built into Java SE. I was just wanting to expose that information so that default options could be chosen intelligently, and so that developers have a way of avoiding overriding automatically-detected settings through "ignorance".

I can appreciate that anti-aliasing isn't desirable for everyone, just like the user you mentioned. That's why I care about being able to make and propose good choices for users, and not impose personal preferences. For example, I know someone with a high-spec LCD screen who doesn't use it at it's full potential (i.e.: lower resolution) and subpixel anti-aliasing isn't too hot like that.

Thanks for your feedback, keep up the good work (it's appreciated!).

chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

Thanks for your feedback Phil, and great work!

The system property "swing.aatext" was a bit hacky, but suitable given that it appears to have been an interim solution. I think something a bit more "structured" could be suitable now that this is a "mature" feature.

I don't think a method such as "(JComponent|UIManager).setTextAntialiasing" is ideal, because we've already got a huge amount of methods in these classes. Besides, it's the look-and-feel that ultimately draws the text, so if the look-and-feel was written before Java SE 6, it's meaningless. However, as far as the look and feels bundled with Sun's implementation are concerned, this can obviously be anticipated.

Why not just add something to the JavaDocs for the anti-aliasing RenderHints, stating that these keys/values can be added to a look-and-feel's UIDefaults, and that that would become the standard "toggle" for this feature (specifying that third-party look-and-feels should leverage the same mechanism)? And of course get the Swing team to implement it... ;-) It seems like most of the hard work has already been done though.

I'll post an RFE, as you suggested. The Swing guys are going to love me, that's the third today... :-)

chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

RFE posted an accepted.

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6302464

It might not show up for a couple of days in the public view of the bug database.

Thanks again Phil.

philrace
Offline
Joined: 2003-06-09
Points: 0

I see it (6302464) in our internal database but you are right it will take longer to show up externally.

I want to follow up on something you wrote in that submission:
>>>>> BEGIN SNIPPET
Ideally, it should be possible to query some object (Font?) to find out what sort of font rendering hints the system applies, and not override them if the system natively supports it and if the user has expressed a preference, avoiding overriding user preferences. It should also be possible to detected (from the same API) to determine if the system actual has this capability (if it doesn't, the application could offer the user an option to enable it or just switch it on).

Something like:

java.awt.Font::getSystemTextAntiAliasingRenderingHint
java.awt.Font::isSystemTextAntiAliasingRenderingHintSupported
...to query the desktop's native subpixel (or standard) text anti-aliasing before steamrollering them with the developer's personal antialiasing preference. Or just stick totally to the type of anti-aliasing keys/values already in the RenderingHints' classes' constants.
<<<<< END SNIPPET

>java.awt.Font::getSystemTextAntiAliasingRenderingHint
Although I did not mention it before we are already adding a mechanism
to expose access to the same desktop info that Swing is currently using so
you can find out what Swing will be doing. It will be a Map of all the hints
Swing will use.

>java.awt.Font::isSystemTextAntiAliasingRenderingHintSupported

So this is an API you'd like to return false on W2K because
the O/S can't do it, so you know it'll never be used by Swing by default
I actually suppose you mean SubPixelAA .. since pretty much everyone
will return true if you include greyscale.

But how will you use that information?
It sounds as if you are thinking that may be the user would like
LCD text if he could have it.

As well as being arguably being a distinct request from a way
to tell Swing what to use, it

This brings me to one question which your final sentence/paragraph
touches on. How do you, the developer, expect to know what your user wants ?

A couple of observations might help frame that question:

* There's no way we can find out (short of asking the user with
a UI dialog) if they have an LCD with a DVI connector, which is
what is needed for LCD text to be useful.

* there is another blog conversation going on at :

http://weblogs.java.net/blog/chet/archive/2005/07/lcd_text_how_do.html

where at least one user expresses a personal dislike for AA text.

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

>How do you, the developer, expect to know
>what your user wants ?

I expect to know _exactly_ what the user wants because the user will set the options in a Swing configuration dialog that I provide. :_)

It's great that a lot of work is being done to set sensible defaults based on existing OS settings - but it's not enough, and never will be considering the human factors. Please enable us to let the users choose.

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

However the functionality is turned on and off, it MUST NOT use System properties because those can not be used by unsigned Java Web Start applications.

chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

> However the functionality is turned on and off, it
> MUST NOT use System properties because those can not
> be used by unsigned Java Web Start applications.

I agree; System properties are a bit "hacky". A nice clean method call wouldn't hurt too much...

chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

Other that "should it be possible", any ideas on how it "may be done"..?

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

Java2D has a set of keys that can be set at runtime to enable antialiasing and other features. I'd like to see something like that.

philrace
Offline
Joined: 2003-06-09
Points: 0

How can you switch on subpixel anti-aliasing for Swing components when your O/S doesn't have this

Since Windows 2000 doesn't natively support LCD text, on W2K Swing will not
see a Windows desktop setting that specifies it. So if you want it in a Java
application you are going to do *something* to make it happen since I
hope it should be obvious that it would be wholly inappropriate that Swing
always do LCD text on all Windows 2000 systems regardless ..

The proposal is that you (the developer or the sysadmin) set a Java
system property which overrides any actual desktop settings such that
Swing sees instead what you specified :


http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6291810


This can be used on any OS/desktop that JDK doesn't recognise
desktop settings.

chris_e_brown
Offline
Joined: 2004-09-14
Points: 0

To start with a comparison: standard Windows applications have a less powerful UI toolkit than Swing (at least, "pre-avalon") in terms of painting complex components (e.g.: watermarked JTables and other advanced Swing paint techniques). I wouldn't want to lose that ability in Swing just because the host platform doesn't support it.

In Chet's post, he stated that this feature meant that subpixel anti-aliasing would be available on platforms that didn't normally support it. Subpixel antialiasing is desirable to have as a programmable option (I wouldn't systematically force it onto my users, I'd give them an option in the application where I knew the desktop can't suggest a user preference for this feature), as it can greatly improve readability, irrespective of the O/S. I cited Windows 2000 as it's the example I'm using, I'm supposing here that there are other windowing systems that might benefit.

If you can use it programmatically when painting with Graphics2D and a key from RenderingHints, I don't see why it can't be enabled as a UIDefault or a "client property" of the look and feel/UIManager, or JComponents, perhaps in the same way as we have the option for JFrame decorations to be painted by the look and feel and not the host windowing system (static method on JFrame in this case).

If Swing can do it on XP, it can do it on any platform. The difference is that there's a preference on XP that isn't present on its predecessors, it's nothing to do with the capability of the Java2D engine AFAIK. All I'm hoping for is an option!

- Chris

philrace
Offline
Joined: 2003-06-09
Points: 0

Yes Java 2D can do any of this on any platform.
That has been implemented and will work dandy on W2K
The nature of the enhancement to Swing is that
enhancement that Swing picks up the desktop settings.

I think at one point we may have discussed supporting
this request using UI defaults, but its a TBD.

I suggest to file an RFE under "classes_swing" that
asks for this API.

We'll have to be careful not to have too many ways
of specifying all these - or at least a clear and
simple story on how these are resolved.

A system property is certainly hacky compared to
API when you have the option but is nonetheless
useful to some class of users
(those who aren't updating the program source) and
want all their Swing apps to look like the desktop.
The requirement here is somewhat different.

BTW there is a set of "secure properties" that can
be set by non-signed webstart apps. Its a simple matter
to add something like this to that set.

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

UI Defaults would be nice.

A system property could still be used to set the UI defaults.

Wrt secure properties, that would work but then we would have to file an RFE every time to get some Java feature into the secure properties. I think standardizing on a mechanism that works in secure and insecure environments would guarantee current and future features going into the JDK will be usable in both environments.