每次我运行程序时它都运行良好。但是,当我运行程序几秒钟后关闭它时,我收到 java.io.IOException:已关闭错误。我尝试环顾四周,但找不到解决方案。我能找到的唯一解决方法是不在 try-catch 块中使用 e.printstacktrace,但这显然不能解决问题。这是代码:
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Main extends Canvas implements Runnable
{
private static final long serialVersionUID = -661485289446387445L;
private Thread thread;
public int blackPos;
public int whitePos;
public boolean isWhiteTurn; // In single player this determines board orientation, in multiplayer it doesn't
public boolean running;
public final int HEIGHT = 800;
public final int WIDTH = 1200;
//public File[] imgSrc = {new File("/images/urBoard.png"), new File("/rsc/urBackground.jpg")};
public BufferedImage[] img = new BufferedImage[2];
public Board board;
public Main()
{
new Window(WIDTH, HEIGHT, this);
board = new Board(this);
}
public void run()
{
requestFocus();
long lastTime = System.nanoTime();
double amountOfTicks = 60.0D;
double ns = 1.0E9D / amountOfTicks;
double delta = 0.0D;
long timer = System.currentTimeMillis();
int frames = 0;
while (this.running)
{
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1.0D)
{
tick();
delta -= 1.0D;
}
if (this.running) {
render();
}
frames++;
if (System.currentTimeMillis() - timer > 1000L)
{
timer += 1000L;
System.out.println("FPS: " + frames);
frames = frames;
frames = 0;
}
}
}
public synchronized void start()
{
thread = new Thread(this);
thread.start();
running = true;
}
public synchronized void stop()
{
try
{
this.thread.join();
this.running = false;
}
catch (Exception e)
{
e.printStackTrace();
}
}
public void tick()
{
board.tick();
}
public void render()
{
BufferStrategy bs = getBufferStrategy();
if(bs == null)
{
createBufferStrategy(3);
return;
}
try
{
img[0] = ImageIO.read(getClass().getResource("/rsc/urBoard.png"));
img[1] = ImageIO.read(getClass().getResource("/rsc/urBackground.jpg"));
}
catch (IOException e) {
e.printStackTrace();
}
Graphics g = bs.getDrawGraphics();
g.drawImage(img[1], 0, 0, WIDTH, HEIGHT, null);
g.setColor(Color.GREEN);
g.drawLine(200, 0, 200, 800);
g.setFont(new Font("times new roman", Font.BOLD, 30));
g.drawString("END PIECES", 10, 30);
board.render(g);
g.dispose();
bs.show();
}
public static void main(String[] args)
{
new Main();
}
}
这是每当我在运行几秒钟后关闭 GUI 时收到的错误:
java.io.IOException: closed
at javax.imageio.stream.ImageInputStreamImpl.checkClosed(ImageInputStreamImpl.java:110)
at javax.imageio.stream.ImageInputStreamImpl.close(ImageInputStreamImpl.java:857)
at javax.imageio.stream.FileCacheImageInputStream.close(FileCacheImageInputStream.java:250)
at javax.imageio.ImageIO.read(ImageIO.java:1451)
at javax.imageio.ImageIO.read(ImageIO.java:1400)
at main.Main.render(Main.java:99)
at main.Main.run(Main.java:54)
at java.lang.Thread.run(Thread.java:745)
我注意到,如果我在启动程序后立即关闭窗口,则不会出现错误。仅当我运行该程序大约 3-4 秒,然后关闭窗口时,才会出现这种情况。什么会导致这种情况发生,解决方法是什么?
看起来您的
render()
方法可能在关闭应用程序时正在运行。由于您的资源在 render()
调用之间没有发生变化,因此将此块移动到 Main()
构造函数的开头,以便 img[]
设置一次,并在找不到资源时引发异常:
try {
img[0] = ImageIO.read(getClass().getResource("/rsc/urBoard.png"));
img[1] = ImageIO.read(getClass().getResource("/rsc/urBackground.jpg"));
} catch (IOException e) {
throw new RuntimeException("Could not find resources");
}
字段
running
在不同的线程中使用,因此应将其标记为volatile
,以便每个线程读取一致的值:
public volatile boolean running;