我试图用Java swing制作Conway的生活游戏,我需要在SwingWorker中运行游戏循环,并在用户决定停止运行循环时结束线程。但是,当我运行程序时,UI冻结,并且我被迫强行退出程序。有人可以告诉我我在做什么错吗?这是我的代码。
import java.awt.*;
import java.awt.Canvas;
import javax.swing.*;
import java.*;
import java.awt.event.*;
import java.util.*;
import java.awt.image.BufferedImage;
import javax.swing.Timer;
// use swing timer for thread stuff
/**
* Write a description of class GameLife here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class GameLife extends JPanel
{
// instance variables - replace the example below with your own
private int x;
private static final Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
private static final int w = (int)screen.getWidth();
private static final int h = (int)screen.getHeight();
private Color co1 = new Color(221,62,76);
private Color co2 = new Color(0,200,235);
private Color co3 = new Color(229,126,215);
private int square = 20;
private boolean flag = false;
private double mousex;
private double mousey;
private ArrayList<ArrayList<Integer>> selected;
private boolean running = false;
private GameWorker game;
/**
* Constructor for objects of class GameLife
*/
public GameLife()
{
game = new GameWorker();
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent me) {
if(!running)
{
flag = true;
mousex = me.getX();
mousey = me.getY();
repaint();
}
}
});
addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int id = e.getID();
int keyCode = e.getKeyCode();
char space = ' ';
if(id == KeyEvent.KEY_PRESSED)
{
if(keyCode == KeyEvent.VK_SPACE)
{
running = !running;
if(running)
{
game.doInBackground();
}
else
{
game.cancel(true);
}
}
if(keyCode == KeyEvent.VK_Q)
{
square+=5;
repaint();
}
if(keyCode == KeyEvent.VK_E)
{
square-=5;
repaint();
}
}
}
});
setFocusable(true);
selected = new ArrayList<ArrayList<Integer>>();
mousex = 0;
mousey = 0;
}
/**
* An example of a method - replace this comment with your own
*
* @param y a sample parameter for a method
* @return the sum of x and y
*/
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(co1);
g2.setStroke(new BasicStroke(2));
for(int i = 0; i < square;i++)
{
for(int j = 0; j< square; j++)
{
g2.setColor(co1);
g2.drawRect((w/square) * j, (h/square) * i,(w/square),(h/square));
if(!(selected.contains(new ArrayList<Integer>(Arrays.asList((w/square) * j,(h/square) * i,(w/square),(h/square))))))
{
g2.setColor(co2);
g2.fillRect((w/square) * j,(h/square) * i,(w/square),(h/square));
}
else
{
g2.setColor(co3);
g2.fillRect((w/square) * j,(h/square) * i,(w/square),(h/square));
}
}
}
if(flag)
{
draw(g2, mousex, mousey);
flag = false;
}
}
public void draw(Graphics2D g, double x , double y)
{
int mx = (int) x;
int my = (int) y;
GameLife aiden = new GameLife();
for(int i = 0; i < square;i++)
{
for(int j = 0; j< square; j++)
{
if( x > (w/square) * j && x < (w/square) * j + (w/square) && y > (h/square) * i && y < (h/square) * i + (h/square) && !(selected.contains(new ArrayList<Integer>(Arrays.asList((w/square) * j,(h/square) * i,(w/square),(h/square))))))
{
selected.add(new ArrayList<Integer>(Arrays.asList((w/square) * j,(h/square) * i,(w/square),(h/square))));
}
else if( x > (w/square) * j && x < (w/square) * j + (w/square) && y > (h/square) * i && y < (h/square) * i + (h/square) && selected.contains(new ArrayList<Integer>(Arrays.asList((w/square) * j,(h/square) * i,(w/square),(h/square)))))
{
selected.remove(new ArrayList<Integer>(Arrays.asList((w/square) * j,(h/square) * i,(w/square),(h/square))));
}
}
}
repaint();
}
public static void main()
{
JFrame frame = new JFrame("Conley's Game");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
GameLife canvas = new GameLife();
frame.getContentPane().add(canvas);
canvas.setSize(w,h);
frame.pack();
frame.setVisible(true);
}
}
这是我的SwingWorker班
import java.util.*;
import javax.swing.*;
/**
* Write a description of class GameWorker here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class GameWorker extends SwingWorker<Void,Void>
{
/**
* Constructor for objects of class GameWorker
*/
public GameWorker()
{
}
public Void doInBackground()
{
while(true)
{
System.out.println("hi");
try{
Thread.sleep(100);
}
catch(InterruptedException e)
{
return null;
}
}
}
}