【问题标题】:Timer in Java swingJava swing 中的定时器
【发布时间】:2013-06-25 18:39:32
【问题描述】:

我正在尝试用 java swing timer 替换 Thread.sleep(),因为我听说这对图形来说更好。

以前,我有这样的设置,但它会干扰图形。

while(counter < array.size){
Thread.sleep(array.get(counter).startTime);
//do first task
Thread.sleep(array.get(counter).secondTime);
//do second task
Thread.sleep(array.get(counter).thirdTime);
//do third task
counter++
}

现在,我正在尝试用其中之一替换每个Thread.sleep(),然后我有在此之后发生的实际事件,但它似乎根本没有等待。

int test = array.get(counter).time;
ActionListener taskPerformer = new ActionListener(){
public void actionPerformed(ActionEvent evt){
}
};
Timer t = new Timer(test, taskPerformer);
t.setRepeats(false);
t.start();

基本上,我如何确保程序在不给它任何代码以在计时器内执行的情况下等待?谢谢!

【问题讨论】:

  • 那是......不是计时器所做的。
  • 好的,谢谢。如果你知道怎么做,那么你能回答我如何让 3 个连续的任务在一个接一个的循环中发生吗?
  • 您不希望程序等待。这个想法是每次计时器滴答时都会以某种方式改变程序的状态,然后绘制并启动下一个计时器......
  • 您可以在睡眠前将布尔变量设置为 false,因此每个动作侦听器(如果有)或其他任务管理器都会在布尔变量为 true 或其他等待锁定对象时工作,然后在睡眠后 notifyAll ,你的意思是“将等待而不给它任何代码在里面执行”?
  • 如何告诉计时器检查布尔值?

标签: java multithreading swing timer sleep


【解决方案1】:

答案归结为您想要实现的目标......

要记住的重要一点是,Swing 是单线程环境,也就是说,所有对 UI 的交互、更改、修改、更新和创建都是在事件调度线程的上下文中完成的。

任何阻止 EDT 的操作(例如 sleepwait 等)都会阻止 EDT 重新绘制 UI 或响应新事件。

实现此目的的一种方法是使用javax.swing.Timer

这是一个非常简单的例子,它使用了 3 个链接在一起的计时器。就个人而言,我会使用一个为短时间滴答配置的单个计时器,并检查是否发生了所需的延迟,然后相应地更改状态,但这得到了重点......

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SimpleTimer {

    public static void main(String[] args) {
        new SimpleTimer();
    }

    public SimpleTimer() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Timer red;
        private Timer green;
        private Timer yellow;
        private Color color = Color.GREEN;

        private Point spot;

        public TestPane() {
            red = new Timer(500, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    color = Color.RED;
                    green.start();
                    repaint();
                }
            });
            green = new Timer(2000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    color = Color.GREEN;
                    yellow.start();
                    repaint();
                }
            });
            yellow = new Timer(1000, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    color = Color.YELLOW;
                    red.start();
                    repaint();
                }
            });
            red.setRepeats(false);
            green.setRepeats(false);
            yellow.setRepeats(false);
            green.start();

            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    spot = e.getPoint();
                    repaint();
                }
            });

        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int radius = 20;
            int x = (getWidth() - radius) / 2;
            int y = (getHeight() - radius) / 2;
            g2d.setColor(color);
            g2d.fillOval(x, y, radius, radius);

            if (spot != null) {

                x = spot.x - 5;
                y = spot.y - 5;
                g2d.setColor(Color.RED);
                g2d.drawOval(x, y, 10, 10);
                g2d.setColor(Color.YELLOW);
                g2d.fillOval(x, y, 10, 10);

            }

            g2d.dispose();
        }
    }
}

另一种选择是使用SwingWorker,这允许在后台线程中进行某种处理(让 EDT 保持运行),但提供了可以简单地将结果同步回 EDT 的方法。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class SimpleTimer {

    public static void main(String[] args) {
        new SimpleTimer();
    }

    public SimpleTimer() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private Color color = Color.GREEN;

        private Point spot;

        public TestPane() {

            new Switcher().execute();

            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseMoved(MouseEvent e) {
                    spot = e.getPoint();
                    repaint();
                }
            });

        }

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

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int radius = 20;
            int x = (getWidth() - radius) / 2;
            int y = (getHeight() - radius) / 2;
            g2d.setColor(color);
            g2d.fillOval(x, y, radius, radius);

            if (spot != null) {

                x = spot.x - 5;
                y = spot.y - 5;
                g2d.setColor(Color.RED);
                g2d.drawOval(x, y, 10, 10);
                g2d.setColor(Color.YELLOW);
                g2d.fillOval(x, y, 10, 10);

            }

            g2d.dispose();
        }

        public class Switcher extends SwingWorker<Void, Color> {

            @Override
            protected void process(List<Color> chunks) {
                color = chunks.get(chunks.size() - 1);
                repaint();
            }

            @Override
            protected Void doInBackground() throws Exception {

                while (true) {

                    publish(Color.GREEN);
                    Thread.sleep(2000);
                    publish(Color.YELLOW);
                    Thread.sleep(500);
                    publish(Color.RED);
                    Thread.sleep(2000);

                }

            }

        }

    }
}

查看Concurrency in Swing了解更多详情

【讨论】:

  • 哇,这太棒了!非常感谢!
  • 希望它能帮助您实现您想要实现的目标
  • 哦,肯定会的。它是一个字幕应用程序,可以遍历网络上具有可用 SRT(字幕)文件的任何视频。
猜你喜欢
  • 2012-07-03
  • 2014-05-29
  • 1970-01-01
  • 2015-04-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
相关资源
最近更新 更多