поэтому я пробовал библиотеку java.awt.Graphics и столкнулся с проблемой в своем коде. Приведенный ниже код возвращает исключение нулевого указателя, поскольку объект Graphics "g" не определен во время выполнения. Я мог бы зациклить вызов и проверить, если g != null, но есть ли лучший способ сделать это?
Спасибо за любую помощь.
Это мой код:
package gui;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Gui extends JPanel{
Graphics g;
public Gui()
{
JFrame frame = new JFrame("test");
frame.setSize(700, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(this);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.g = g;
g.setColor(Color.blue);
for(int x = 0;x < 700; x += 20)
{
g.drawLine(x, 0, x, 700);
}
for(int y = 0;y < 700; y += 20)
{
g.drawLine(0, y, 700, y);
}
}
public void draw(Tuple xy)
{
g.setColor(Color.blue); // <--- null pointer exception
g.fillOval(xy.x, xy.y, 5, 5);
}
}
и основной класс:
package gui;
public class Main {
public static void main(String[] args)
{
new Gui().draw(new Tuple(200,200)); //Tuple is a custom class I wrote
}
}
И как мне снова запустить метод paintComponent, чтобы проверить, обновился ли Tuple?
Звоните, перекрашивайте...




Вы должны сделать весь рисунок на
public void paintComponent(Graphics g)
как указано в https://docs.oracle.com/javase/tutorial/uiswing/painting/problems.html.
Используйте функцию обратного вызова. Намного лучше, чем polling недвижимость. И вы получаете свежий графический объект. И ваш вызов выполняется в правильном контексте.
Вот общая идея:
new Gui((Graphics graphics)-> {
// your code here
});
public Gui(GraphicsCallback callback)
Вызовите обратный вызов. Вы можете проверить, вызывается ли он, и только один раз выполнить обратный вызов, если это подходит для вашего варианта использования. Или реализация обратного вызова может управлять многократным вызовом.
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.g = g;
this.callback(g)
Нашел решение своей нулевой проблемы. Я изменил метод «draw()», чтобы он принимал кортеж, а затем передал его в функцию paintComponent() и вызвал repaint().
package gui;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class Gui extends JPanel{
Graphics g;
Tuple xy;
public Gui()
{
JFrame frame = new JFrame("test");
frame.setSize(700, 700);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.add(this);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
this.g = g;
g.setColor(Color.blue);
for(int x = 0;x < 700; x += 20)
{
g.drawLine(x, 0, x, 700);
}
for(int y = 0;y < 700; y += 20)
{
g.drawLine(0, y, 700, y);
}
if (xy != null)
{
g.fillOval(xy.x, xy.y, 5, 5);
}
}
public void draw(Tuple xy)
{
this.xy = xy;
repaint();
}
}
Спасибо за вашу помощь
Не сохраняйте ссылку на графику, вместо этого используйте сеттер для установки значения кортежа (и вызовите перерисовку), а затем из PaintComponent нарисуйте кортеж, если он не нулевой.