英文:
Java: Accessing BufferedImage to be rendered only has an effect inside class
问题
我正在尝试构建一个小型库,以在其他项目中使用,它可以帮助设置一个每秒重绘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)
{
//此处是我放置工作代码的位置
display.repaint();
}
}
}
public static boolean AssessTime(int FPS)
{
...不相关的代码...
}
}
以及:
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)
{
...不相关的代码...
}
}
我尝试在其他地方(另一个包中)创建Runtime的实例,然后修改Display的变量'image',使得渲染的图像可以在该上下文中以动态且简单的方式进行更改。我有一个生成噪声填充缓冲图像的函数用于测试,当我在OnUpdate()中将Display的'image'设置为这个图像时,它能够工作...
然而,当我尝试在其他地方这样做时,它不起作用,即(伪代码):
public void main(String args[])
{
Runtime runtime = new Runtime(...)
while(true)
{
runtime.display.image = (随机生成的图像)
}
}
当我将代码放在第一个类中的OnUpdate()中时,它能够工作,并且每帧都会更新为噪声图像,但是当我尝试在其他地方这样做时,不会抛出错误,JFrame保持黑屏。我觉得我的代码结构可能有问题,但我不知道如何使其足够灵活,以便在多个不同的项目中使用。
感谢您的帮助,为我的愚蠢之处道歉!
英文:
I am trying to build a little library, to use on other projects, that helps to set up a frame with an image that is redrawn X times per second.
It consists of two classes:
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...
}
}
And:
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...
}
}
I'm trying to create an instance of Runtime elsewhere (in another package) and then modify Display's variable 'image' such that the image rendered may be changed dynamically and simply in that context. I have a function that makes a noise-filled buffered image for testing and when I set Display's 'image' to this in OnUpdate() it works...
However, when I try and do this elsewhere it doesn't work i.e. (pseudocode):
public void main(String args[])
{
Runtime runtime = new Runtime(...)
while(true)
{
runtime.display.image = (randomly generated image)
}
}
When I have the code in OnUpdate() as indicated in the first class it works and updates with noise every frame but when I try to do this elsewhere no error is thrown the JFrame just stays black. I feel like I'm structuring my code wrong but I don't know how else to make it flexible enough to use for several different projects.
Thanks for your help and sorry for my idiocy!
答案1
得分: 0
好的,以下是您要求的翻译内容:
我假设JFrame
在您显式调用repaint
之前不会绘制任何图像。
在OnUpdate
中有效,因为您在那里显式调用它,并且在循环迭代之间给组件一些时间来重新绘制自身。
deltaT = (System.currentTimeMillis() - lastShortTime) / 1000;
lastShortTime = System.currentTimeMillis();
while (AssessTime(FPS)) {
. . .
display.repaint();
}
如果您只使用while
循环 - 您的组件将没有足够的时间来重新绘制自身。
尝试这样做以验证我的假设:
while (true) {
Thread.sleep(50);
runtime.display.image = (随机生成的图像)
runtime.display.repaint();
}
英文:
Well, I assume JFrame
won't draw any image until you call repaint
explicitly.
It works in OnUpdate
because you call it explicitly there and you give some time to the component to repaint itself between loop iterations.
deltaT = (System.currentTimeMillis()-lastShortTime)/1000;
lastShortTime = System.currentTimeMillis();
while(AssessTime(FPS)) {
. . .
display.repaint();
}
If you just do while
loop - your component will not have enough time to redraw itself.
Try to do something like that to validate my assumption:
while(true) {
Thread.sleep(50);
runtime.display.image = (randomly generated image)
runtime.display.repaint();
}
专注分享java语言的经验与见解,让所有开发者获益!
评论