首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用swing创建计时器

如何使用swing创建计时器
EN

Stack Overflow用户
提问于 2018-06-14 05:33:32
回答 1查看 144关注 0票数 0

我想创建一个计时的计时器。由于我的游戏使用swing组件,因此我也想使用swing组件来完成此任务。

我还希望计时器被重新绘制到一个JLabel上。当玩家与finish JLabel发生冲突时,它应该停止计时器

当我尝试在JLabel上打印计时器时,我得到了这个问题: javax.swing.Timer@42cc41de

这个类是游戏面板class.It,游戏的所有组件都是在这个类中创建的。墙就是在这里创建的。冲突是一个使用索引的for循环。这些墙排列成一个阵列。这是我的游戏的精简版,只有6面墙。我通常有49个。我还减少了一些不必要的类,比如一个用于文件的类和另一个包含第二个迷宫的类。

代码语言:javascript
复制
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.time.Duration;
import java.time.Instant;

/**
 * demonstrates basic animation using a timer, an action listener, and a key
 * listener demonstrates basic collisions between rectangular objects
 * 
 * @author 602052004
 */

public class GamePane extends JPanel implements ActionListener, KeyListener {// *change
                                                                                // GamePane
                                                                                // to
                                                                                // GamePane
    // This is were the game screen is made and the player is created.

    static final long serialVersionUID = 1L;

    private Duration timeOutDuration = Duration.ofSeconds(5);
    private Instant startTime; // Set this when you're ready to start the timer


    JLabel player = new JLabel();
    JLabel finish = new JLabel();
    JLabel instructions = new JLabel(
            "The controls for this game will be using the WASD keys. W is going up, A is going to the left, S is going down and, D is going right.");
    JFrame gameFrame;
    int playerSpeed = 4;
    int FPS = 40;

    // This array holds my Jlabels for the walls.I used it so that i can have a
    // for loop with an index for the labels.
    JLabel[] walls = new JLabel[6];//this is cut down from 49-6
    {

        walls[0] = new JLabel();
        walls[1] = new JLabel();
        walls[2] = new JLabel();
        walls[3] = new JLabel();
        walls[4] = new JLabel();
        walls[5] = new JLabel();

    }
    private final Set<Integer> keys = new HashSet<>();

    // The keys set holds the keys being pressed

    public static void main(String[] args) {
        // Open the GUI window
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                // Create a new object and
                // run its go() method
                new GamePane().go();
            }
        });
    }

    GamePane() {
        // Run the parent class constructor
        super();
        // Allow the panel to get focus
        setFocusable(true);
        // Don't let keys change the focus

    }

    protected void go() {
        setLayout(new CardLayout());
        // Setup the window
        gameFrame = new JFrame();
        // Add this panel to the window
        gameFrame.setLayout(new CardLayout());
        gameFrame.add(this, "main");
        gameFrame.setContentPane(this);

        // Set's the window properties
        gameFrame.setTitle("main");
        gameFrame.setSize(800, 600);
        gameFrame.setLocationRelativeTo(null);
        gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        gameFrame.setVisible(true);
        gameFrame.add(new ButtonPane(gameFrame), "buttons");
        // Creates the new JPanel that will hold the game.
        JPanel gamestage = new JPanel();
        gamestage.setBackground(Color.darkGray);
        gameFrame.add(gamestage, "game");
        gamestage.setLayout(null);
        // *Move the setup of the player and the timer under the walls
        // Get a sample of collisions going so that i can do it over the weekend
        // Setup the movable box
        player.setBounds(25, 25, 20, 20);
        player.setVisible(true);
        player.setBackground(Color.red);
        // Opaque makes the background visible
        player.setOpaque(true);

        // Setup the key listener
        addKeyListener(this);
        // Null layout allows moving objects!!!
        gamestage.add(player);
        // Set the timer
        Timer tm = new Timer(1000 / FPS, this);
        tm.start();
        Timer gameTimer = new Timer(1000 / 30, this);
        gameTimer.start();
        System.out.println(gameTimer);
        walls[0].setBounds(10, 15, 10, 480);// left height
        walls[0].setVisible(true);
        walls[0].setBackground(Color.white);
        walls[0].setOpaque(true);
        gamestage.add(walls[0]);

        walls[1].setBounds(10, 10, 490, 10);// top width
        walls[1].setVisible(true);
        walls[1].setBackground(Color.white);
        walls[1].setOpaque(true);
        gamestage.add(walls[1]);

        walls[39].setBounds(490, 10, 10, 480);// Right width
        walls[39].setVisible(true);
        walls[39].setBackground(Color.white);
        walls[39].setOpaque(true);
        gamestage.add(walls[39]);

        // wall3.setBounds(x, y, width, height);
        walls[2].setBounds(10, 100, 100, 10);
        walls[2].setVisible(true);
        walls[2].setBackground(Color.white);
        walls[2].setOpaque(true);
        gamestage.add(walls[2]);

        walls[3].setBounds(100, 60, 10, 40);
        walls[3].setVisible(true);
        walls[3].setBackground(Color.white);
        walls[3].setOpaque(true);
        gamestage.add(walls[3]);

        walls[4].setBounds(70, 60, 35, 10);
        walls[4].setVisible(true);
        walls[4].setBackground(Color.white);
        walls[4].setOpaque(true);
        gamestage.add(walls[4]);


        finish.setBounds(30, 455, 20, 20); // *make the game change to the main
                                            // screen when finished
                                            // Add a timer
        finish.setVisible(true);
        finish.setBackground(Color.LIGHT_GRAY);
        finish.setOpaque(true);
        gamestage.add(finish);

        instructions.setVisible(true);
        instructions.setOpaque(true);
        instructions.setBounds(510, 10, 265, 525);
        instructions.setBackground(Color.GRAY);
        instructions.setForeground(Color.white);
        gamestage.add(instructions);

    }

    /**
     * Check if two JLabel objects are touching &
     * 
     * @param a
     *            The first JLabel
     * @param b
     *            The second JLabel
     * @return true if the JLabels are touching
     */
    public boolean areColliding(JLabel a, JLabel b) {
        return a.getBounds().intersects(b.getBounds());
    }

    /**
     * this method makes the player move. It takes the players speed and subtracts
     * or adds the player speed to the current position of the player. It also
     * figures out were the player is at currently as well. This method also
     * contains a for loop which is used to see if the player is colliding with the
     * walls
     * 
     * @param arg0
     */
    @Override
    public void actionPerformed(ActionEvent arg0) {
        // Move up if W is pressed
        if (keys.contains(KeyEvent.VK_W)) {
            player.setLocation(player.getX(), player.getY() - playerSpeed);
        }
        // Move right if D is pressed
        if (keys.contains(KeyEvent.VK_D)) {
            player.setLocation(player.getX() + playerSpeed, player.getY());
        }
        // Move down if S is pressed
        if (keys.contains(KeyEvent.VK_S)) {
            player.setLocation(player.getX(), player.getY() + playerSpeed);
        }
        // Move left if A is pressed
        if (keys.contains(KeyEvent.VK_A)) {
            player.setLocation(player.getX() - playerSpeed, player.getY());
        }

        for (int i = 0; i < walls.length; i++) {
            if (areColliding(walls[i], player)) { // Reposition the target
                int newX = (int) (25);// This is the new location of the player in the X axis once it hits a wall
                int newY = (int) (25);// this is the new location of the player in the Y axis once it hits a wall
                player.setLocation(newX, newY);// Sets the location of the player once the new X and Y location is set

            }
        }

        if (areColliding(finish, player)) {// to change the pane when you fimish the game
            // Reposition the target
            int newX = 25;
            int newY = 25;
            player.setLocation(newX, newY);
            CardLayout layout = (CardLayout) gameFrame.getContentPane().getLayout();
            layout.show(gameFrame.getContentPane(), "buttons");
        }

        if (startTime != null) {
            Duration runningTime = Duration.between(startTime, Instant.now());
            Duration timeRemainig = timeOutDuration.minus(runningTime);
            if (timeRemainig.isNegative() || timeRemainig.isZero()) {
                // Time has run out...
                 startTime = null; // stop the timer
                 System.out.println("finish");
            } else {
                // Update the UI
                repaint();
            }
        }
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // Add the key to the list
        // of pressed keys
        if (!keys.contains(e.getKeyCode())) {
            keys.add(e.getKeyCode());
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
        // Remove the key from the
        // list of pressed keys
        keys.remove((Integer) e.getKeyCode());
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }


}

