0
我正在爲即將舉行的會議上的演示建模John Conway的Game of Life進行工作,並且我在一個應該完成95%的地方開發該程序,但是,沒有任何響應用戶輸入。它幾乎看起來像我的動作監聽器和鼠標監聽器沒有正確實現,但我不知道在哪裏。該計劃幾乎完全完成;有幾個部分仍然是空的,但它仍然會編譯並正確創建我的JFrame。Swing GUI未對輸入做出響應
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
public class GameOfLife
{
public static void main(String[] args)
{
MyFrame frame = new MyFrame();
}
}
類,它包含全局信息:
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
public class GLOBAL
{
/**
* Build Information for GameOfLife
*/
public static final double BUILDVERSION = 0.1;
public static final String BUILDNAME = "Alpha 0.1";
/**
* Global Constants for GameOfLife
*/
public static final int FRAMEHEIGHT = 1000; //Frame Height
public static final int FRAMEWIDTH = 1000; //Frame Width
public static final int HEIGHT = 100; //Game Height
public static final int WIDTH = 100; //Game Width
/**
* Global Variables
*/
public static int delay = 500; //Step Delay (Milliseconds)
public static byte[][] herd0; //Herd Byte Array 0
public static byte[][] herd1; //Herd Byte Array 2
public static byte[][] startHerd; //Customized herd before animation is started
public static byte activeArray; //Array currently being displayed
public static boolean active; //States if simulation is repeating
public static long arraySwitches; //Tallies times active array is switched
/**
* Action Commands
*/
public static final String CLOSE = "close"; //Closes Application
public static final String START = "go"; //Starts looping simulation
public static final String STOP = "stop"; //Stops loop
public static final String RULES = "rules"; //Pops up window with Rules for GOL
public static final String ABOUT = "about"; //Displays about dialog
public static final String RESETGRID = "resetGrid"; //Resets the grid to before the simulation
public static final String NEWGAME = "new"; //Zeroes the grid and arrays
}
框架:
/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.*;
/**
* @author Brendan Kristiansen
*/
public class MyFrame extends JFrame implements ActionListener, ChangeListener
{
private JPanel mPanel;
private JButton start;
private JButton stop;
private JButton setGame;
private JButton resetGame;
private JButton newGame;
private JLabel speedLabel;
private JSlider speed;
private HerdPanel mHerdPanel;
/**
* Constructor
*/
public MyFrame()
{
GLOBAL.active = false;
initArrays();
setSize(GLOBAL.FRAMEWIDTH, GLOBAL.FRAMEHEIGHT);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mPanel = new JPanel();
initForm();
setVisible(true);
mPanel.setVisible(true);
JMenuBar menu = new JMenuBar();
JMenu game = new JMenu("GameOfLife");
JMenu help = new JMenu("Help");
JMenuItem gamePlay = new JMenuItem("Play");
JMenuItem gameExit = new JMenuItem("Exit");
JMenuItem helpRules = new JMenuItem("Rules");
JMenuItem helpAbout = new JMenuItem("About");
gamePlay.addActionListener(this);
gameExit.addActionListener(this);
helpRules.addActionListener(this);
helpAbout.addActionListener(this);
gamePlay.setActionCommand(GLOBAL.START);
gameExit.setActionCommand(GLOBAL.CLOSE);
helpRules.setActionCommand(GLOBAL.RULES);
helpAbout.setActionCommand(GLOBAL.ABOUT);
game.add(gamePlay);
game.add(gameExit);
help.add(helpRules);
help.add(helpAbout);
menu.add(game);
menu.add(help);
this.setJMenuBar(menu);
this.setVisible(true);
}
/**
* Lays Out Panel
*/
public void initForm()
{
setGame = new JButton("Set Grid");
resetGame = new JButton("Reset Grid");
newGame = new JButton("Clear Grid");
start = new JButton("Start Simulation");
stop = new JButton("Stop Simulation");
speedLabel = new JLabel("Simulation Speed (ms): " + GLOBAL.delay);
// N speed = new JSlider(3000, 50, GLOBAL.delay);
setGame.addActionListener(this);
resetGame.addActionListener(this);
newGame.addActionListener(this);
start.addActionListener(this);
stop.addActionListener(this);
// setGame.setActionCommand(GLOBAL.SETGRID);
resetGame.setActionCommand(GLOBAL.RESETGRID);
newGame.setActionCommand(GLOBAL.NEWGAME);
start.setActionCommand(GLOBAL.START);
stop.setActionCommand(GLOBAL.STOP);
mPanel = new JPanel();
mPanel.setLayout(new BoxLayout(mPanel, BoxLayout.X_AXIS));
mPanel.setBackground(new Color(100, 100, 100));
mHerdPanel = new HerdPanel();
mPanel.add(setGame);
mPanel.add(resetGame);
mPanel.add(newGame);
mPanel.add(start);
mPanel.add(stop);
// mPanel.add(speedLabel);
// mPanel.add(speed);
getContentPane().add(mPanel, BorderLayout.NORTH);
getContentPane().add(mHerdPanel, BorderLayout.CENTER);
}
/**
* Directs ActionEvents to the proper functions
* @param event
*/
@Override
public void actionPerformed(ActionEvent event)
{
String e = event.toString();
if(e.equals(GLOBAL.CLOSE))
{
System.exit(0);
}
else if(e.equals(GLOBAL.START))
{
GLOBAL.active = true;
playGame();
}
else if(e.equals(GLOBAL.STOP))
{
GLOBAL.active = false;
}
else if(e.equals(GLOBAL.NEWGAME))
{
initArrays();
mHerdPanel.paintImage();
}
else if(e.equals(GLOBAL.RESETGRID))
{
GLOBAL.herd0 = GLOBAL.startHerd;
GLOBAL.herd1 = GLOBAL.startHerd;
GLOBAL.activeArray = 0;
mHerdPanel.paintImage();
}
else if (e.equals(GLOBAL.ABOUT))
{
JOptionPane.showMessageDialog(null, "Game of Life\n Developed by Brendan Kristiansen with MSU Storytelling.");
}
else if (e.equals(GLOBAL.RULES))
{
}
}
/**
* Directs ChangeEvents to the proper functions
* @param e
*/
@Override
public void stateChanged(ChangeEvent e)
{
GLOBAL.delay = speed.getValue();
}
/**
* initializes byte arrays to be 0
*/
public void initArrays()
{
GLOBAL.herd0 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
GLOBAL.herd1 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
for(int i = 0; i <= GLOBAL.HEIGHT - 1; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH - 1; j++)
{
GLOBAL.herd0[i][j] = 0;
}
}
GLOBAL.herd1 = GLOBAL.herd0;
GLOBAL.activeArray = 0;
GLOBAL.arraySwitches = 0;
}
/**
*Controls the advancement of the game
*/
public void playGame()
{
GLOBAL.startHerd = GLOBAL.herd0;
if (GLOBAL.active == true)
{
while(GLOBAL.active == true)
{
nextFrame();
try
{
wait(GLOBAL.delay);
}
catch(Exception e)
{
System.out.println(e);
}
}
}
else
{
nextFrame();
}
}
/**
*Advances Game of Life by one frame
*/
public void nextFrame()
{
if (GLOBAL.activeArray == 0)
{
for(int i = 0; i <= GLOBAL.HEIGHT; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH; j++)
{
int neighbors = countNeighbors(i, j, GLOBAL.herd0);
if (neighbors == 3 || neighbors == 4)
{
GLOBAL.herd1[i][j] = 1;
}
else
{
GLOBAL.herd1[i][j] = 0;
}
}
}
GLOBAL.activeArray = 1;
mHerdPanel.paintImage();
}
else
{
for(int i = 0; i <= GLOBAL.HEIGHT; i++)
{
for(int j = 0; j <= GLOBAL.WIDTH; j++)
{
int neighbors = countNeighbors(i, j, GLOBAL.herd1);
if (neighbors == 3 || neighbors == 4)
{
GLOBAL.herd0[i][j] = 1;
}
else
{
GLOBAL.herd0[i][j] = 0;
}
}
}
GLOBAL.activeArray = 0;
mHerdPanel.paintImage();
}
GLOBAL.arraySwitches++;
}
/**
* Counts the living neighbors of a given cell in a herd
* @param i
* @param j
* @param herd
* @return
*/
public int countNeighbors(int i, int j, byte[][] herd)
{
int neighbors = 0;
if(i == 0 && j == 0) //Top left case
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom Neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
}
else if(i == 0 && j == GLOBAL.WIDTH) //Top right case
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(i == GLOBAL.HEIGHT && j == 0) //Bottom left case
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
}
else if(i == GLOBAL.HEIGHT && j == GLOBAL.WIDTH) //Bottom right case
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(i == 0) //Top Row
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(j == 0) //Left side
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
}
else if(i == GLOBAL.HEIGHT) //Bottom Row
{
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
}
else if(j == GLOBAL.WIDTH) //Right side
{
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
}
else //Middle of herd
{
if(herd[i + 1][j] == 1){neighbors++;} //Bottom neighbor
if(herd[i + 1][j - 1] == 1){neighbors++;} //Bottom left neighbor
if(herd[i][j - 1] == 1){neighbors++;} //Left neighbor
if(herd[i - 1][j - 1] == 1){neighbors++;} //Top left neighbor
if(herd[i - 1][j] == 1){neighbors++;} //Top neighbor
if(herd[i - 1][j + 1] == 1){neighbors++;} //Top right neighbor
if(herd[i][j + 1] == 1){neighbors++;} //Right neighbor
if(herd[i + 1][j + 1] == 1){neighbors++;} //Bottom right neighbor
}
return neighbors;
}
}
而且HerdPanel類。這應該是一個網格,您可以點擊更改單元格的顏色,然後玩遊戲生活已經突出顯示的細胞:
/**
*
* @author Brendan Kristiansen
*/
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;
//https://www.shodor.org/stella2java/rgbint.htmlhttps://www.shodor.org/stella2java/rgbint.html
public class HerdPanel extends JPanel implements MouseListener, MouseMotionListener
{
Graphics2D g;
Graphics2D g2;
BufferedImage grid;
BufferedImage bisonCell;
/**
* Constructor
*/
public HerdPanel()
{
setSize(500, 500); //Width, Height
addMouseListener(this);
addMouseMotionListener(this);
try
{
bisonCell = ImageIO.read(new File("bison.png"));
}
catch (IOException e)
{
System.out.println(e);
}
grid = new BufferedImage(GLOBAL.WIDTH, GLOBAL.HEIGHT, 1);
paintImage();
//g = grid.createGraphics();
}
/**
* Converts byte[][] array to BufferedImage
*/
public void paintImage()
{
if (GLOBAL.activeArray == 0)
{
for (int i = 0; i <= GLOBAL.WIDTH - 1; i++)
{
for (int j = 0; j <= GLOBAL.HEIGHT - 1; j++)
{
if (GLOBAL.herd0[j][i] == 0)
{
grid.setRGB(j, i, 16777215);
} else
{
grid.setRGB(j, i, 0);
}
}
}
}
else
{
for (int i = 0; i <= GLOBAL.WIDTH; i++)
{
for (int j = 0; j <= GLOBAL.HEIGHT; j++)
{
if (GLOBAL.herd1[j][i] == 0)
{
grid.setRGB(j, i, 16777215);
} else
{
grid.setRGB(j, i, 0);
}
}
}
}
g = grid.createGraphics();
super.paintComponent(g);
g.drawImage(grid, null, 0, 0);
repaint();
}
@Override
public void mouseClicked(MouseEvent e)
{
int xClick = (int)(e.getX()/GLOBAL.WIDTH);
int yClick = (int) (e.getY()/GLOBAL.HEIGHT);
if(GLOBAL.activeArray == 0)
{
GLOBAL.herd0[yClick][xClick] = 1;
}
else
{
GLOBAL.herd1[yClick][xClick] = 1;
}
paintImage();
}
@Override
public void mousePressed(MouseEvent e)
{
}
@Override
public void mouseReleased(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
}
@Override
public void mouseDragged(MouseEvent e)
{
}
@Override
public void mouseMoved(MouseEvent e)
{
}
}
您阻止事件指派線程,阻止它畫,看看[併發在Swing(https://開頭的文檔.oracle.com/javase/tutorial/uiswing/concurrency /)以獲得更多詳細信息以及[如何使用Swing Timers](https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html)簡單的解決方案 – MadProgrammer
對於需要定期更新UI的更復雜或更耗時的任務,應該使用['SwingWorker'](https://docs.oracle.com/javase/tutorial/uiswing/concurrency /worker.html) – MadProgrammer