Java,无限循环的替代?

时间:2010-01-19 19:52:35

标签: java loops replace interruptions

我正在制作一个通过阵列显示细胞生长的程序。当我按下开始按钮时,我已经得到了它,数组在一段时间(真实){}循环中每10秒更新一次。问题是我希望能够通过按下暂停按钮来停止循环,但在循环中,它不会让我使用任何控件。我需要在orer中使用除了无限循环之外的其他东西来刷新帧。

我是一个新手,但我目前正在上一节java课程。所以我掌握了一些语言。

9 个答案:

答案 0 :(得分:10)

我建议使用一个单独的线程来处理数组。确保使用线程安全对象(检查Java Docs),并在想要启动时在线程对象上调用.start()。保持指向它的指针,以便您可以通过setPaused(true)暂停它

像这样......

class MyArrayUpdater extends Thread {
    private volatile boolean enabled = true;
    private volatile boolean paused = true;

    @Override
    public void run() {
        super.run();
        try {
            while (enabled) {
                if (!paused) {
                    // Do stuff to your array here.....
                }
                Thread.sleep(1);
            }
        } catch (InterruptedException ex) {
            // handle ex
        }
    }

    public void setEnabled(boolean arg) {
        enabled = arg;
    }

    public void setPaused(boolean arg) {
        paused = arg;
    }
}

答案 1 :(得分:6)

您需要的是使用Timer来更改组件的状态(在这种情况下是细胞增长),然后调用JComponent.repaint()

此计时器可以cancelled进行暂停,然后重新启动它,您只需创建一个新计时器:

所以你可以定义以下两种方法:

private Timer timer;
...
public void startPaiting() {
    timer = new Timer();
    timer.schedule( new TimerTask(){
        public void run(){
            changeState();
            repaint();
        }
    },0,  10000 ); // 10 s. 
}

public void pause(){
    timer.cancel();
}

然后在“暂停/恢复”按钮中调用此“暂停/启动”方法:

if( e.getActionCommand().equals("Pause")){
    growPanel.pause();
    setText("Resume");
} else {
    growPanel.startPaiting();
    setText("Pause");
}

http://img512.imageshack.us/img512/7119/capturadepantalla201001.png

以下是运行的完整源代码:

import javax.swing.*;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.*;
import java.util.Timer;
import java.util.TimerTask;

public class Grow {

    public static void main( String [] args ) {
        JFrame frame = new JFrame();
        final GrowPanel growPanel = new GrowPanel();
        frame.add( growPanel );
        frame.add( new JPanel(){{
            add( new JButton("Pause"){{
                addActionListener( new ActionListener(){
                    public void actionPerformed( ActionEvent e ){
                        if( e.getActionCommand().equals("Pause")){
                            growPanel.pause();
                            setText("Resume");
                        } else {
                            growPanel.startPaiting();
                            setText("Pause");
                        }
                    }
                });
        }});}}, java.awt.BorderLayout.SOUTH );
        frame.setSize( 400, 300 );
        frame.setVisible( true );
    }
}

class GrowPanel extends JComponent {
    private int x;
    private int y;
    private Timer timer;
    GrowPanel() {
        x = 10;
        y = 10;
        startPaiting();
    }

    public void startPaiting() {
        timer = new Timer();
        timer.schedule( new TimerTask(){
            public void run(){
                changeState();
                repaint();
            }
        },0,  100 ); // or 10000 which is 10 s. 
    }

    public void pause(){
        timer.cancel();
    }

    public void paintComponent( Graphics g ){
        g.fillOval( x, y, 10, 10 );
    }
    private void changeState(){
            x+=10;
            if( x >= 400 ) {
                y+=10;
                x = 0;
            }
            if( y >= 300 ){
                y = 10;
            }
    }

}

答案 2 :(得分:2)

如果这些“按钮”是Swing按钮,那么执行此操作的方法是:让“开始”按钮创建一个新的javax.swing.Timer对象,该对象每10秒进行一次更新。然后让“暂停”按钮停止该计时器。

答案 3 :(得分:1)

您想在线程中运行模拟(查找可运行的接口)。 然后,您可以将消息传递给此线程以暂停,继续和停止。

答案 4 :(得分:1)

我个人更喜欢使用the Timer class而不是ThreadThread.sleep()。 timer类处理定期运行代码并取消它。

您的代码如下:

TimerTask myTask = new TimerTask() {
  public void run() {
    // here goes my code
  }
};

Timer timer = new Timer();
timer.schedule(myTask, 0 /*starts now*/, 10 * 1000 /* every 10 seconds */);

// whenever you need to cancel it:
timer.cancel();

答案 5 :(得分:0)

是的。听起来你正在事件调度程序线程上进行绘图。事件(按钮按下)从来没有机会被调用,因为你从上次调用它时从未返回控制...

答案 6 :(得分:0)

您正在寻找的是多线程。进行数据处理并将其放入第二个线程,异步运行,并使用主线程检查用户输入。

当然,这也可能需要使用信号量在两个线程之间进行通信。你在什么级别的班级 - 你已经涵盖了这两个主题吗?

答案 7 :(得分:0)

看一下wait()/ notify()机器。简而言之,一个线程可以等待10秒,但仍然会收到外部事件发生的通知,

答案 8 :(得分:0)

处理此问题的另一种方法是使用BlockingQueue个作业。

相关问题