【问题标题】:Differences in JLabel when loading ttf font between Windows and LinuxWindows 和 Linux 加载 ttf 字体时 JLabel 的差异
【发布时间】:2013-04-24 15:08:23
【问题描述】:

我正在使用以下代码在 java 中上传 aller 字体:

private Font loadFont(final String path) {
    Font font = null;

    InputStream fontFile = null;
    fontFile = FontLoaderClass.class.getResourceAsStream(path);

    if (fontFile != null) {
        try {
            font = Font.createFont(Font.PLAIN, fontFile);
        } catch (FontFormatException e) {
            LOGGER.error("Error with font format {}", e);
        } catch (IOException e) {
            LOGGER.error("Error accessing font {}", e);
        }
    }
    return font;
}

字体加载正确:

http://www.fontsquirrel.com/fonts/Aller

字体设置为全部“.font”,更改 java 应用程序的默认设置,但在 Linux 中显示正确,但 Windows 不正确。

private Font buildFont(final String key, final int size) {
    Font f = loadFont(ALLER_LT_FONT_PATH);
    GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(f);
    if (f == null) {
        f = (Font) UIManager.get(key);
    }
    f = f.deriveFont(Font.TRUETYPE_FONT, size);
    return f;
}

Linux 显示:

Windows 显示:

正如您在图像中看到的那样,Windows 中存在一些截断,导致图像无法正确显示。

以前有人遇到过这个问题吗?

【问题讨论】:

  • 我看不出有什么问题...它们看起来一样,只是 Windows 上的标签似乎有点大。
  • 在windows中显然不像在linux中那样流畅。
  • 1.在这种情况下,请使用 PNG 图像而不是 JPEG。 2. 确定不是system cleartype settings造成的?
  • 它们是字体,而不是图像

标签: java swing fonts jlabel truetype


【解决方案1】:

我之前也遇到过类似的问题,直到我在 SourceForge 找到这个名为 Smooth Metal 的库,你可以从 Here 下载它

图书馆首页Smooth Metal

Smooth Metal 外观和感觉是对某些外观和感觉的补充,包括 Java,使用 anti-aliased text 增强它们。

您会注意到 Windows 中的 ClearType 选项不会影响结果...

在类路径中添加库的 jar 文件后,我编写了这个小型 java 应用程序,它渲染 JLabel 并使用两个 JButtons 撤消渲染,结果非常清晰:

这是你可以测试的代码:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.plaf.basic.BasicLabelUI;
import smoothmetal.SmoothLabelUI; // UI Class to set for the JLabel


public class LabelRender extends JFrame{

    JPanel panel = new JPanel();
    JPanel panel2 = new JPanel();
    JButton button = new JButton("RENDER");
    JButton button2 = new JButton("UNDO");
    JLabel label = new JLabel("HELLO WORLD");

    public LabelRender(){
        setSize(600, 250);
        setLocationRelativeTo(null);
        setTitle("JLabel Renderer");


        setLayout(new BorderLayout());

        label.setFont(new Font("Aller", Font.PLAIN, 70));
        label.setForeground(Color.WHITE);

        panel.add(label);
        panel2.add(button);
        panel2.add(button2);

        panel.setBackground(Color.BLACK);

        this.add(panel2, BorderLayout.NORTH );
        this.add(panel,BorderLayout.CENTER);

        setVisible(true);
        validate();


       // System.out.println(label.getUI());

        button.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                label.setUI(new SmoothLabelUI());
            }
        });

        button2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                label.setUI(new BasicLabelUI());
            }
        });

    }

    public static void main(String args[]){
        new LabelRender();
    }
}

【讨论】:

  • 嗨,当您以java -cp .;smoothmetal.jar -Dawt.useSystemAAFontSettings=on LabelRender 运行您的示例时,它确认了我在第一个示例中提到的内容:“如果 AA 默认开启,您必须将其设置为“关闭”,否则您无法切换它在应用程序中”欢呼,弗兰克
【解决方案2】:

找到两个附加的小演示,它们分别为 Swing 组件启用抗锯齿以进行绘图操作。

用于 Swing 组件

// to enable antialiasing (AA) for Swing components
//
// either:
//    start the JVM with the option -Dawt.useSystemAAFontSettings=on
//    see also: http://docs.oracle.com/javase/6/docs/technotes/guides/2d/flags.html#aaFonts
// or:
//    System.setProperty("awt.useSystemAAFontSettings", "on");
//    - you must call it before the first Swing component is rendered
//    - if AA it's on by default you must set it "off", otherwise you can't
//      toggle it inside the application

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import static java.awt.RenderingHints.KEY_ANTIALIASING;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_OFF;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON;

