Unicode labels, fonts for components?

P

Peter Duniho

The main problem I'm having is that the "â†" (left arrow) and "→" (right
arrow) characters are not displaying property under Windows (Java 6).
They are displayed correctly on the Mac (Java 5). (I mentioned the JRE
version in case it's relevant, but I'd hope it wouldn't be).

I wondering if this is a consequence of me not setting some property or
setting or otherwise not configuring my application or Java correctly. If
so, how do I get it to work? If not, what might be wrong? Is it a known
limitation of the Windows Java implementation?

I had expected that Java would be fully Unicode-enabled. Eclipse seems to
support it just fine, under Windows and on the Mac. And the Java runtime
on the Mac supports it fine. (In fact, even on the Eclipse version of
Windows the arrows show up fine in the source, and since Eclipse is
practically all Java (right?) I expect that demonstrates that there is
_some_ way to get Unicode characters to work right in a Java application).

Related to this is that Component.getFont() doesn't appear to behave as
documented. The docs imply that _some_ font will be returned; if the
Component doesn't have one set, the parent's font will be returned. Now,
I suppose read literally this means that if the parent doesn't have a
font, you get null. But I would have thought that "font will be returned"
really means "the result of Component.getFont() on the parent will be
returned", implying that it will work its way up the containment hierarchy
until a font is found and returned.

I ran into this because I wondered if the arrows weren't displaying
properly because of a font issue. The font being displayed _looks_ like
Arial, but my installed Arial font has those characters so I figured I'd
double-check to see what font was being used. But calling getFont() on
the Component (it's a Button...not sure if that matters) returns null,
which is not at all what I expected.

Is there any way programmatically to reliably get the actual font that's
current being used to display text in a Component?

But mostly I just want to know how to get my arrow characters to display
properly. :)

Thanks!
Pete
 
R

RedGrittyBrick

Peter said:
The main problem I'm having is that the "â†" (left arrow) and "→" (right
arrow) characters are not displaying property under Windows (Java 6).
They are displayed correctly on the Mac (Java 5). (I mentioned the JRE
version in case it's relevant, but I'd hope it wouldn't be).

I wondering if this is a consequence of me not setting some property or
setting or otherwise not configuring my application or Java correctly.
If so, how do I get it to work? If not, what might be wrong? Is it a
known limitation of the Windows Java implementation?

I had expected that Java would be fully Unicode-enabled. Eclipse seems
to support it just fine, under Windows and on the Mac. And the Java
runtime on the Mac supports it fine. (In fact, even on the Eclipse
version of Windows the arrows show up fine in the source, and since
Eclipse is practically all Java (right?) I expect that demonstrates that
there is _some_ way to get Unicode characters to work right in a Java
application).

Related to this is that Component.getFont() doesn't appear to behave as
documented. The docs imply that _some_ font will be returned; if the
Component doesn't have one set, the parent's font will be returned.
Now, I suppose read literally this means that if the parent doesn't have
a font, you get null. But I would have thought that "font will be
returned" really means "the result of Component.getFont() on the parent
will be returned", implying that it will work its way up the containment
hierarchy until a font is found and returned.

I ran into this because I wondered if the arrows weren't displaying
properly because of a font issue. The font being displayed _looks_ like
Arial, but my installed Arial font has those characters so I figured I'd
double-check to see what font was being used. But calling getFont() on
the Component (it's a Button...not sure if that matters) returns null,
which is not at all what I expected.

Is there any way programmatically to reliably get the actual font that's
current being used to display text in a Component?

But mostly I just want to know how to get my arrow characters to display
properly. :)

The following displays fine on Windows XP with JRE 1.6

--------------------------8<---------------------------------
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class TestGetFont {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new TestGetFont();
}
});
}

TestGetFont() {
String arrows = "left \u2190 right \u2192 arrows";

JButton b = new JButton(arrows);
System.out.println("JButton font is " + b.getFont());

JPanel p = new JPanel();
p.add(b);

JFrame f = new JFrame("Test Component.getFont()");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(p);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}

}
--------------------------8<---------------------------------

The console output from println is:
JButton font is
javax.swing.plaf.FontUIResource[family=Dialog,name=Dialog,style=bold,size=12]
 
