Некоторые символы FontAwesome не отображаются в кнопках Java Swing JToolBar

у меня проблема с отображением определенных глифов из коллекции FontAwesome в кнопках в Swing JToolBar. Вот скриншот для иллюстрации (обратите внимание, что верхняя кнопка на панели инструментов с правой стороны не является хорошим значком, а вместо этого показывает три пустых прямоугольника):

Screenshot to illustrate the problem

код для воспроизведения этого (по крайней мере, на моем 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();
                }
            }
        });
    }

}

я попробовал несколько вещей: (1) Используя разные версии FontAwesome.ttf файл, нет (2) попытка различных версий JDK, без изменений; (3) отображение одного и того же символа в обычной JButton, это работает, как вы можете видеть на следующем скриншоте (так что это явно не какая-то проблема с файлом шрифта):

Screenshot to show it works in a regular JButton

Я тестировал на Mac без сетчатки, и все работает, поэтому мне интересно, является ли это чем-то специфическим для дисплея Retina. Если у кого-то есть какие-либо предложения, я был бы признателен, услышав от вас, спасибо.

код только для JButton пример (который отлично работает):

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 ответов


Я думаю, что проблема заключается в ComponentUi
Средства в специальном: ToolbarUi или ButtonUi (- реализация).

ToolbarUi (и ButtonUi) являются абстрактными классами, которые реализованы в выбранном LookAndFeel.
Реализация может быть совершенно разной для каждого виду.
Некоторые реализации игнорируют некоторые" пользовательские " настройки, такие как e.g шрифт или цвета.

JButtons может использовать другой Ui-реализация, чем кнопки, которые добавляются в JToolBars!
И эта реализация может игнорировать настройки шрифта.

см., например, реализацию ButtonUi (только часть) в 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;
           }
       }
...

здесь вы можете увидеть различное поведение при MetalUtils.isToolbarButton

вы должны проверить свое поведение реализации LookAndFeel.
(Возможно, есть и другая реализация, в зависимости от разрешения экрана)