如何让JTextArea显示固定宽度的字体但不启用抗锯齿

13

有人知道如何使JTextArea在所有平台上显示固定大小的字体吗?

我想制作一个带有保存/打开功能的简单代码编辑器,这很简单,但是我希望字体是固定大小的,最好使用Courier New。

问题是Courier New显然是专有的,而且它并不是所有系统默认安装的字体,大多数现代系统将其设置为默认的ClearType,这使得它看起来很糟糕。

我想自己制作带有更新-渲染-绘制功能的JPanel,重新发明JTextArea,并将字体保存为固定大小的位图,但这种方法似乎很傻,而且非常耗时。

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

遗憾的是,Swing自动遵守系统首选项,因此如果不破坏用户的设置,似乎不行。

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

提前谢谢!

2个回答

33

你可以使用逻辑字体“monospaced”。虽然它保证了所有字符具有相同的大小,但在所有平台上它们不会完全一样。

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)加载它。

另外,您可以寻找符合您需求的“免费”字体,在代码中嵌入该字体并使用java.awt.Font.createFont(int, InputStream)进行加载。


谢谢,这回答了我的问题,但我仍然想知道是否可以让等宽字体保证不进行抗锯齿处理。这可行吗? - Dmytro
2
@Dmitry 有几种方法可以禁用抗锯齿:1)System.setProperty("awt.useSystemAAFontSettings","false"); System.property("swing.aatext",“false”); 2)您可以在paintComponent方法的Graphics对象上设置RenderingHints以禁用TEXT_ANTI_ALIASING(((Graphics2D)g)。setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,Boolean.FALSE);),但您不能绝对保证以后不会更改。 - Guillaume Polet
我不担心事后的更改,我担心默认设置:)。非常感谢! - Dmytro
1
@Dmitry 小更正,您不能使用 Boolean.FALSE 作为提示值。请改用 RenderingHints.VALUE_TEXT_ANTIALIAS_OFF。对此我感到抱歉。 - Guillaume Polet
谢谢:),我已经解决了。虽然现在我正在与查找字体选择器进行斗争,因为它不是Java默认包含的。 - Dmytro
3
将以下代码翻译成中文: @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 中,添加必要的代码并完成。 - Guillaume Polet

2

我通过使用JTextPane 代替 JTextArea ,将JTextPane 的内容类型设置为text/html,并将文本设置为html格式,接近了一个解决方案。

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>"                
        + "");

<tt> 标签使文本变得等宽,并将所有空格和换行字符替换为 HTML 的空格实体<br> 标签。我在 Windows 和 Ubuntu 操作系统中测试了输出结果,它们是相同的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接