Why does JTextPane.setFont(null) sets monospaced font?

65 Views Asked by At

I encountered a somewhat strange behaviour of Java Swing JTextPane. Why does JTextPane.setFont(null) sets monospaced font? It's totally illogical. I found it when I tried to debug JTextPane.setFont(Font.getFont(Font.MONOSPACED)), and it turned out that Font.getFont returns null.

Edit: when I getFont() after setting null, it returns java.awt.Font[family=Lucida Grande,name=Lucida Grande,style=plain,size=13], and I dont't think that it is monospaced.

2

There are 2 best solutions below

7
jetbrain_icin icin On

When you call setFont(null) on a JTextPane, it sets the font to the default font of the JTextPane's parent container. If the parent container does not have a default font set, then it will use a default font that is usually monospaced.

0
MadProgrammer On

Calling setFont with null will set the component's font property to null. The Swing designers obviously felt that this was a suitable solution and allowed getFont instead to return the parent container's Font (or null if the component didn't have a parent, in which case, it won't be painted, so it probably doesn't matter)

Font font = this.font;
if (font != null) {
    return font;
}
Container parent = this.parent;
return (parent != null) ? parent.getFont_NoClientCode() : null;

Just to be clear, on my system, doing the above will result in a Font of null until the frame is realised, after which it will return com.apple.laf.AquaFonts$DerivedUIResourceFont[family=Lucida Grande,name=Lucida Grande,style=plain,size=13]. This is most likely coming from the Look and Feel.

In the case of the JTextPane, there's additional layer, the StyledDocument.

So, on my system, UIManager.getFont("TextPane.font") will return com.apple.laf.AquaFonts$DerivedUIResourceFont[family=Lucida Grande,name=Lucida Grande,style=plain,size=13]

StyledDocument doc = textPane.getDefaultRootElement().getAttributes();
System.out.println(doc.getFont(attributes));

Will print javax.swing.plaf.FontUIResource[family=Monospaced,name=Monospaced,style=plain,size=12] regardless of the font state of the JTextPane.

Sooo, observationally (as I'm not going to dig into the Look and Feel classes), if the font property is set on the JTextPane, it will override the StyledDocument's root element's Font value (which, based on stepping through the code default's to Monospaced if no Font attribute exists)

Sooo, the answer is, it's complicated and may be different on different platforms based on the implementations/interactions of the Look and Feel.