Reputation: 4477
I'm having a problem displaying certain glyphs from the FontAwesome collection in buttons in a Swing JToolBar. Here is a screenshot to illustrate (notice that the top button in the toolbar on the right hand side is not a nice icon but instead shows three empty rectangles):
The code to reproduce this (at least on my Mac) is:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;![enter image description here][2]
import java.awt.FontFormatException;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JToolBar;
public class TestFontAwesome {
public static void main(String[] args) {
new TestFontAwesome();
}
public TestFontAwesome() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try (InputStream is = TestFontAwesome.class.getResourceAsStream("/fontawesome-webfont_old.ttf")) {
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
font = font.deriveFont(Font.PLAIN, 24f);
JToolBar toolBar = new JToolBar(JToolBar.VERTICAL);
JButton button1 = new JButton("\uf00e");
button1.setFont(font);
toolBar.add(button1);
JButton button2 = new JButton("\uf01e");
button2.setFont(font);
toolBar.add(button2);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new JButton("Irrelevant content..."));
frame.add(toolBar, BorderLayout.EAST);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException | FontFormatException exp) {
exp.printStackTrace();
}
}
});
}
}
I tried a few things: (1) Using different versions of the FontAwesome.ttf file, no change; (2) Trying different JDK versions, no change; (3) Displaying the same character in a regular JButton, this works as you can see in the following screenshot (so this is clearly not some issue with the font file):
I tested on a non-Retina Mac and everything works, so I wonder if this is something specific to the Retina display. If anyone has any suggestions I'd appreciate hearing from you, thanks.
The code for the JButton only example (that works fine) is:
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontFormatException;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.JButton;
import javax.swing.JFrame;
public class TestFontAwesome2 {
public static void main(String[] args) {
new TestFontAwesome2();
}
public TestFontAwesome2() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try (InputStream is = TestFontAwesome.class.getResourceAsStream("/fontawesome-webfont_old.ttf")) {
Font font = Font.createFont(Font.TRUETYPE_FONT, is);
font = font.deriveFont(Font.PLAIN, 24f);
JButton button1 = new JButton("\uf00e");
button1.setFont(font);
JButton button2 = new JButton("\uf01e");
button2.setFont(font);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(new JButton("Irrelevant content..."));
frame.add(button1);
frame.add(button2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException | FontFormatException exp) {
exp.printStackTrace();
}
}
});
}
}
Upvotes: 9
Views: 1039
Reputation: 3518
i think the problem is the ComponentUi
Means in special: ToolbarUi or ButtonUi (-Implementation).
ToolbarUi (and ButtonUi) are abstract classes, which are implemented in your selected LookAndFeel.
The Implementation can be totally different for each LookAndFeel.
Some Implementations do ignore some "user" settings like e.g Font or Color.
JButtons can use a different Ui-Implementation than Buttons which are added to JToolBars!
And this Implementation may ignore your Font settings.
See for example ButtonUi Implementation (only part of) in MetalLookAndFeel
public void update(Graphics g, JComponent c) {
AbstractButton button = (AbstractButton)c;
if ((c.getBackground() instanceof UIResource) &&
button.isContentAreaFilled() && c.isEnabled()) {
ButtonModel model = button.getModel();
if (!MetalUtils.isToolBarButton(c)) {
if (!model.isArmed() && !model.isPressed() &&
MetalUtils.drawGradient(
c, g, "Button.gradient", 0, 0, c.getWidth(),
c.getHeight(), true)) {
paint(g, c);
return;
}
}
...
Here you can see the different behaviour when MetalUtils.isToolbarButton
You have to check your LookAndFeel Implementation behaviour.
(Maybe there is also a different Implementation, depending the screen resolution)
Upvotes: 4