这是包含按钮和操作侦听器的按钮窗格。它还会为我更改屏幕。

代码语言:javascript
复制
/**
 * This pane contains the button and sets up the button pane
 */
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ButtonPane extends JPanel {

    private JButton startBTN;// Calls the JButton
    JFrame game;

    public ButtonPane(JFrame g) {
        game = g;
        setLayout(new GridBagLayout());
        setBackground(Color.gray);// Sets the menu stages color blue
        startBTN = new JButton("Start");// Creates a new button
        add(startBTN);// Adds the button on the startStage



        startBTN.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (game.getContentPane().getLayout() instanceof CardLayout) {
                    CardLayout layout = (CardLayout) getParent().getLayout();
                    layout.show(game.getContentPane(), "game");

                }
            }
        });
    }

}
EN

回答 1

Stack Overflow用户

发布于 2018-06-14 06:21:46

当我试图在JLabel上打印出计时器时,我得到了这个问题: javax.swing.Timer@42cc41de

Timer不携带任何“时间”信息,它只是负责在事件调度线程上定期调度回调。

为了打印运行时间或剩余时间,您需要根据需要格式化Duration

因此,在此块中,您需要使用一些信息实际更新标签,调用repaint将简单地绘制状态。

代码语言:javascript
复制
if (startTime != null) {
    Duration runningTime = Duration.between(startTime, Instant.now());
    Duration timeRemainig = timeOutDuration.minus(runningTime);
    if (timeRemainig.isNegative() || timeRemainig.isZero()) {
        // Time has run out...
         startTime = null; // stop the timer
         System.out.println("finish");
    } else {
        // Update the UI
        //repaint();
        // Format the duration and update the label...
    }
}

How could I add a refreshing timer to a JLabel using swing components中所述,您可以使用以下命令生成DurationString

代码语言:javascript
复制
long hours = timeRemainig.toHours();
long mins = timeRemainig.minusHours(hours).toMinutes();

// Or if you're lucky enough to be using Java 9+
//String formatted = String.format("%dhrs %02dmins", duration.toHours(), duration.toMinutesPart());
String formatted = String.format("%dhrs %02dmins", hours, mins);

然后相应地设置标签的文本

代码语言:javascript
复制
// Sorry can't identify your count down label...
countDownLabel.setText(formatted);

而且,您真的只需要一个Timer

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50846601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档