R

RedGrittyBrick

<My SSCCE snipped>

P.S.

I can replace
String arrows = "left \u2190 right \u2192 arrows";
with
String arrows = "left ↠and right → arrows";

But I first had to change Eclipse's default text-file-encoding from the
default CP1252 to UTF8 in Window -> Preferences -> General -> Workspace.

When I did this, Eclipse recompiled everything in my workspace and made
a mess of some non-ASCII Latin-1 accented characters in one string
constant in one source file. I was able to simply paste in replacement
text from a backup, but you might want to prepare for this if your
workspace has many Java source code files that contain non-ASCII characters.

For me, this sort of problem is a strong argument in favour of using
Unicode escapes such as \u2190.

I expect anyone in a non-English locale has already got Eclipse set up
so that usage of non-ASCII characters in Java source code isn't a problem.
 
P

Peter Duniho

The following displays fine on Windows XP with JRE 1.6

Thanks for the demo code! I'll try that sample when I get a chance.
However, note that I'm not using Swing. It's a plain AWT Button, not a
JButton.

Is this something that is simply not expected to work with AWT, but will
with Swing?

Can anyone else comment on the AWT side of the question?

Thanks,
Pete
 
J

Joshua Cranmer

Peter said:
Thanks for the demo code! I'll try that sample when I get a chance.
However, note that I'm not using Swing. It's a plain AWT Button, not a
JButton.

That explains a lot. AWT punts everything to the OS in terms of how
stuff works; fonts are no exception. Try reading Sun's i18n FAQ. (In
short: blame Microsoft for your problems)
 
P

Peter Duniho

That explains a lot. AWT punts everything to the OS in terms of how
stuff works; fonts are no exception. Try reading Sun's i18n FAQ. (In
short: blame Microsoft for your problems)

As far as I know, Microsoft didn't write the JRE implementation. I don't
see how they are responsible. It's not their fault Sun documented
something they can't deliver (assuming what you write is correct).

If this is a limitation in AWT, then the docs should say so. I think it's
pretty silly for the docs to imply that getFont() will always return a
font when in fact it doesn't.

I appreciate attempts to answer the actual question, but I don't see how
the finger-pointing is constructive or helpful at all. Either the docs
describe what happens or they don't. I'm less interested in why
(especially when it involves subjective blame games), and more interested
in whether I can get Unicode characters to be correctly displayed in my
Button control and if so, how (the font issue is actually secondary to my
main question anyway).

Thanks,
Pete
 
P

Peter Duniho

You can do a setFont for any font installed. So long as it has
unicode support for the chararters you want, you should be in good
shape.

Well, there are certainly fonts installed (and ubiquitous enough) that
include the characters I want. But they seem not to be used by default,
and I'm confused by your own advice as to whether I can actually use them
or not. See below...

Thanks!

According to this link, the font being used on Windows should be "Lucida
Sans". And sure enough, the characters I want are not in that font, in
spite of your statement on the page that "these Java logical fonts support
many more characters than most fonts". Apparently the arrows are not
among the "miscellanous symbols" included :(...in fact, looking at the
font, at least according to the Character Map application, the font has
relatively few characters in it, and no Chinese characters at all
(something your page specifically mentioned as being included).

Interestingly, there's also a "Lucida Sans Unicode" font installed that
_does_ have the arrows (but no Chinese characters still).

But: your page also says that I can only use the five Java logical fonts
with an AWT control. This conflicts with your statement above, "You can
do a setFont for any font installed". Can I actually do that? Or am I,
as the web page says, restricted to the five Java fonts?

Pete

p.s. By the way, that page took forever to load in Opera, and never did
finish downloading the last of 85 images (the brower's status shows it
stuck at "Image: 84/85"). Not sure if you're concerned about that or not.
 
P

Peter Duniho

[...]
But: your page also says that I can only use the five Java logical fonts
with an AWT control. This conflicts with your statement above, "You can
do a setFont for any font installed". Can I actually do that? Or am I,
as the web page says, restricted to the five Java fonts?

Okay, I'd love to get a more definitive answer, but just for the record, I
was unable to set the font to something that would display the arrow
characters while using an AWT control.

I tried using a Swing JButton instead, and it works fine by default. I
didn't even have to set the font. The "look and feel" is actually a
little off on Windows XP...it has more of a Vista look. And on the Mac,
the auto-sizing of the button is a little different, but otherwise it
looks okay.

Maybe I should just not worry so much about the question of using
native-peer AWT controls (for best user-experience consistency) and go
with the Swing controls instead.

I'd still like to know if it's possible to do this somehow with AWT. In
particular, is it really true that I can set the font to any font I need?
If so, how?

Thanks!
Pete
 
W

Wayne

Peter said:

I'd still like to know if it's possible to do this somehow with AWT. In
particular, is it really true that I can set the font to any font I
need? If so, how?

Thanks!
Pete

Fonts support a "canDisplay" method. You can use this to iterate over
available fonts to determine a set that displays the characters
you wish.

Here's some code. While I used swing (so my applet could have
a menu) I think this would work for AWT as well:

