-1

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

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

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();

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

4

1 回答 1

5

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

要记住的重要事项是,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();
        }
    }
}

另一种选择是使用 a 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);

                }

            }

        }

    }
}

查看Swing 中的并发以获取更多详细信息

于 2013-06-28T04:38:04.827 回答