Параметры запуска / остановки таймера

#java #timer #if-statement #conditional

#java #таймер #if-оператор #условные операторы

Вопрос:

С тех пор, как я присоединился к этому сообществу, я добился больших успехов в навыках и прогрессе. Вы все очень помогаете. У меня возникли проблемы с заданием таймера, для которого я реализовал определенные параметры, когда он запускается и останавливается.

Я либо получаю ошибки, говорящие: «возможно, таймер локальной переменной не был инициализирован», либо я не получаю ошибок, но ничего не происходит. Может быть, у меня таймер не в том месте?

Если я тоже добавлю timer.start(); конструктор, все будет работать нормально, но тогда таймер должен запуститься при инициализации программы. Мне бы очень хотелось, чтобы таймер не запускался до тех пор, пока не будет выполнен определенный параметр. Скажем, например, до тех int p1Laps=1; пор, пока but if я не помещу timer.start(); в оператор if в конструкторе (т. Е. if(p1Laps>=1) { timer.start(); } Таймер никогда не запускается.

Я пробовал размещать timer.start(); в разных местах и либо не получил ответа, либо выдал сообщение об отсутствии локальной переменной timer .

Вторая, несколько связанная с этим проблема, с которой я сталкиваюсь, — это невозможность установить какие-либо параметры для вызова timer.stop(); без получения вышеупомянутой ошибки «таймер локальной переменной, возможно, не был инициализирован». Я оставил timer.stop(); там, где, по моему мнению, это должно быть в коде, но он получает эту ошибку.

Короче говоря, я хочу иметь возможность указывать таймеру запускаться при выполнении параметра, а именно, когда игрок завершил круг. И я хочу иметь возможность указать таймеру остановиться, когда он достигнет значения.

Заранее спасибо за отличный совет, который, я уверен, я получу. Примечание: это не весь код, а только соответствующая информация.

 import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.awt.geom.*;

public class RacerDoom extends JFrame {
    int counter = 0;
    int p1Laps = 0;
public RacerDoom() {
        //create JFrame
        super("Racer Doom Squared");
        setSize(WIDTH,HEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
        //set up Timer
        final Timer timer=new Timer(1000, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(counter>=10) {
                    timer.stop(); //error here reads "local variable timer may
                                    //not have been initialized"
                }
                else{
                   counter  ;
                   }
                System.out.println(counter);
            }
        });
        //inner class threads
        Move1 m1 = new Move1();
        m1.start();
        //start timer
        if(p1Laps>=1) {
            timer.start(); //error here is that timer will not start when
                            //p1Laps>=1
        }
    }
    private class Move1 extends Thread implements KeyListener {
        public void run() {
            addKeyListener(this);
            while(true) {
                try {
                    repaint();
                    //collisions
                    if(p1.intersects(finishtop)amp;amp;p1Direction==UPamp;amp;p1cross!=true){
                        p1cross=true;
                        p1Laps  ;
                        p1Boost  ;
                        counter=0;
                        System.out.println(p1Laps);
                    }
                    if(p1.intersects(finishtop)==false) {
                        p1cross=false;
                    }
    public static void main (String [] args) {

        new RacerDoom();
    }
}
  

Ответ №1:

Поскольку вы хотите запускать и останавливать таймер в разных местах кода, вы должны сделать его переменной-членом. Это устранит проблему, когда вы пытаетесь остановить таймер внутри прослушивателя действий.

Переменная p1Laps не изменится в конструкторе (после того, как вы инициализировали ее в 0), поэтому вам нужно запустить таймер, в котором вы меняете значение plLaps . Я не уверен, безопасно ли вызывать timer.start() из другого потока (Move1). Поэтому может быть безопаснее запускать таймер с помощью SwingUtilities.invokeLater().

Комментарии:

1. Мне нужно изучить SwingUtilities.invokeLater() , поскольку я видел, что это упоминалось несколько раз на этом сайте, но я совершенно не знаком с ним.

2. Привет, могу я задать несколько вопросов? В java, если мы присвоим объекту timer значение null (timer = null;) без вызова timer.stop() перед этим, перестанет ли таймер запускаться для слушателя?

3. Нет, это не остановит таймер, поскольку ссылка на таймер по-прежнему будет присутствовать во внутренней очереди или тайм-драйверах, которые будут запущены (поддерживаются внутренним потоком).

Ответ №2:

Быстрое исправление:

Вместо

 timer.stop();
  

Сделать

 ((Timer)e.getSource()).stop();
  

Метод getSource ActionEvent вернет ссылку на объект, который вызывает метод actioPerformed (таймер), так что это должно сработать.

Могут быть другие проблемы с вашим кодом, включая фоновый поток без Thread.sleep(…), использование вами KeyListeners вместо привязки ключа, добавление KeyListener в фоновый поток,…

Комментарии:

1. Извините, в моем фоновом потоке есть Thread.sleep(...); , я просто забыл его включить.