public class SwingAntiAliasingDemo {

    public static void main(String[] args) {
        System.setProperty("awt.useSystemAAFontSettings", "off");
        initGui();
    }

    public static void initGui() {
        JFrame frame = new JFrame();

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });

        Font font = new Font("Serif", Font.TRUETYPE_FONT, 96);
        JPanel jpanel = new JPanel(new BorderLayout());

        JLabel labelAA = new JLabel("Antialiasing ON") {
            @Override
            public void paintComponent(Graphics g) {
                Graphics2D graphics2d = (Graphics2D) g;
                graphics2d.setRenderingHint(KEY_ANTIALIASING,
                        VALUE_ANTIALIAS_ON);
                super.paintComponent(g);
            }
        };
        labelAA.setFont(font);
        labelAA.setForeground(Color.WHITE);

        JLabel labelNoAA = new JLabel("Antialiasing OFF") {
            @Override
            public void paintComponent(Graphics g) {
                Graphics2D graphics2d = (Graphics2D) g;
                graphics2d.setRenderingHint(KEY_ANTIALIASING,
                        VALUE_ANTIALIAS_OFF);
                super.paintComponent(g);
            }
        };
        labelNoAA.setFont(font);
        labelNoAA.setForeground(Color.WHITE);

        jpanel.setBackground(new Color(0, 22, 95));
        jpanel.add(labelAA, BorderLayout.NORTH);
        jpanel.add(labelNoAA, BorderLayout.SOUTH);

        frame.setTitle("stackoverflow question 16304254");
        frame.getContentPane().add(jpanel);
        frame.setLocation(200, 200);
        frame.pack();
        frame.setResizable(false);
        frame.setVisible(true);
    }
}

用于绘制操作

// to enable antialiasing (AA) for draw operations

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;

import static java.awt.RenderingHints.KEY_ANTIALIASING;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_OFF;
import static java.awt.RenderingHints.VALUE_ANTIALIAS_ON;

public class DrawAntiAliasingDemo extends JFrame {

    private Font font;
    private Color backGroundColor;

    public static void main(String[] args) {
        new DrawAntiAliasingDemo();
    }

    public DrawAntiAliasingDemo() {
        font = new Font("Serif", Font.TRUETYPE_FONT, 96);
        backGroundColor = new Color(0, 22, 95);
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent we) {
                System.exit(0);
            }
        });

        setTitle("stackoverflow question 16304254");
        setSize(850, 260);
        setResizable(false);
        setVisible(true);
    }

    @Override
    public void paint(Graphics g) {
        Graphics2D d = (Graphics2D) g;
        d.setColor(backGroundColor);
        d.fillRect(0, 0, getWidth(), getHeight());
        d.setFont(font);
        d.setPaint(Color.white);

        d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
        d.drawString("Antialiasing ON", 10, 115);

        d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_OFF);
        d.drawString("Antialiasing OFF", 10, 230);
    }
}

干杯 弗兰克

【讨论】:

  • 根据 JAVA 文档(您的链接),默认情况下“awt.useSystemAAFontSettings”是打开的,我刚刚对其进行了测试,我的桌面设置显然表明应该使用 AA。这是您没有 System.setProperty 的第一个示例,它为我显示了相同的标签。所以我想这种行为是可以的。如果 RamonBoza 想确保他的应用程序使用 AA 而不管桌面设置如何,他应该使用 JVM 参数解决方案,这似乎是最简单的。
  • @Trilarion JVM 会自动检查操作系统是否支持 AA。可以使用System.out.println(Toolkit.getDefaultToolkit().getDesktopProperty("awt.font.desktophints")); 进行交叉检查。JVM 选项“-Dawt.useSystemAAFontSettings=on”强制启用 AA 支持(使用操作系统默认设置)。如果您想使用其他设置,您可以使用 javadoc 链接下描述的其中一个可能的值。
【解决方案3】:

在我看来,Windows 操作系统没有使用 ClearType。 ClearType 是一个选项,启用后它会平滑字体。有时出于调整或性能原因禁用它。见http://support.microsoft.com/kb/306527。尝试启用它。

将 ClearType 用于屏幕字体:

  1. 单击开始,单击控制面板,单击外观和主题,然后 然后单击显示。
  2. 在外观选项卡上,单击效果。
  3. 单击选中“使用以下方法平滑屏幕字体边缘”复选框,然后单击列表中的 ClearType。

【讨论】:

猜你喜欢
  • 2018-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
  • 1970-01-01
  • 1970-01-01
  • 2017-02-02
相关资源
最近更新 更多