Java FontMetrics生成NullPointerException

Java FontMetrics生成NullPointerException,java,null,nullpointerexception,fontmetrics,Java,Null,Nullpointerexception,Fontmetrics,我为Java簿记程序创建的GUI的一部分需要显示不同的字符串。在显示此字符串之前,必须在适当的位置添加换行符。为此,我创建了一个扩展JTextArea的类,并重写了setText()方法: public class ContentPane extends JTextArea { private FontMetrics fm; public ContentPane() { super(); // Instatiate FontMetrics } public ContentP

我为Java簿记程序创建的GUI的一部分需要显示不同的字符串。在显示此字符串之前,必须在适当的位置添加换行符。为此,我创建了一个扩展JTextArea的类,并重写了setText()方法:

public class ContentPane extends JTextArea {

private FontMetrics fm;

public ContentPane() {
    super();
    // Instatiate FontMetrics
}

public ContentPane(String string) {
    super(string);
    // Instatiate FontMetrics
}

@Override
public void setText(String text) {
    int n;
    String remainder;

    while (fm.stringWidth(text) > maxStringWidth()) {
        n = numberOfCharsToCut(text);
        remainder = text.substring(text.length() - n);
        text = text.substring(0, text.length() - n) + "\n" + remainder;
    }

    super.setText(text);
}

private int numberOfCharsToCut(String str) {
    String newStr = str;
    int i = 0;
    while (fm.stringWidth(newStr) > maxStringWidth()) {
        newStr = str.substring(0, str.length() - i);
        i++;
    }
    return i;
}

private int maxStringWidth() {
    return fm.stringWidth("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@lll");
}
}
我尝试了几种不同的方法来代替“//Instatitate FontMetrics”。起初,我尝试使用“new”创建FontMetrics对象

…却发现无法以这种方式实例化FontMetrics。我尝试使用getFontMetrics(字体)检索FontMetrics对象,从以下问题的答案中获取默认的swing字体:

我的代码如下所示:

fm = getFontMetrics(UIManager.getDefaults().getFont("TabbedPane.font"));
这引发了NullPointerException。我还尝试:

fm = getGraphics().getFontMetrics(UIManager.getDefaults().getFont("TabbedPane.font"));
这也给了我一个NullPointerException。也许我不了解如何使用FontMetrics。任何见解都值得赞赏


编辑:好的,现在我又尝试了上面的两个代码段,用getFont()替换UIManager.getDefaults().getFont(…)。抛出相同的NullPointerException。

若要确定问题所在,应尝试将引发异常的物理行中的每个逻辑行分离出来。比如说,

UIDefaults uiDefaults = UIManager.getDefaults();
Font font = uiDefaults.getFont("TabbedPane.font");
Graphics graphics = getGraphics();
fm = graphics.getFontMetrics(font);

我怀疑问题在于UI默认值中没有使用“TabbedPane.font”键注册的字体。为了克服这个问题,您应该能够通过
组件#getFont
方法直接从组件获取字体。这确实是您想要的字体。

永远不要使用getGraphics()!如果组件尚未绘制,则返回NULL。当您开始进行调用时,可能没有加载UI默认值。@在这种情况下,程序员从未加载过,或者从未加载过?这是一个很难回答的问题,因为它脱离了上下文
getGraphics
为您提供用于渲染组件的上一个图形上下文的副本。如果组件从未被渲染到屏幕,则该值将为null。依赖或普遍使用这种方法是一种不好的做法。因此,虽然“从不”可能有点苛刻,但通常应该避免。
UIDefaults uiDefaults = UIManager.getDefaults();
Font font = uiDefaults.getFont("TabbedPane.font");
Graphics graphics = getGraphics();
fm = graphics.getFontMetrics(font);