Java: доступ к BufferedImage, который будет отображаться, имеет эффект только внутри класса - PullRequest
1 голос
/ 05 апреля 2020

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

Он состоит из двух классов:

package displayKit;

public class Runtime 
{
    public Display display;
    static double lastTime;
    static double thisTime;
    public static double deltaT;
    static double lastShortTime;
    public static Thread thread;
    public int FPS = 50;
    public static boolean running = false;

    public Runtime(int w, int h)
    {
        display = new Display(w, h);
        lastTime = System.currentTimeMillis();
        lastShortTime = System.currentTimeMillis();
        running = true;

        while(running)
        {
            OnUpdate();
        }
    }

    void OnUpdate()
    {
        deltaT = (System.currentTimeMillis()-lastShortTime)/1000;
        lastShortTime = System.currentTimeMillis();

        while(AssessTime(FPS))
        {
            if(display != null)
            {
                //Where I've been putting the code that works
                display.repaint();
            }
        }
    }

    public static boolean AssessTime(int FPS)
    {
        ...irrelevant...
    }
}

И:

package displayKit;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Display extends JPanel
{
    private static final long serialVersionUID = 1L;
    public static int width;
    public static int height;
    public static Dimension dimension;

    public static JFrame frame;
    public static JPanel panel;

    public BufferedImage image;
    public Runtime runtime;

    public Display(int w, int h)
    {
        width = w;
        height = h;
        dimension = new Dimension(width, height);
        frame = buildJFrame(w, h);
    }

    public JFrame buildJFrame(int w, int h)
    {
        JFrame frame = new JFrame();
        frame.setSize(dimension);
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        panel = this;
        panel.setPreferredSize(dimension);
        panel.setSize(dimension);
        panel.setMaximumSize(dimension);
        panel.setMinimumSize(dimension);
        frame.add(panel);
        frame.setVisible(true);
        frame.pack();
        image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        return frame;
    }

    public void paintComponent(Graphics g)
    {
        g.setColor(Color.black);
        g.fillRect(0, 0, width, height);
        g.drawImage(image, 0, 0, null);
        g.dispose();
    } 

    public static BufferedImage ColorNoise(int w, int h)
    {
        ...irrelevant...
    }
}

Я пытаюсь создать экземпляр среды выполнения в другом месте (в другом пакете), а затем измените переменную Display 'image' так, чтобы отображаемое изображение могло изменяться динамически и просто в этом контексте. У меня есть функция, которая делает заполненное шумом буферизованное изображение для тестирования, и когда я устанавливаю 'изображение' для Display в OnUpdate (), это работает ...

Однако, когда я пытаюсь сделать это в другом месте, это не не работает, т.е. (псевдокод):

public void main(String args[])
{
    Runtime runtime = new Runtime(...)
    while(true)
    {
        runtime.display.image = (randomly generated image)
    }
}

Когда у меня есть код в OnUpdate (), как указано в первом классе, он работает и обновляется с шумом каждый кадр, но когда я пытаюсь сделать это в другом месте, нет ошибки брошен JFrame просто остается черным. Мне кажется, что я неправильно структурирую свой код, но я не знаю, как еще сделать его достаточно гибким для использования в нескольких различных проектах.

Спасибо за вашу помощь и извините за мой идиотизм!

1 Ответ

0 голосов
/ 05 апреля 2020

Ну, я полагаю, JFrame не будет рисовать изображения, пока вы не вызовете repaint явно.

Он работает в OnUpdate, потому что вы вызываете его там явно, и вы даете компоненту некоторое время для перекраски между l oop итерациями.

deltaT = (System.currentTimeMillis()-lastShortTime)/1000;
        lastShortTime = System.currentTimeMillis();

while(AssessTime(FPS)) {
    . . . 
    display.repaint();
}

Если вы просто делаете while l oop - у вашего компонента не будет достаточно времени для перерисовки.

Попробуйте сделать что-то подобное, чтобы подтвердить мое предположение:

while(true) {
    Thread.sleep(50);
    runtime.display.image = (randomly generated image)
    runtime.display.repaint();
}
...