Как отложить код Java до завершения другой части кода?

поэтому я пробовал библиотеку 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 нарисуйте кортеж, если он не нулевой.

MadProgrammer 17.02.2019 04:16

И как мне снова запустить метод paintComponent, чтобы проверить, обновился ли Tuple?

BlockCoder 17.02.2019 13:49

Звоните, перекрашивайте...

MadProgrammer 17.02.2019 19:11
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
3
85
3

Ответы 3

Вы должны сделать весь рисунок на

public void paintComponent(Graphics g) 

как указано в https://docs.oracle.com/javase/tutorial/uiswing/painting/problems.html.

Используйте функцию обратного вызова. Намного лучше, чем polling недвижимость. И вы получаете свежий графический объект. И ваш вызов выполняется в правильном контексте.

Вот общая идея:

Создание экземпляра

new Gui((Graphics graphics)-> {
   // your code here
});

CTOR или функция инициализации

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

}

Спасибо за вашу помощь

Другие вопросы по теме