让 JTextArea 显示固定宽度的字体而不进行抗锯齿

Posted

技术标签:

【中文标题】让 JTextArea 显示固定宽度的字体而不进行抗锯齿【英文标题】:Getting JTextArea to display fixed-width font without antialiasing 【发布时间】:2013-04-23 04:28:11 【问题描述】:

有谁知道如何让 JTextArea 显示固定大小 所有平台上的字体?

我想制作一个具有保存/打开功能的简单代码编辑器, 这很简单,但我想让字体成为 固定大小,最好是快递新的。

问题是 courier new 显然是专有的,而不是 只是它不是默认安装在许多系统上,而是在大多数系统上 现代系统,默认设置为 cleartype,这使得 看起来像垃圾。

我很想用 update-render-paint 和 重新发明 JTextArea,并将字体保存为固定大小的位图,但是 这种方法看起来很愚蠢,而且非常耗时。

我想在项目中包含一个免费的固定大小字体,并且 在所有平台上使用该字体,这似乎是可能的。然而, 现代系统似乎强制平滑所有字体,我会 喜欢阻止它这样做。

遗憾的是,Swing 似乎自动遵守系统偏好 所以在不破坏用户设置的情况下,这似乎是不行的。

简而言之,有没有办法让 JTextArea 显示固定宽度 字体并禁用字体平滑/抗锯齿(或至少切换),或 这个任务用 swing 是不可能的吗?

提前谢谢!

【问题讨论】:

【参考方案1】:

您可以使用逻辑字体“等宽”。虽然它保证所有字符都具有相同大小的字体,但它不会在所有平台上都相同。

import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class TestTextArea 

    private void initUI() 
        JFrame frame = new JFrame("test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JTextArea textArea = new JTextArea(24, 80);
        textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 12));
        frame.add(new JScrollPane(textArea));
        frame.pack();
        frame.setVisible(true);
    

    public static void main(String[] args) 
        SwingUtilities.invokeLater(new Runnable() 
            @Override
            public void run() 
                new TestTextArea().initUI();
            
        );

    


或者,您可以查找满足您需要的“免费”字体,将该字体与代码一起嵌入并使用java.awt.Font.createFont(int, InputStream) 加载它。

【讨论】:

谢谢,这回答了这个问题,但我仍然很好奇我是否可以让等宽字体保证它不会被抗锯齿。这可能吗? @Dmitry 有几种方法可以禁用抗锯齿: 1) System.setProperty("awt.useSystemAAFontSettings","false"); System.property("swing.aatext", "false"); 2) You can set the RenderingHints on the Graphics 对象的 paintComponent 方法禁用 TEXT_ANTI_ALIASING (((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, Boolean.FALSE); 但你不会有绝对保证以后不会有人改变。 我不担心更改后记,我担心默认设置:)。非常感谢! @Dmitry 小修正,提示值不能使用Boolean.FALSE。请改用RenderingHints.VALUE_TEXT_ANTIALIAS_OFF。对此感到抱歉。 @Dmitry JComboBox cb = new JComboBox(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames()); JSpinner spinner = new JSpinner(new SpinnerNumberModel(12, 4, 240, 1)); JCheckBox italic = new JCheckBox("Italic"); JCheckBox bold = new JCheckBox("Bold"); 将所有这些添加到 JPanel 中,添加包装代码就完成了。【参考方案2】:

通过将JTextPane 的内容类型设置为text/html 并将文本设置为html 内容,我使用JTextPane 而不是JTextArea 接近了解决方案。

JtextPane textPane;
String text;

// initialization

textPane.setContentType("text/html");
textPane.setText(""
        + "<html>"
        + "<body>"
        + "<p>"
        + "<tt>"+text.replaceAll(" ", "&nbsp;").replaceAll("\n", "<br>")+"</tt>"
        + "</p>"
        + "</body>"
        + "</html>"                
        + "");

&lt;tt&gt; 标记使文本 等宽 并且 text 的所有空格和换行符已分别替换为 html space entity 和 &lt;br&gt; 标记。我在 Windows 和 Ubuntu 操作系统中测试了输出,它们是相同的。

【讨论】:

以上是关于让 JTextArea 显示固定宽度的字体而不进行抗锯齿的主要内容,如果未能解决你的问题,请参考以下文章

如何创建具有指定宽度和显示所有文本所需的最小高度的 JTextArea?

如何缩小字体以适应 Android 中视图的内部宽度?

为我的所有 Jlabels JTextArea 等设置通用字体大小

固定宽度字体 - 用于用户界面

SVG、文本、固定宽度/高度的字体

如何把android textView字体大小固定写死,而不随系统设置字体大小的改变而改变。