1

我想做的很简单,我想在屏幕上显示算法的步骤,因此为什么我试图将 repaint() 与 sleep() 结合起来,但我做错了,如果有人知道的话,我会喜欢它关于它首先解释这段代码有什么问题,其次,我该怎么做才能让它工作......

谢谢!

总而言之,这段代码的目的是绘制 10 个红色顶点,然后以 200 毫秒的间隔一个一个地涂黑。

这是代码:

public class Tester {

       public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    ShowGUIGraph();
                }
            });
        }

        private static void ShowGUIGraph() {
            JFrame f = new JFrame("something");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            JPanel p=new JPanel();
            p.setLayout(new BorderLayout());
            p.add(BorderLayout.CENTER,new SomePanel());
            f.add(p);
            f.setPreferredSize(new Dimension(800,600));
            f.pack();
            f.setVisible(true);
        }
}

public class SomePanel extends JPanel {
    private static final long serialVersionUID = 1L;
    LinkedList<Vertex> vertices=new LinkedList<Vertex>();
    public SomePanel () {
        for (int i=0;i<10;i++) {
            Vertex v=new Vertex(i);
            v.setLocation(20+30*i, 20+30*i);
            vertices.add(v);
        }
        traverseVerticesRecoursive(0);
        traverseVerticesNonRecoursive();
    }
    public void traverseVerticesRecoursive(int i) {
        if (i>=vertices.size()) return;
        vertices.get(i).setColor(Color.black);

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        repaint();
        traverseVerticesRecoursive(i+1);
    }
    public void traverseVerticesNonRecoursive() {
        for (int i=0;i<10;i++) {
            vertices.get(i).setColor(Color.red);
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            repaint();
        }
    }
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (int i=0;i<vertices.size();i++) {
            vertices.get(i).paintVertex(g);
        }

    }
}
   public class Vertex {
        private int x,y,tag,r=20;
        private Color color=Color.red;
        Vertex (int i) {
            tag=i;
        }
        public void setLocation(int x0,int y0) {
            x=x0;
            y=y0;
        }
        public int getX() {
            return x;
        }
        public int getY() {
            return y;
        }

        public void setColor(Color c) {
            color=c;
        }
        public boolean colorIs(Color c) {
            return (color.equals(c));
        }

        public void paintVertex(Graphics g) {
            g.setColor(color);
            g.fillOval(x,y,r,r);
            g.setColor(Color.BLACK);
            g.drawOval(x,y,r,r);
            g.drawString(""+tag, x+r/2, y+r/2+4);
        }
        public int getR() {
            return r;
        }
    }
4

4 回答 4

4

不要在 Event Dispatch Thread 中休眠;这将导致 GUI 冻结。对于动画,请使用对 EDT 友好的实用程序类,例如javax.swing.Timer.

于 2012-01-09T16:49:28.517 回答
1

只是一些可能使您的代码更清洁的想法:

  1. 在您的SomePanel类中,将遍历代码放在构造函数之外的方法中。构造函数用于初始化字段。
  2. 首先启动您的静态 GUI,然后生成一个工作线程以通过以前的方法进行更新(这将是您的小型“引擎”)。在此线程中,您可以调用sleep.
  3. 在您的traverseVerticesRecoursive方法中,仅在 UI 线程上进行重绘,并在您的工作线程上进行状态更新。

你应该做的主要修改是不要用睡眠调用阻塞 GUI 线程,正如他们在第一个答案中告诉你的那样。

于 2012-01-09T17:35:54.097 回答
0

Thread.sleep是一项长期运行的任务。当您在 EDT 中运行此类任务时,它会阻止执行所有重绘请求。在睡眠阶段发送的所有未决的重绘请求都将排队等待将来处理。

结果,当 EDT 退出sleep阶段时,它将所有此类重绘请求(如果启用了默认属性的合并)合并为一个执行的重绘。如果未启用合并,则所有排队的请求都将连续执行,中间没有任何时间间隔。结果似乎UI没有更新。

要纠正这种情况timer,请在特定时间间隔后定期触发。

于 2013-01-22T15:26:46.963 回答
0

伙计,您可以使用与 EDT 线程不同的新线程来制作动画。例如,

 void play() {
    Thread thread = new Thread() {
        @Override
        public void run() {
            game();
        }
    };
    thread.start();
}

void game() {
    for (; ; ) {
        switch (state) {
            case GameData.ANIMATING:
                // call some function as repaint() to update GUI
                break;
            case GameData.GAME_ENDED:
                return;
            default:
                break;
        }

        diffTime = System.currentTimeMillis() - beforeTime;
        sleepTime = delay - diffTime;
        sleepTime = (sleepTime < 0) ? 0 : sleepTime;
        Thread.sleep(sleepTime);
    }
}
于 2016-12-29T14:28:17.713 回答