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