<snippit>
// Find all Fonts that can display arrow symbols:
fontList = new ArrayList<Font>();
Collections.addAll( fontList,
GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts() );
for (Iterator<Font> i = fontList.iterator(); i.hasNext(); ) {
Font f = i.next();
if ( ! f.canDisplay( '\u2192' ) ) // right arrow
i.remove();
}
</snippit>

Here's a link to the full applet and code:
http://www.hccfl.edu/pollock/Java/UnicodeSymbols.htm

Hope this helps!

-Wayne
 
S

Stefan Ram

Peter Duniho said:
I'd still like to know if it's possible to do this somehow with AWT.

Swing does this with AWT. Therefore, it is possible.
To see how, you migh read the Swing source code.
 
P

Peter Duniho

Fonts support a "canDisplay" method. You can use this to iterate over
available fonts to determine a set that displays the characters
you wish.

Well, that's useful information, thank you. But if I can't actually set a
font on an AWT control, I'm not sure how to take advantage of it. :(
 
P

Peter Duniho

Swing does this with AWT. Therefore, it is possible.
To see how, you migh read the Swing source code.

It does?

Maybe my impression of AWT and Swing is wrong. But reading the Sun
tutorials and whatnot, I have the impression that AWT is a thin layer over
the native GUI controls each platform provides, while Swing is a
from-scratch Java implementation of the controls. Wouldn't the Swing
JButton control have all its own custom drawing code, rather than just
wrapping a native button control? I realize much of Swing is built on the
AWT API, but does that actually mean that the Swing JButton is using the
AWT Button class?

In any case, without even looking at the code I feel positive that it's
more than a 30-minute affair to decipher what it does and how it does it.
I'd sooner just switch to using Swing and live with the
"non-look-and-feel" inconsistency than to try to reverse-engineer the
implementation. This project just doesn't warrant a large time commitment
for something like that.

Thanks,
Pete
 
R

Roedy Green

But: your page also says that I can only use the five Java logical fonts
with an AWT control. This conflicts with your statement above, "You can
do a setFont for any font installed". Can I actually do that? Or am I,
as the web page says, restricted to the five Java fonts?

Pete

I explain all this at http://mindprod.com/jgloss/font.html

the rules are different for
AWT components
AWT drawString
Swing

Then there is the matter of whether you can have anti-aliasing.

Most people use Swing nowadays where you have the most flexibility
with Fonts.
 
R

Roedy Green

Okay, I'd love to get a more definitive answer, but just for the record, I
was unable to set the font to something that would display the arrow
characters while using an AWT control.

I spend many days experimenting to sort this all out. All you need do
is read my essay. It is illogical, but not that hard to follow.
see http://mindprod.com/jgloss/font.html

I feel like a mother upset at her sons for refusing to chow down on
the food she has gone to so much effort to prepare.
 
R

Roedy Green

Fonts support a "canDisplay" method. You can use this to iterate over
available fonts to determine a set that displays the characters
you wish.

In practice, canDisplay is almost useless. It will say true if it can
display a blob.
 
R

RedGrittyBrick

Peter said:
I tried using a Swing JButton instead, and it works fine by default. I
didn't even have to set the font. The "look and feel" is actually a
little off on Windows XP...it has more of a Vista look. And on the Mac,
the auto-sizing of the button is a little different, but otherwise it
looks okay.

