Java,无限循环的替代?

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

我是一个新手,但我现在在一个java类。 所以我掌握了一些语言。

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

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

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

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

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

 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; } } } 

我建议使用一个单独的线程来处理数组。 确保使用线程安全对象(检查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; } } 

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

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

我个人更喜欢使用Timer类而不是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(); 

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

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

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

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