FontMetrics генерирует исключение NullPointerException

Часть графического интерфейса, который я создаю для бухгалтерской программы на Java, должна отображать различные строки. Прежде чем отображать эту строку, она должна добавлять разрывы строк, где это необходимо. Для этого я создал класс, расширяющий 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");
}
}

Вместо «// Instatiate FontMetrics» я пробовал несколько разных вещей. Сначала я попытался создать объект FontMetrics, используя "новый"...

fm = new FontMetrics();

... только чтобы обнаружить, что вы не можете создать экземпляр FontMetrics таким образом. Я попытался получить объект FontMetrics с помощью getFontMetrics(font), получив шрифт Swing по умолчанию из ответа на этот вопрос:

Как получить шрифт по умолчанию для меток Swing JTabbedPane?

Мой код выглядел так:

fm = getFontMetrics(UIManager.getDefaults().getFont("TabbedPane.font"));

Это вызвало исключение NullPointerException. Я также пробовал:

fm = getGraphics().getFontMetrics(UIManager.getDefaults().getFont("TabbedPane.font"));

Это также дало мне исключение NullPointerException. Возможно, я не понимаю, как использовать FontMetrics. Любое понимание хорошо ценится.

Изменить: хорошо, теперь я снова попробовал два приведенных выше фрагмента, заменив UIManager.getDefaults().getFont(...) на getFont(). Выбрасывается такое же исключение NullPointerException.


person sleeparrow    schedule 13.03.2013    source источник
comment
НИКОГДА не используйте getGraphics()! Это вернет NULL, если компонент еще не был окрашен. Возможно, настройки пользовательского интерфейса по умолчанию не загружены, когда вы начинаете звонить.   -  person MadProgrammer    schedule 13.03.2013
comment
@MadProgrammer Никогда в этом случае или никогда?   -  person sleeparrow    schedule 13.03.2013
comment
На этот вопрос сложно ответить, так как он вырван из контекста. getGraphics предоставляет вам копию последнего графического контекста, который использовался для визуализации компонента. Это значение будет нулевым, если компонент никогда не отображался на экране. Это плохая практика полагаться на этот метод или вообще использовать его. Поэтому, хотя никогда не может быть немного суровым, его следует избегать.   -  person MadProgrammer    schedule 13.03.2013


Ответы (1)


Чтобы определить, в чем проблема, вы должны попытаться выделить каждую из логических строк в физической строке, выдающей исключение. Например,

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

Я подозреваю, что проблема в том, что шрифт не зарегистрирован с ключом «TabbedPane.font» в настройках пользовательского интерфейса по умолчанию. Чтобы преодолеть это, вы должны иметь возможность получить шрифт непосредственно из вашего компонента с помощью метода Component#getFont. Это действительно тот шрифт, который вам нужен в любом случае.

person Matthew T. Staebler    schedule 13.03.2013