问题
Okay so i am making a simple reaction game and my code is as below. Now when startGame() is called, if I comment out the while loop everything happens okay but when I run it with the thread.sleep(1000) the thing is just stuck! the whole program executes and nothing happens. Please take 2 minutes to run the code and help me debug it. I am using the thread.sleep(1000) to see if the the user can click the lit up jPanelArray JPanel. But I believe because of the thread.sleep the GUI doesn't change AT ALL when the start game button is pressed. Help is really appreciated.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class JExternFrame extends JFrame implements ActionListener{
public Color randomColor(){
return new Color((.8f) * generator.nextFloat() + .04f,(.8f) * generator.nextFloat() + .04f,(.8f) * generator.nextFloat() + .04f);
}
public JPanel [][]jPanelArray;
public JButton startButton;
int []currentLitUp;
public Random generator;
public JPanel main;
public JExternFrame(){
super("The Reaction Game");
generator = new Random();
setSize(400,400);
startButton = new JButton("Start Game");
startButton.setOpaque(true);
startButton.setBorderPainted(false);
startButton.setBackground(randomColor());
add(startButton,BorderLayout.NORTH);
main = new JPanel();
main.setBackground(randomColor());
add(main);
mouseClick myMouseClick = new mouseClick();
startButton.addActionListener(this);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void startGame(){
startButton.setVisible(false);
int numOfClicks = generator.nextInt(8)+5;
int sizeX = 15;
int sizeY = 15;
currentLitUp = new int[2];
jPanelArray = new JPanel[sizeX][sizeY];
mouseClick mouseClicked = new mouseClick();
main.setLayout(new GridLayout(sizeX,sizeY));
for(int i = 0; i < sizeX; i++){
for(int j = 0; j < sizeY; j++){
jPanelArray[i][j] = new JPanel();
jPanelArray[i][j].setBackground(Color.GRAY);
main.add(jPanelArray[i][j]);
jPanelArray[i][j].addMouseListener(mouseClicked);
}
}
while (numOfClicks != 0){
numOfClicks--;
currentLitUp[0] = generator.nextInt(14);
currentLitUp[1] = generator.nextInt(14);
jPanelArray[currentLitUp[0]][currentLitUp[1]].setBackground(randomColor());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
jPanelArray[currentLitUp[0]][currentLitUp[1]].setBackground(Color.GRAY);
currentLitUp[0] = -1;
currentLitUp[1] = -1;
}
System.exit(0);
}
public class mouseClick implements MouseListener{
@Override
public void mouseClicked(MouseEvent e) {
if(e.getSource() == jPanelArray[currentLitUp[0]][currentLitUp[1]]){
System.out.print("Correct");
}
else System.out.print("INCORRECT");
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
public void actionPerformed(ActionEvent e){
if(e.getSource() == startButton){
startGame();
}
}
public static void main(String[] args){
new JExternFrame();
}
}
回答1:
Your actionPerformed()
method is invoked by Swing on the Event Dispatch Thread. In your actionPerformed()
method, you call startGame()
and this method loops continually. This means that you never let the Event Dispatch Thread continue doing it's work.
You need to investigate SwingWorker, and SwingUtilities.invokeLater().
回答2:
Your Thread.sleep() is running in the GUI thread and putting it to sleep so it can't keep processing other GUI events.
Concurency in Swing is your issue, you'll find this question answered many times over...
来源:https://stackoverflow.com/questions/10345591/java-gui-not-changing