簡體   English   中英

Java Swing計時器不清晰

[英]Java Swing Timer Not Clear

使用Java swing的Timer函數時遇到了一些問題。 我對使用Java編程還很陌生,因此非常感謝您的幫助。 我在該網站上查看了許多其他計時器問題,但沒有一個回答我的問題。 我制作了一個GUI,可用來播放剪刀石頭布,您可以在其中單擊三個按鈕進行選擇。 我希望我的程序在單擊按鈕后休眠1秒鍾左右,然后在它顯示一條消息后再次休眠。 當我意識到Thread.sleep()對我的GUI無效時,我嘗試實現一個計時器。

import java.awt.*;
import java.awt.event.*;
import javax.swing.*; 
import javax.swing.border.Border;
import java.io.*;

public class rps { 
//ROCK PAPER SCISSORS
static JLabel middle = new JLabel();
static JLabel them = new JLabel();
static JLabel yourWins = new JLabel();
static JLabel theirWins = new JLabel();
static JPanel yourPanel = new JPanel();
static JPanel middlePanel = new JPanel();
static JLabel blank1 = new JLabel();
static JLabel blank2 = new JLabel();
static JButton rock = new JButton("Rock");
static JButton paper = new JButton("Paper");
static JButton scissors = new JButton("Scissors");
static int yw = 0;
static int tw = 0;
static ButtonHandler listener = new ButtonHandler();

public static void main(String[] args) { 

    //Create the frame
    JFrame frame = new JFrame("Rock Paper Scissors");
    frame.setSize(500, 500); //Setting the size of the frame

    middle.setFont(new Font("Serif", Font.PLAIN, 30)); 
    middle.setHorizontalAlignment(SwingConstants.CENTER);
    them.setFont(new Font("Serif", Font.PLAIN, 15));
    them.setHorizontalAlignment(SwingConstants.CENTER);
    yourWins.setHorizontalAlignment(SwingConstants.CENTER);
    theirWins.setHorizontalAlignment(SwingConstants.CENTER);

    //Creating panels
    JPanel bigPanel = new JPanel();

    Border border = BorderFactory.createLineBorder(Color.BLACK, 1); 
    Border wlb = BorderFactory.createLineBorder(Color.RED, 1); 
    them.setBorder(border);
    yourPanel.setBorder(border);
    bigPanel.setBorder(border);
    yourWins.setBorder(wlb);
    theirWins.setBorder(wlb);
    middlePanel.setBorder(border);

    //Creating grid layouts 
    GridLayout yourGrid = new GridLayout(1,3,10,10); 
    GridLayout theirGrid = new GridLayout(1,1); //One row, one column
    GridLayout middleGrid = new GridLayout(5,1);
    GridLayout bigGrid = new GridLayout(3,1);//Two rows, one column

    //Setting the layouts of each panel to the grid layouts created above
    yourPanel.setLayout(yourGrid); //Adding layout to buttons panel
    them.setLayout(theirGrid); //Adding layout to label panel
    middlePanel.setLayout(middleGrid); 
    bigPanel.setLayout(bigGrid);

    //Adding r/p/s to your grid.
    yourPanel.add(rock);
    yourPanel.add(paper);
    yourPanel.add(scissors);

    //Adding w/l rations to middlegrid.
    middlePanel.add(theirWins);
    middlePanel.add(blank1);
    middlePanel.add(middle);
    middlePanel.add(blank2);
    middlePanel.add(yourWins);

    //Attaching the listener to all the buttons
    rock.addActionListener(listener);
    paper.addActionListener(listener);
    scissors.addActionListener(listener);

    bigPanel.add(them);
    bigPanel.add(middlePanel);
    bigPanel.add(yourPanel); 

    //Shows the score at 0-0.
    yourWins.setText("Your wins: " + yw);
    theirWins.setText("Their wins: " + tw);

    frame.getContentPane().add(bigPanel); //panel to frame 
    frame.setVisible(true); // Shows frame on screen
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

//Class represents what do when a button is pressed
private static class ButtonHandler implements ActionListener { 
    public void actionPerformed (ActionEvent e) {
        Timer timer = new Timer(1000, this);

        String tc = random();
        them.setText("They chose: " + tc + "!");
        if (e.getSource() == rock) {
            whoWins("rock", tc);
        } else if (e.getSource() == paper) {
            whoWins("paper", tc);
        } else if (e.getSource() == scissors) {
            whoWins("scissors", tc);
        }
        yourWins.setText("Your wins: " + yw);
        theirWins.setText("Their wins: " + tw);

        timer.setRepeats(false);
        timer.start();
    }
} 

public static String random() {
    int random = (int) (Math.random() * 3);
    if (random == 0) {
        return "Rock";
    } else if (random == 1) {
        return "Paper";
    } else if (random == 2) {
        return "Scissors";
    }
    return "";
}

public static void whoWins(String yc, String tc) {
    if (yc.equals("rock")) {
        if (tc.equals("Rock")) {
            middle.setText("It's a tie!");            
        } else if (tc.equals("Paper")) {
            middle.setText("You lose!");
            tw++;
        } else if (tc.equals("Scissors")) {
            middle.setText("You win!");
            yw++;
        }
    } else if (yc.equals("paper")) {
        if (tc.equals("Rock")) {
            middle.setText("You win!");
            yw++;
        } else if (tc.equals("Paper")) {
            middle.setText("It's a tie!");
        } else if (tc.equals("Scissors")) {
            middle.setText("You lose!");
            tw++;
        }
    } else if (yc.equals("scissors")) {
        if (tc.equals("Rock")) {
            middle.setText("You lose!");
            tw++;
        } else if (tc.equals("Paper")) {
            middle.setText("You win!");
            yw++;
        } else if (tc.equals("Scissors")) {
            middle.setText("It's a tie!");
        }
    }
}
}

實際發生的事情是從按下按鈕到顯示消息沒有延遲,因為顯然我沒有正確使用計時器。 我希望計時器僅運行一次,然后運行該代碼即可執行。 但是,當我單擊按鈕時,盡管setRepeats為false,計時器仍將重復運行。 因此,我要顯示的消息會立即顯示,而不是被延遲,但會立即顯示,但隨后會循環並繼續顯示消息(消息是隨機的),直到我關閉程序為止。 如果再次單擊該按鈕,它將使計時器的速度翻倍,並且消息顯示的速度快兩倍,依此類推。

them.setText("They chose: " + tc + "!");

這是重復顯示的消息,變量tc每次都會更改。 計時器似乎只是在每個計時器間隔(1s)中顯示此消息。

任何幫助將不勝感激。

編輯:

所以我添加了本節:

private static class ButtonHandler implements ActionListener { 
    public void actionPerformed (ActionEvent e) {
        // I'd be disabling the buttons here to prevent
        // the user from trying to trigger another 
        // update...

        // This is an instance field which is used by your
        // listener

        Timer timer = new Timer(1000, listenert);
        timer.setRepeats(false);
        timer.start();
    }
}
private static class timer implements ActionListener {
    public void actionPerformed (ActionEvent e) {
        String tc = random(); //A method that chooses a random word.
        them.setText("They chose: " + tc + "!"); 
        if (e.getSource() == rock) {
            whoWins("rock", tc); //whoWins is a method that will display a message.
        } else if (e.getSource() == paper) {
            whoWins("paper", tc);
        } else if (e.getSource() == scissors) {
            whoWins("scissors", tc);
        }
        yourWins.setText("Your wins: " + yw);
        theirWins.setText("Their wins: " + tw);

        // Start another Timer here that waits 1 second
        // and re-enables the other buttons...
    }
}

因此,我現在所相信的是,當我單擊按鈕時,buttonhandler偵聽器將啟動計時器,該計時器將連接到計時器偵聽器(名為listenert),該計時器將在計時器類的actionPerformed中運行代碼。 但是睡眠功能仍然不起作用

編輯2.5:

 private static class ButtonHandler implements ActionListener { 
    public void actionPerformed (ActionEvent e) {
        final JButton button = (JButton)e.getSource();
        Timer timer = new Timer(1000, new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        String tc = random();
                        them.setText("They chose: " + tc + "!");
                        if (button == rock) {
                            whoWins("rock", tc);
                        } else if (button == paper) {
                            whoWins("paper", tc);
                        } else if (button == scissors) {
                            whoWins("scissors", tc);
                        }
                        yourWins.setText("Your wins: " + yw);
                        theirWins.setText("Their wins: " + tw);
                    }
                });
        timer.setRepeats(false);
        timer.start();     

    }
} 

到目前為止,我只需要在它們之后添加另一個睡眠即可。setText(“他們選擇了:” + tc +“!”); 如果有的話,我該在哪里放置timer.restart()? timer.start()位於我不太了解的方法的末尾。

因此,當計時器“滴答”時,將通知您提供給TimerActionListener ,因此ButtonHandler actionPerformed應該看起來更像...

public void actionPerformed (ActionEvent e) {
    // I'd be disabling the buttons here to prevent
    // the user from trying to trigger another 
    // update...

    // This is an instance field which is used by your
    // listener
    choice = e.getSource();

    Timer timer = new Timer(1000, listener);
    timer.setRepeats(false);
    timer.start();
}

