Skip to main content

Two reasons why AA text doesn't work

4 replies [Last post]
uncle_alice
Offline
Joined: 2003-06-16
Points: 0

When I first ran my home-grown editor app under Mustang-b40, neither the textarea nor the line-number gutter was displaying AA text (although they work fine under Tiger with the "swing.aatext" property set). I finally figured out what the problems were, and thought I'd share what I learned.

All JComponents are supposed to use the drawString/drawChars methods of the new SwingUtilities2 class to paint text. Before painting the text, they check the JComponent (which is passed as one of their parameters) for a certain client property which contains info about what kind of AA to use (if any), plus other hints. If the JComponent parameter is null, or it doesn't have that client property, no AA is used.

The client property is supposed to be set automatically when the JComponent is created, assuming the L&F supports AA. This is done in the setUI method. But if your JComponent subclass doesn't have a UI delegate, that method never gets called, and you don't get AA. That was the problem with my gutter component. I first got it to work by having it extend JPanel instead of JComponent, but I didn't really want to do that. So I tried just calling setUI(null) in the constructor, and it worked!

My textarea uses a custom View class, which ultimately calls the drawTabbedText method in javax.swing.text.Utilities. Trouble is, there are two versions of that method now, and I was calling the wrong one. The one I needed to call takes the View as its first parameter. It uses that to get a reference to the textarea, then passes that along to the SwingUtilities2.drawString method. Because I was calling the wrong method, drawString was receiving a null JComponent reference, so I got no AA. Unfortunately, the "right" method is package-private--I had to copy it into my own source tree to use it. Does anybody know a good reason why that method can't be public?

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
zixle
Offline
Joined: 2004-07-22
Points: 0

Dr Uncle Alice,

We're actively trying to figure out what the best approach would be for this. Here are some possibilities:

. Expose a desktop property that is a Map of the rendering hints. You could set this on the Graphics any time you do string drawing operations so that they are appropriate based on the current platform.
. Move the code for setting the private data on JComponent to updateUI and perhaps the constructor so that subclasses of JComponent that don't have a UI will work too.
. Move some of the SwingUtilities2 methods to javax.swing.SwingUtilities and encourage developers to use them for swing components.

What do you think?

-Scott

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

Hey Scott, thanks for responding. I don't think any of those suggestions is satisfactory WRT text components. We still have to either supply SwingUtilities[2] with a reference to the JComponent, or add code to set the rendering hints. Either way, we have to update our code to get AA to continue working under Mustang.

Why doesn't SwingUtilities2 just get the setting directly from the UIDefaults table? Maybe it could look for a client property first, and if it can't find one, use the UIDefaults setting. That would enable us to use different settings for individual components, but the default behavior would be to use the L&F setting everywhere.

-Alan

zixle
Offline
Joined: 2004-07-22
Points: 0

Hi Alan,

Thanks for the clarification.

If we added a fallback such that if you don't supply a component you get what the desktop wants, would that be enough? If we did that I think you're code (meaning code before your change to call drawTabbedPane with View) would just work. Is that right?

-Scott

uncle_alice
Offline
Joined: 2003-06-16
Points: 0

Right. And that would also eliminate the need for the setUI(null) hack in components without UI delegates.