бұрылу таймері дұрыс жұмыс істемейді

Сәлеметсіз бе, мен жобада жұмыс істеймін (java жады ойыны) және ең алдымен мен жұмыс істейтін таймер қалай жұмыс істейтінін түсінуге тырысамын. біріншіден, менің басты классым ActionListener және ItemListener . егер қолданушы әртүрлі суреттерді таңдаған екі карточка болса, онда timer.start() функциясын қолдансам, оны actionPerformed (ActionEvent e) содан кейін олар қайтадан жабылады. бірақ пайдаланушы екі түрлі суретті таңдайтын болса, олар кенеттен жабылған, сондықтан екінші суретті көре алмаймын. Мен сөндіргіш таймер туралы кейбір оқулықтарды оқыдым, бірақ, менің ойымша, дұрыс емес түсіндім. Менің 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; j1)
                    return true;
            }
        }

        return false;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {

        new ConcentrationGame4();

    }

}
2
иә, бірақ бағдарламаның қажетсіз бөлігін жойдым. Мен өзімнің белгішелерімді пайдаланбаймын және көптеген түймелерді жасамаймын дегенді білдіремін (4 түсіну үшін бұл минимум), сондықтан бұл оңай көшірме және басқа адамдар үшін компиляция. Яғни, онда қажетсіз кодтарды көре алмаймын. Менен не күтесіз? Жалпы айтқанда, мен 20 батырманы жасаймын және олар өздерінің белгішелерін blablabla деп атайды. және иә, тақырып өте үлкеніне ұқсас. бірақ егер сіз кодты оқып, мұқият қарасаңыз, мен кейбір өзгертулер енгізіп, таймер қалай жұмыс істейтінін білгіңіз келеді ...
қосылды автор quartaela, көзі
және адамдар неге ставканы төмендетеді? бұрынғыдай бір сұрақты сұрастырудың себебі болып табылады?
қосылды автор quartaela, көзі
Бұл қысқа емес, бірақ ол кем дегенде өзіндік және компиляция.
қосылды автор JB Nizet, көзі
Айналдыру таймері шынымен де дұрыс жұмыс жасайды - яғни, ол мұны не істеп жатқанын ғана жасайды. Сіздің кодыңызда қате бар, бірақ менің ойымша, JB Nizet бұл мәселені анықтады және бұл шешім үшін (1+) ұсынды.
қосылды автор Hovercraft Full Of Eels, көзі
stackoverflow.com/q/7910639/1005662 ішіндегі адамдардың реакциясы бойынша бұл тағы да sscce емес. Бұл кодтың қалдықтары және көмек сұрауы. Пожалуйста, білесіңдер, бұл ссср: sscce.org Сондай-ақ, бұл жоғарыда аталған стеккопергистің сілтемесі дерлік ...
қосылды автор NickLH, көзі

3 жауаптар

Xxx секундқа арналған кідірту үшін 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();
         }
      });
   }
}
6
қосылды
Swing +1 сияқты қарапайым
қосылды автор mKorbel, көзі
Мен іс-әрекеттерді түсінуге тырысуым керек екенін байқадым, өйткені ActionPeterformed-де actionlistener қолдануға болатынын білмедім. сондықтан іс-шара іс-әрекеттер тізімін алып тастаған кезде, ол онымен жұмыс істейді, сол себепті ішкі әрекетті шақырушы туралы не болады. бір оқиғаны өңдей ме? (және бұл мәселе бойынша бірнеше күн бойы есіме түсіргеніме көп рахмет, түсіну үшін неғұрлым анық көрінеді)
қосылды автор quartaela, көзі

Мен не істегіңіз келетінін білмеймін, бірақ this параметрін Timer конструкторына дәлел ретінде өткізесіз. Бұл әрбір 2 секундтан кейін this (ConcentrationGame4 данасы) actionPerformed әдісі шақырылады. Және бұл әдіс бірінші болып табылады

GameButton button = (GameButton) e.getSource();

Әлбетте, бұл жағдайды алып тастауы мүмкін, себебі оқиғаның шығу тетігі ойын түймесі емес, таймер болады.

