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):
我在Swing JToolBar中的按钮中显示FontAwesome集合中的某些字符时遇到了问题。下面是一个截图(注意右边工具栏的顶部按钮不是一个很好的图标,而是显示了三个空的矩形):
The code to reproduce this (at least on my Mac) is:
复制这个(至少在我的Mac上)的代码是:
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):
我尝试了一些东西:(1)使用不同版本的FontAwesome。ttf文件,没有变化;(2)尝试不同的JDK版本,没有变化;(3)在普通的JButton中显示相同的字符,如下面的截图所示(显然这不是字体文件的问题):
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.
我在一个非视网膜的Mac电脑上做了测试,一切都很正常,所以我想知道这是不是视网膜显示屏特有的东西。如果有人有什么建议,我希望能收到你的来信,谢谢。
The code for the JButton only example (that works fine) is:
JButton only示例(运行良好)的代码是:
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();
}
}
});
}
}
1 个解决方案
#1
4
i think the problem is the ComponentUi
Means in special: ToolbarUi or ButtonUi (-Implementation).
我认为问题在于ComponentUi在special中的意思:ToolbarUi或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.
ToolbarUi(和ButtonUi)是抽象类,在选定的LookAndFeel中实现。每个外观的实现可能完全不同。有些实现确实忽略了一些“用户”设置,如e。g字体或颜色。
JButtons can use a different Ui-Implementation than Buttons which are added to JToolBars!
And this Implementation may ignore your Font settings.
JButtons可以使用与添加到JToolBars中的按钮不同的ui实现!这个实现可能会忽略字体设置。
See for example ButtonUi Implementation (only part of) in MetalLookAndFeel
参见MetalLookAndFeel中的ButtonUi实现(仅为部分)
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
在这里,您可以看到当MetalUtils.isToolbarButton时的不同行为
You have to check your LookAndFeel Implementation behaviour.
(Maybe there is also a different Implementation, depending the screen resolution)
您必须检查外观和感觉实现行为。(根据屏幕分辨率,可能还有不同的实现)
#1
4
i think the problem is the ComponentUi
Means in special: ToolbarUi or ButtonUi (-Implementation).
我认为问题在于ComponentUi在special中的意思:ToolbarUi或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.
ToolbarUi(和ButtonUi)是抽象类,在选定的LookAndFeel中实现。每个外观的实现可能完全不同。有些实现确实忽略了一些“用户”设置,如e。g字体或颜色。
JButtons can use a different Ui-Implementation than Buttons which are added to JToolBars!
And this Implementation may ignore your Font settings.
JButtons可以使用与添加到JToolBars中的按钮不同的ui实现!这个实现可能会忽略字体设置。
See for example ButtonUi Implementation (only part of) in MetalLookAndFeel
参见MetalLookAndFeel中的ButtonUi实现(仅为部分)
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
在这里,您可以看到当MetalUtils.isToolbarButton时的不同行为
You have to check your LookAndFeel Implementation behaviour.
(Maybe there is also a different Implementation, depending the screen resolution)
您必须检查外观和感觉实现行为。(根据屏幕分辨率,可能还有不同的实现)