Графическое исключение NullPointerException при переопределении встроенного метода рисования холста

#java #canvas #awt

#java #холст #awt

Вопрос:

Итак, я пытаюсь создать холст и переопределить встроенный метод рисования, однако я получаю исключение NullPointerException для графики холста.

 Canvas c = new Canvas(){
    @Override
    public void paint(Graphics g){
        g.setColor(Color.BLACK);
        g.drawString("Canvassed Window", 100, 100);
    }
};
  

Исключение NullPointerException выполняется для

 g.setColor(Color.BLACK);
  

Я просто собираюсь создать новый класс, который наследуется от Canvas, но мне было интересно, знает ли кто-нибудь причину, по которой он это делает. У меня есть подозрение, что это связано с тем, что холст еще не инициализирован.

Мне также было интересно, знает ли кто-нибудь обходной путь для этого, я попытался написать что-то похожее

 private boolean isInit = false;
init(){
    isInit = true;
}
  

а затем в методе рисования вверху поместите строку с надписью

 if(!isInit) return;
  

но когда я попытался вызвать init позже, он не захотел знать, он просто выдал ошибку и сказал, что init не находится в классе Canvas, я предполагаю, что я могу переопределять методы только таким образом.

Редактировать:

У меня есть класс Window

 import java.awt.Canvas;
import java.awt.Frame;

@SuppressWarnings("serial")
public class Window extends Frame{

    public Window(int width, int height, int locationX, int locationY) {
        setSize(width, height);
        setLocation(locationX, locationY);
        setResizable(false);
        setTitle("Window");
        setVisible(true);
    }
    public Window(int width, int height, int locationX, int locationY, String title){
        Window w = new Window(width, height, locationX, locationY);
        w.setTitle(title);
    }
    public Window(int width, int height, int locationX, int locationY, String title, Canvas c){
        Window w = new Window(width, height, locationX, locationY, title);
        w.add(c);
    }

} 
  

И вот мой основной метод, в котором я создаю новый экземпляр окна:

 public static void main(String[] args){
    Canvas c = new Canvas(){
        @Override
        public void paint(Graphics g){
            g.setColor(Color.BLACK);
            g.drawString("Canvassed Window", 100, 100);
        }
    };
    new Window(800, 600, 200, 100, "CanvassedWindow", c);
}
  

Я получаю окно или «рамку», правильный размер, размеры и заголовок, однако, похоже, он не рисует строку, и есть NPE. Я больше ничего не делаю, все, что у меня есть, это класс-оболочка для моего основного метода.

Комментарии:

1. В вашей проблеме и вашем коде больше, чем вы нам показываете. Этот код не должен вызывать NPE, если он не используется странным образом. Также в качестве побочного вопроса, почему AWT, а не Swing?

2. Пожалуйста, покажите нам минимальный рабочий пример, который воспроизводит проблему.

3. Как вы звоните paint() ?

4. AWT устарел на 15 лет, он был заменен Swing более 15 лет назад, да, некоторое понимание того, как работает AWT, может помочь, но я бы не стал моим первым пунктом вызова. Используете ли вы getGraphics и пытаетесь вызвать paint самостоятельно?

5. У вас есть конструктор, создающий экземпляр самого себя, что является очень опасным кодом, и поэтому ваш код создает два окна. Я почти уверен, что вы не хотите делать то, что делаете. Возможно, вы хотите this(...) вместо этого вызвать более стандартный конструктор. Ваш код не должен вызывать NPE, который вы описываете, и поэтому загадка продолжается.

Ответ №1:

Итак, основываясь на вашем примере, Window класс создаст три новых окна, из которых будет видно только одно, а не то, к которому вы добавляете свое Canvas

При вызове new Window(800, 600, 200, 100, "CanvassedWindow", c); создается новый экземпляр Window ( JFrame ), это окно #1, но оно не отображается…

Затем public Window(int width, int height, int locationX, int locationY, String title, Canvas c) конструктор создает другой экземпляр Window ( JFrame ), это окно # 2, но оно не отображается…

Затем это вызывает public Window(int width, int height, int locationX, int locationY, String title) , который создает другой Window , который на самом деле является видимым…

Это связано с тем, что конструктор Window w = new Window(width, height, locationX, locationY); является единственным, который фактически устанавливает свойства фрейма и делает его видимым…

Вероятно, это приводит к каким-то странным paths…it конечно, для меня это было так…

Вместо этого вы должны связывать свои конструкторы, например…

 public class Window extends Frame{

    public Window(int width, int height, int locationX, int locationY) {
        setSize(width, height);
        setLocation(locationX, locationY);
        setResizable(false);
        setTitle("Window");
        setVisible(true);
    }
    public Window(int width, int height, int locationX, int locationY, String title){
        this(width, height, locationX, locationY);
        setTitle(title);
    }
    public Window(int width, int height, int locationX, int locationY, String title, Canvas c){
        this(witdth, height, locationX, locationY, title);
        add(c);
    }

}