I guess you are referring to the results of using
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
Maybe I should just not worry so much about the question of using
native-peer AWT controls (for best user-experience consistency) and go
with the Swing controls instead.

YMMV but, rather than playing with AWT fonts, it may be better to try a
few Swing L&Fs such as the ones from JGoodies[1].

e.g.
if (System.getProperty("os.name").equals("Windows XP")) {
UIManager.setLookAndFeel(new WindowsLookAndFeel()); // JGoodies
} else if (...) {
...
} else {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}

I've not tried L&Fs for Mac etc so can't suggest a near-native L&F for
that. I'd try JGoodies [2] and look for recommendations from Mac users.

[1] Karsten Lentzsch's http://www.jgoodies.com/
[2] http://www.jgoodies.com/download/demos/looks/looksdemo.jnlp
 
W

Wayne

Peter said:
Well, that's useful information, thank you. But if I can't actually set
a font on an AWT control, I'm not sure how to take advantage of it. :(

AWT controls have a setFont method just like swing ones do:

Label l = new Label( "hi" );
Font f = new Font( ... );
l.setFont( f );

You are not limited to just five logical font names in AWT, you
can use any font that is installed.

Roedy says canDisplay doesn't always work right so maybe you should
either bundle your app with an appropriate font, use GIF arrows,
or "fake" an arrow "ligature" with ASCII art:

-->
<--

-Wayne
 
S

Stefan Ram

Peter Duniho said:
It does?
Wouldn't the Swing JButton control have all its own custom
drawing code, rather than just wrapping a native button
control?

This is possible, but still it is based on AWT to actually
do the rendering.

You could use your own custom drawing code as well (like
Swing does), for everything AWT can't do, and use AWT otherwise.

If AWT does not have a certain feature, this minimizes the
deviation from AWT.
 
P

Peter Duniho

I spend many days experimenting to sort this all out. All you need do
is read my essay. It is illogical, but not that hard to follow.
see http://mindprod.com/jgloss/font.html

All due respect, and I do appreciate you sharing your thoughts on the
page, but you directed to me to a very specific part of that page,
implying that was the information I needed. And that information said in
no uncertain terms that I could only create one of five fonts using AWT.
Even now, I can't find anything on that page that suggests I'd be able to
change the font of my AWT Button control to something that would display
the characters I want.

I _do_ however find these statements:

-- "In AWT, you are limited to the five Java logical fonts, unless you
use Canvas.drawString".
-- "AWT: limited to the 5 Java logical fonts."
-- "Peered AWT components, such as Label and TextField, can only use
Java logical fonts".

I'm not interested in subclassing any controls just so that I can use
Canvas.drawString() to display the text in the control. So again, the web
page you directed me to still seems to suggest that I cannot set the
Button control's font to any arbitrary font, and in particular I can't set
it to something that will display these characters.
I feel like a mother upset at her sons for refusing to chow down on
the food she has gone to so much effort to prepare.

I'm sorry you feel like that, but a) you never suggested there were other
parts of the page that would pertain to my question, and b) that web page
is almost 30 browser windows full (and never actually loads completely,
for that matter, though it does seem to me that all of the actual content
is present). By web standards, it's more of a novel than an essay and as
such makes you more like a mother who has prepared a 10-course meal and is
disappointed that her three-year-old couldn't even make it through the
first course.

I'm not as unappreciative as it seems I appear to be. I do appreciate the
effort. But I still don't see how your previous post is consistent with
the article you referred me to. In that situation, it's impossible to
know which to believe. I suspect the article is more accurate than your
post, given my experience here trying to set the font of the Button
control. But instead of clarification, all I'm getting is "you didn't
read the WHOLE thing." As if I had some reason to believe I needed to.

Is there a way for me to set a font other than the five Java virtual fonts
using Button.setFont()? Or not?

Thanks,
Pete
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

Positioning CSS components 1
Unicode fonts in Java 3
Custom fonts 11
Fonts 4
problem with java displaying unicode, under ms-windows 13
I need help fixing my website 2
Components 5
How can I add arrows to my FAQ 0

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top