创建Java计时器和计时任务?

4
我刚接触Java,正在尝试设置一个简单的定时器。由于之前有JavaScript和ActionScript的经验,我很熟悉set_interval。然而,由于我对类还不是很熟悉,所以容易感到困惑。虽然我正在查看文档,但我仍然不太清楚如何设置一个新的Timer并设置一个TimerTask
因此,我创建了一个Applet,这是我的init方法:
public void init() {
    TimerTask myTask;
    Timer myTimer;
    myTimer.schedule(myTask,5000);
}

我该如何实际设置任务代码? 我希望它能做一些像这样的事情:
g.drawString("Display some text with changing variables here",10,10);

3
请参考如何使用Swing计时器 - trashgod
1
我不同意这里所有的答案(即使是“甚至是相当好的可能性”),对于在Swing JComponentsAWT / Swing中进行绘画,正如@trashgod所指出的那样,只使用Swing Timer - mKorbel
4个回答

2

无论您想要执行什么操作,例如绘图或其他操作,只需定义任务并在其中实现代码。

import javax.swing.*;
import java.awt.*;
import java.util.Timer;
import java.util.TimerTask;

public class TimerApplet extends JApplet {

  String someText;
  int count = 0;

  public TimerApplet() {
    Timer time = new Timer();
    Сalculate calculate = new Сalculate();
    time.schedule(calculate, 1 * 1000, 1000);
  }

  class Сalculate extends TimerTask {

    @Override
    public void run() {
      count++;
      System.out.println("working.. "+count);
      someText = "Display some text with changing variables here.." +count;
      repaint();

    }
  }

  //This is how do you actually code.
  @Override
  public void paint(Graphics g)//Paint method to display our message
  {
//    super.paint(g);   flickering
    Graphics2D g2d = (Graphics2D)g;
    g2d.setColor(Color.WHITE);
    g2d.fillRect(0, 0, getWidth(), getHeight());
    if (someText != null) {
      g2d.setColor(Color.BLACK);
      g2d.drawString(someText,10,10);
    }

    //.....
  }
}

我可以问一下,为什么你使用了那个类:Сalculate吗? - Radicate
实际上,我想你只是自己创建了这个类,但出于某种原因,它一直给我一个错误,说它期望一个类、接口或枚举。 - Radicate
1
@RomanC:请再次查看您的答案。谁调用了这个paintComponent(...)方法(在您的代码中没有人调用它)。由于JApplet没有一个paintComponent()方法,它只有paint()/paintComponents()方法,所以如果您认为您正在覆盖其中一个,请尝试提供一个注释,以便编译器能够与您争论。 - nIcE cOw
1
@GagandeepBali +1 好建议,我有时间重新审查了我的答案并修复了一些错误。请查看新版本。 - Roman C

2

根据众多 Stackoverflow 用户的建议,这里正确的方法是使用 javax.swing.TImer。以下是一个小代码片段以供参考。如果有超出您理解范围的问题,请随时询问,我会提供相应的信息。

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;

public class DrawStringWithTimer
{
    private final int WIDTH = 400;
    private final int HEIGHT = 300;
    private Timer timer;
    private int x;
    private int y;
    private int counter;
    private Random random;
    private String[] messages = {
                                    "Bingo, I am ON",
                                    "Can you believe this !!",
                                    "What else you thinking about ?",
                                    "Ahha, seems like you are confused now !!",
                                    "Lets Roll and Conquer :-)"
                                };
    private CustomPanel contentPane;

    private ActionListener timerAction = new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent ae)
        {
            if (counter == 5)
                counter = 0;
            /*
             * Creating random numbers where 
             * x will be equal to zero or 
             * less than WIDTH and y will be
             * equal to zero or less than HEIGHT.
             * And we getting the value of the
             * messages Array with counter variable
             * and passing this to setValues function,
             * so that it can trigger a repaint()
             * request, since the state of the 
             * object has changed now.
             */ 
            x = random.nextInt(WIDTH);
            y = random.nextInt(HEIGHT);
            contentPane.setValues(x, y, messages[counter]);
            counter++;
        }
    };

    public DrawStringWithTimer()
    {
        counter = 0;
        x = y = 10;
        random = new Random();
    }

    private void displayGUI()
    {
        JFrame frame = new JFrame("Drawing String Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        contentPane = new CustomPanel(WIDTH, HEIGHT);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
        /*
         * javax.swing.Timer is what you need
         * when dealing with Timer related
         * task when using Swing.
         * For more info visit the link
         * as specified by @trashgod, in the
         * comments.
         * Two arguments to the constructor
         * specify as the delay and the 
         * ActionListener associated with 
         * this Timer Object.
         */
        timer = new Timer(2000, timerAction);
        timer.start();
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                new DrawStringWithTimer().displayGUI();
            }
        });
    }
}

