问题
hi there i am working on a project(card matching game) and it is almost finished but the things is when i clicked on second button to open the picture if it not same with first it suddenly closed. well nothings is wrong but user must see the picture for a while(maybe 2 second). so i used Thread.sleep(2000)
but i doesnt work properly. it sets icon null and then start to wait 2 seconds. here is my code a tried to make a SSCCE,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.Random;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.border.*;
public class ConcentrationGame3 extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private int buttoncounter=0;
private int counter = 0;
private JFrame frame;
private JPanel mainPanel;
private JPanel buttonPanel;
private JMenuBar menuBar;
private JMenu menu;
private JMenuItem menuItem;
private int[] arr = new int[16];
private int i,j;
private int random;
private int size = 4;
private Icon hidden;
private GameButton buttonFirst;
private GameButton buttonSecond;
int k=0;
private Icon img[] = {UIManager.getIcon("OptionPane.errorIcon"),
UIManager.getIcon("OptionPane.informationIcon"),
UIManager.getIcon("OptionPane.warningIcon")};
private Icon iconList[] = new ImageIcon[size];
public ConcentrationGame3(){
createArray();
initComponents();
}
private void initComponents(){
frame = new JFrame("Concentration Game");
menuBar = new JMenuBar();
menu = new JMenu("Menu");
frame.setJMenuBar(menuBar);
menuBar.add(menu);
menuItem = new JMenuItem("New Game");
menu.add(menuItem);
menuItem = new JMenuItem("Solve");
menu.add(menuItem);
menuItem = new JMenuItem("Exit");
menu.add(menuItem);
mainPanel = new JPanel(new BorderLayout(5, 5));
mainPanel.setBorder(new EmptyBorder(4,4,4,4));
frame.setContentPane(mainPanel);
buttonPanel = new JPanel(new GridLayout(4,4,5,5));
buttonPanel.setBackground(Color.green);
for(i=0; i<4; i++){
final GameButton button = new GameButton(new JToggleButton(),iconList[i]);
button.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent e){
button.setState();
}
});
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
try {
buttonActionPerformed(e,button);
} catch (InterruptedException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
buttonPanel.add(button);
}
mainPanel.add(buttonPanel, BorderLayout.CENTER);
frame.setSize(300, 300);
//frame.pack();
frame.setLocation(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
class GameButton extends JToggleButton{
private static final long serialVersionUID = 1L;
private JToggleButton gameButton;
private Icon icon;
public GameButton(JToggleButton gameButton,Icon icon){
this.gameButton = gameButton;
this.icon = icon;
}
public void setState() {
if (this.isSelected() || !this.isEnabled()) {
this.setIcon(icon);
} else {
this.setIcon(hidden);
}
}
}
private void buttonActionPerformed(ActionEvent e, GameButton button) throws InterruptedException {
if(button.isSelected()){
buttoncounter++;
if(buttoncounter==1){
buttonFirst = (GameButton) e.getSource();
}
else if(buttoncounter==2){
buttonSecond = (GameButton) e.getSource();
buttoncounter=0;
if( checkPairs(buttonFirst,buttonSecond) ) {
retirePair(buttonFirst,buttonSecond);
}
else{
Thread.sleep(2000);
buttonFirst.setIcon(hidden);
buttonFirst.setSelected(false);
buttonSecond.setIcon(hidden);
buttonSecond.setSelected(false);
}
}
}
}
private void retirePair(GameButton a, GameButton b){
a.setSelected(true);
a.setEnabled(false);
b.setSelected(true);
b.setEnabled(false);
}
private boolean checkPairs(GameButton first, GameButton second){
if(first.getIcon().equals(second.getIcon()))
return true;
else
return false;
}
private void createArray(){
Random rnd = new Random();
while(i<4){
random = rnd.nextInt(3)+1;
if(!includes(random)){
arr[i]=random;
iconList[i] = img[random-1];
i++;
}
}
}
public boolean includes(int rnd){
counter=0;
for(j=0; j<arr.length; j++){
if(arr[j] == rnd){
counter++;
if(counter>1)
return true;
}
}
return false;
}
/**
* @param args
*/
public static void main(String[] args) {
new ConcentrationGame3();
}
}
i appreciated if you can help me. and thanks anyway :)
回答1:
You don't want to use Thread.sleep on the Swing thread, since as I'm sure you've read if you've done any searching, what this does is put Swing to sleep, sleep meaning all drawing is frozen, and all user interaction (like response to buttons) is frozen. Instead use a Swing Timer which will allow you to pause your application without preventing Swing from drawing your second image and showing both for 2 or 3 seconds. The logic will be: show both images, start the timer, and when the timer "ticks" after 2 or 3 seconds (or whatever you set the delay to be), hide the images inside of the timer's ActionListener.
Also: make sure that you set the timer as non-repeating (there's a boolean method of Swing Timer that does this). Also, you'll want to make all of your JToggleButtons unresponsive (or enabled == false) while the the two images are shown, and then you want the Timer to set all the non-paired buttons to a responsive state when it "ticks".
来源:https://stackoverflow.com/questions/7910639/keep-2-pictures-open-for-a-while-in-memory-game-in-java