您的listener應該看起來更像

public void actionPerformed (ActionEvent e) {
    String tc = random(); //A method that chooses a random word.
    them.setText("They chose: " + tc + "!"); 
    if (choice == rock) {
        whoWins("rock", tc); //whoWins is a method that will display a message.
    } else if (choice == paper) {
        whoWins("paper", tc);
    } else if (choice == scissors) {
        whoWins("scissors", tc);
    }
    yourWins.setText("Your wins: " + yw);
    theirWins.setText("Their wins: " + tw);

    // Start another Timer here that waits 1 second
    // and re-enables the other buttons...
}

例如...

您可以考慮查看如何使用Swing計時器以了解更多詳細信息

更新

從一個簡單的示例開始...公共類TestPane擴展了JPanel {

    private JLabel label;
    private SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

    public TestPane() {
        setLayout(new GridBagLayout());
        label = new JLabel();
        add(label);
        tick();

        Timer timer = new Timer(500, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tick();
            }
        });
        timer.start();
    }

    protected void tick() {

        label.setText(sdf.format(new Date()));

    }
}

這只是每半秒調用一次tick方法以更新JLabel上的時間...

首先導入以下內容;

import java.awt.event.ActionEvent ;

import java.awt.event.ActionListener ;

import javax.swing.Timer ; 

然后像這樣在表單的末尾初始化計時器; 公共靜態void main(String args []){

 java.awt.EventQueue.invokeLater(new Runnable() {        
            public void run() {       
            new mainprogramme().setVisible(true);    
        }    

});

}    
    private Timer timer ;

然后在初始化計時器之后,添加一個公共類,如下所示;

公共類的進度實現了ActionListener {public void actionPerformed(ActionEvent evt){

int n = 0 ;
if (n<100){
    n++ ;
    System.out.println(n) ;
}else{
    timer.stop() ;
}
}
}

完成此操作后,轉到j框架>右鍵單擊並選擇>事件>窗口>打開的窗口,然后鍵入以下內容;

private void formWindowOpened(java.awt.event.WindowEvent evt) {                                  
        timer = new Timer(100,new progress()) ;

在完成所有這些操作之后,將按鈕命名為任何名稱,然后在其空白處輸入following,如下所示;

 timer.start();

這就是代碼,然后回復我...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM