13

Does anybody know how to get JTextArea to display a fixed size font on all platforms?

I want to make a simple code editor with save/open functionality, which is simple enough, but I would like to get font to be fixed-size, preferably courier new.

The problem is that courier new is proprietary apparently, and not only is it not installed by default on many systems, but on most modern systems, it is set to cleartype be default, which makes it look like garbage.

I am tempted to make my own JPanel with update-render-paint and reinvent the JTextArea, and save fonts as fixed-size bitmaps, but this approach appears silly, and very time consuming.

I would like to include a free fixed-size font to the project and use that font on all platforms, which appears possible. However, modern systems appear to force-smooth all fonts, which I would like to prevent it from doing.

Sadly, it appears that Swing automatically abides by system preferences so without destroying user's settings, it appears to be a no go.

So in short, is there a way to get JTextArea to display a fixed-width font and disable font smoothing/antialiasing (or at least toggle), or is this task impossible using swing?

Thanks ahead of time!

2 Answers 2

33

You can use the logical font "monospaced". While it guarantees to have a font that has the same size for all characters, it won't be the same on all platform.

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();
            }
        });

    }

}

Alternatively, you could look up a "free" font which meets your need, embed that font in with code and load it with java.awt.Font.createFont(int, InputStream).

6
  • Thanks, that answers the question, but I am still curious if I can make the monospaced font guarantee that it will not be antialiased. Is this possible?
    – Dmytro
    Commented Apr 29, 2013 at 13:37
  • 2
    @Dmitry There are several ways to disable anti-aliasing: 1) System.setProperty("awt.useSystemAAFontSettings","false"); System.property("swing.aatext", "false"); 2) You can set the RenderingHints on the Graphics` object of the paintComponent method to disable TEXT_ANTI_ALIASING (((Graphics2D)g).setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, Boolean.FALSE); but you won't have an absolute guarantee that someone is not going to change that afterwards. Commented Apr 29, 2013 at 13:49
  • I'm not worried about change afterwords, I'm worried about default settings :). Thanks a lot!
    – Dmytro
    Commented Apr 29, 2013 at 13:52
  • 1
    @Dmitry Small correction, you can't use Boolean.FALSE for the hint value. Use RenderingHints.VALUE_TEXT_ANTIALIAS_OFF instead. Sorry about that. Commented Apr 29, 2013 at 13:56
  • 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"); Add all of those in a JPanel, add the wraping code and you are done. Commented Apr 29, 2013 at 16:31
2

I came close to a solution by using JTextPane instead of JTextArea by setting the content type of the JTextPane to text/html and setting the text as a html content.

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> tag is making the text monospaced and all white spaces and new line characters of the text have replaced with html space entity and <br> tag, respectively. I tested the output in both Windows and Ubuntu OSes and they were same.

Not the answer you're looking for? Browse other questions tagged or ask your own question.