class CustomPanel extends JPanel
{
    private final int GAP = 10;
    private int width;
    private int height;
    private int x;
    private int y;
    private String message = "";

    public CustomPanel(int w, int h)
    {
        width = w;
        height = h;

        setOpaque(true);
        setBackground(Color.WHITE);
        setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP));
    }

    public void setValues(int x, int y, String msg)
    {
        this.x = x;
        this.y = y;
        message = msg;

        /*
         * As the state of the variables will change,
         * repaint() will call the paintComponent()
         * method indirectly by Swing itself. 
         */
        repaint();
    }

    @Override
    public Dimension getPreferredSize()
    {
        return (new Dimension(width, height));
    }

    @Override
    protected void paintComponent(Graphics g)
    {
        /*
         * Below line is used to draw the JPanel
         * in the usual Java way first.
         */
        super.paintComponent(g);
        /*
         * This line is used to draw the dynamic
         * String at the given location.
         */
        g.drawString(message, x, y);
    }
}

@Don:正如 @mKorbel@trashgod 所指出的那样,Swing Timer非常适合与Swing相关的任务。来自trashgod指定链接的一句话说道:“通常情况下,我们建议使用Swing计时器而不是通用计时器来处理GUI相关任务,因为Swing计时器都共享同一个预先存在的计时器线程,并且GUI相关任务会自动在事件分派线程上执行。但是,如果您不打算从计时器中触及GUI,或者需要执行长时间的处理,则可以使用通用计时器。” - nIcE cOw
@Don:这里有许多不同的惊人示例,由**@mKorbel示例@trashgod**提供。 - nIcE cOw
那么,如果我的目标是创建一个简单的2D游戏,我的最佳选择是Timer而不是Swing Timer?或者... - Radicate
在进行与图形相关的操作时,您需要进入EDT以对GUI进行更改。因此,如果您使用Swing Timer,则与在EDT上执行任务相关的许多事情将由Swing Timer处理,尽管如果您计划使用普通的java.util.Timer,则必须显式地在EDT上执行更改以更改GUI,这是一项有点繁琐的任务,因为Swing Timer会隐式地为您处理此方面的问题,而无需您关心。 - nIcE cOw
这里有一个使用线程的例子(链接:https://dev59.com/MGnWa4cB1Zd3GeqP5OMX#13004927),它执行冒泡排序然后进行二分查找。但是,既然你说类使你感到困惑,我建议最好先熟悉类和对象,然后再进入 Swing 的世界。 - nIcE cOw
显示剩余2条评论

1

我已经在我的小应用程序中解决了同样的问题,我知道我的解决方案不是最好的,但它很简单。只需在自定义内部类中使用两个自变参数即可。这是我的代码。

final static Random random = new Random();
 ....//other codes
static class MyTimerTask extends TimerTask {

        int index_x = random.nextInt(50);
        int index_y = random.nextInt(50);

        @Override
        public void run() {
            System.out.println("Display some text with changing variables here: " + index_x + "," + index_y);
            index_x = random.nextInt(50);
            index_y = random.nextInt(50);
            System.gc();
        }

        public static MyTimerTask getInstance() {
            return new MyTimerTask();
        }

    }

1

在此链接中按您的期望进行示例

计时器将在我们的应用程序中一直运行,直到应用程序关闭或没有更多的作业可分配或安排。

TimerTask - 这是一个任务,它具有基于时间或持续时间运行的某些功能。

计时器中,我们将分配 TimerTask 以在特定持续时间内运行或在特定持续时间开始运行。

请了解其工作原理,然后使用小程序或其他应用程序进行应用。

1、GCTask类扩展了TimerTask类并实现了run()方法。

2、在TimerDemo程序中,实例化了一个Timer对象和一个GCTask对象。

3、使用Timer对象,使用Timer类的schedule()方法安排任务对象在5秒延迟后执行,然后继续每5秒执行一次。

4、main()中的无限while循环实例化了SimpleObject类型的对象(其定义如下),这些对象立即可供垃圾回收。

import java.util.TimerTask;

public class GCTask extends TimerTask
{
    public void run()
    {
        System.out.println("Running the scheduled task...");
        System.gc();
    }
}

import java.util.Timer;
public class TimerDemo
{
    public static void main(String [] args)
    {
        Timer timer = new Timer();
        GCTask task = new GCTask();
        timer.schedule(task, 5000, 5000);
        int counter = 1;
        while(true)
        {
            new SimpleObject("Object" + counter++);
            try
            {
                Thread.sleep(500);
            }
            catch(InterruptedException e) {}
        }
    }
}

public class SimpleObject
{
    private String name;
    public SimpleObject(String n)
    {
        System.out.println("Instantiating " + n);
        name = n;
    }
    public void finalize()
    {
        System.out.println("*** " + name + " is getting garbage collected ***");
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接