Таймердің не істеп жатқанын және қалай жұмыс істейтінін түсіну үшін бұл өте оңай. Сіз тек api doc бағдарламасын оқып шығуыңыз керек: http://download.oracle.com/javase/6/docs/api/javax/swing/Timer.html . Бұл құжат сізді мысалдармен қалай жұмыс істейтіндігін түсіндіретін оқулыққа алып келеді.

5
қосылды
Мен жай ғана тәсілі, ол 2 секунд тоқтайды және одан кейін, ол оның жұмысқа жалғастырады Мен <�коды> falsePair() төмен </коды> туралы <�коды> timer.start() </кодты> пайдалансаңыз деп ойлаған
қосылды автор quartaela, көзі
Жақсы, мен мұны осылай деп ойлаймын, сондықтан мен оны жойғым келеді. сізді ашуландырғаныңыз үшін кешірім сұраймын:)
қосылды автор quartaela, көзі
Жоқ, таймер не істемейді. F ** құжаттамасын оқыңыз. Thread.sleep мұны жасайды, бірақ егер сіз оны оқиға жіберу жөнелтілімінде жасасаңыз, GUI 2 секунд бойы қатырылады.
қосылды автор JB Nizet, көзі
Сіз мені ашуландырдыңыз. Мен жауап берген сұрақтардың жартысы құжаттарды оқып, жауап беруге болады. Сізге бірдеңе үйренсеңіз деп ойлаймын, енді сіз құжатты оқып үйренесіз.
қосылды автор JB Nizet, көзі
@Hovercraft: timer.start() ағымдағы ағынды екі секундқа кідіртпей, одан кейін жалғастырады. timer.start() біраз уақыттан кейін оқиға тудыратын өң ағынын бастайды. Әрине, оқиғаны тыңдаушы falsePair() әдісін шақыра алады, бірақ бұл ағымдағы ағынды кідірту және жалғастыру сияқты бірдей нәрсе емес.
қосылды автор JB Nizet, көзі
Мен бұған келісемін. ОП ойыны timer.start() ағымдағы жіпті тоқтатады, мысалы Thread.sleep (). Мен жай ғана айтқаным жоқ. Мен ОШ-ны қалаған нәрсені жасау үшін пайдаланылмайтын деп айтпадым.
қосылды автор JB Nizet, көзі
Бұл хабарды немесе жіпті ең аз ақымақ емес етіп жоймаңыз. Міне, мен JB Nizet-мен келіспеймін, бұл үшін құюшы таймер жұмыс істейді және іс жүзінде мұндай нәрсені кодтағанмын. Тек қайталанбайтын етіп жасаңыз.
қосылды автор Hovercraft Full Of Eels, көзі
Жарайды, түсінбеушілік үшін кешірім өтінемін.
қосылды автор Hovercraft Full Of Eels, көзі
@JB Nizet: Ол кез келген ағыны тоқтатуға немесе қажет емес. Ол еске түсіру ойынын жасап жатыр және ол істеу керек нәрселер - суреттерді көрсету және түймелердің жұмысын көрсетпеу. Маған нені білдіретінімді білу үшін менің «жауап» деген кодты қараңыз.
қосылды автор Hovercraft Full Of Eels, көзі

As an aside, you might want to look at using List and List. Such Collections are easy to shuffle in a reliable way. Also, note the difference between an individual GameButton and a collection of them, external to the GameButton class. It's the collection that you'll need to examine when any one button is clicked.

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://stackoverflow.com/questions/7933424 */
public class ButtonTimer extends JPanel {

    private List list = new ArrayList();
    private List buttons = new ArrayList();
    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();
            }
        });
    }
}
5
қосылды
рахмет бұл мен үшін өте жақсы үлгі
қосылды автор quartaela, көзі
Өте жақсы. Тым риза емес; сіз алған ұсыныстарды қабылдауға дайын екеніңіз анық. Сұрақтарды қою кезінде мысалда мәселенің белгілі бір аспектісі, мысалы, shuffle() қолданатын Timer @ Hovercraft пайдаланғанына назар аударыңыз. Мұндай мысал жасаудың сәл астам жұмысы, бірақ бұл күш сіз үшін құнды болады.
қосылды автор trashgod, көзі