Таймер свинга не работает должным образом
Привет! Я работаю над проектом (игра памяти Java), и в первую очередь я пытаюсь понять, как работает таймер свинга. во-первых, я реализую свой основной класс ActionListener
а также ItemListener
, и я использую таймер в actionPerformed(ActionEvent e)
если две карты, которые пользователь выбрал разные картинки, то я использую timer.start()
дать ему пару секунд, чтобы увидеть фотографии, а затем они снова будут закрыты. но если пользователь выбирает две разные картинки, они внезапно закрываются, поэтому я не вижу вторую картинку. Я прочитал несколько уроков о таймере свинга, но, думаю, я понял неправильно. По тому, как я создал свой 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 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.Timer;
import javax.swing.UIManager;
import javax.swing.border.*;
public class ConcentrationGame4 extends JFrame implements ActionListener, ItemListener{
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;
private Timer timer;
private Icon img[] = {UIManager.getIcon("OptionPane.errorIcon"),
UIManager.getIcon("OptionPane.informationIcon"),
UIManager.getIcon("OptionPane.warningIcon")};
private Icon iconList[] = new ImageIcon[size];
public ConcentrationGame4(){
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);
timer = new Timer(2000,this);
for(i=0; i<4; i++){
final GameButton button = new GameButton(iconList[i]);
button.addItemListener(this);
button.addActionListener(this);
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);
}
public void itemStateChanged(ItemEvent e){
GameButton button = (GameButton) e.getItem();
button.setState();
}
public void actionPerformed(ActionEvent e){
GameButton button = (GameButton) e.getSource();
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{
timer.start();
falsePair(buttonFirst, buttonSecond);
}
}
}
}
class GameButton extends JToggleButton{
private static final long serialVersionUID = 1L;
private Icon icon;
public GameButton(Icon icon){
this.icon = icon;
}
public void setState() {
if (this.isSelected() || !this.isEnabled()) {
this.setIcon(icon);
}
else {
this.setIcon(hidden);
}
}
}
private void retirePair(GameButton a, GameButton b){
a.setSelected(true);
a.setEnabled(false);
b.setSelected(true);
b.setEnabled(false);
}
private void falsePair(GameButton buttonFirst, GameButton buttonSecond){
buttonFirst.setIcon(hidden);
buttonFirst.setSelected(false);
buttonSecond.setIcon(hidden);
buttonSecond.setSelected(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 ConcentrationGame4();
}
}
3 ответа
Пример использования Swing Timer для приостановки действия на ххх секунд:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class QuickTimerEg extends JPanel {
private static final int TIMER_DELAY = 2000;
private boolean buttonsWorking = true;
private JButton btn1 = null;
private JButton btn2 = null;
private Timer swingTimer;
public QuickTimerEg() {
ActionListener btnListener = new ActionListener() {
public void actionPerformed(ActionEvent e) {
btnActionPerformed(e);
}
};
setLayout(new GridLayout(4, 4));
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
JButton button = new JButton(" ");
button.addActionListener(btnListener);
add(button);
}
}
}
private void btnActionPerformed(ActionEvent e) {
if (!buttonsWorking) {
return;
}
JButton button = (JButton)e.getSource();
button.setBackground(Color.blue);
button.setEnabled(false);
if (btn1 == null) {
btn1 = button;
} else {
buttonsWorking = false;
btn2 = button;
swingTimer = new Timer(TIMER_DELAY, new ActionListener() {
public void actionPerformed(ActionEvent e) {
btn1.setBackground(null);
btn2.setBackground(null);
btn1.setEnabled(true);
btn2.setEnabled(true);
btn1 = null;
btn2 = null;
buttonsWorking = true;
}
});
swingTimer.setRepeats(false);
swingTimer.start();
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("QuickTimerEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new QuickTimerEg());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Кроме того, вы можете посмотреть на использование List<Icon>
а также List<GameButton>
, такие Collections
легко перетасовать надежным способом. Также обратите внимание на разницу между человеком GameButton
и их коллекция, внешняя по отношению к GameButton
учебный класс. Это коллекция, которую вам нужно изучить при нажатии любой кнопки.
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.Timer;
import javax.swing.UIManager;
/** @see http://stackru.com/questions/7933424 */
public class ButtonTimer extends JPanel {
private List<Icon> list = new ArrayList<Icon>();
private List<GameButton> buttons = new ArrayList<GameButton>();
private Timer timer = new Timer(1000, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
createPanel();
}
});
public ButtonTimer() {
this.setLayout(new GridLayout(1, 0));
list.add(UIManager.getIcon("OptionPane.errorIcon"));
list.add(UIManager.getIcon("OptionPane.informationIcon"));
list.add(UIManager.getIcon("OptionPane.warningIcon"));
list.add(UIManager.getIcon("OptionPane.questionIcon"));
createPanel();
timer.start();
}
private void createPanel() {
Collections.shuffle(list);
this.removeAll();
for (Icon icon : list) {
GameButton gb = new GameButton(icon);
buttons.add(gb);
this.add(gb);
}
this.revalidate();
}
class GameButton extends JToggleButton {
private Icon icon;
public GameButton(Icon icon) {
super(icon);
this.icon = icon;
}
}
private void display() {
JFrame f = new JFrame("ButtonTimer");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ButtonTimer().display();
}
});
}
}
Я не знаю, что вы хотите сделать, но вы проходите this
в качестве аргумента для конструктора Timer. Это означает, что каждые 2 секунды actionPerformed
метод this
(экземпляр ConcentrationGame4) будет вызван. И первое, что делает этот метод, это
GameButton button = (GameButton) e.getSource();
Очевидно, это вызовет исключение, поскольку источником события будет не кнопка игры, а таймер.
Понять, что делает Таймер и как он работает, очень просто. Вам просто нужно прочитать его документ API: http://download.oracle.com/javase/6/docs/api/javax/swing/Timer.html. Этот документ даже приведет вас к учебнику, объясняющему, как они работают, с примерами.