我正在制作一个通过数组显示细胞生长的程序。我已经实现了当我按下“开始”按钮时,数组每10秒更新一次,在while(true){}循环中。问题在于,我想能够通过按下“暂停”按钮来停止循环,但在循环中,它不会让我使用任何控件。我需要除了无限循环以外的其他东西来刷新帧。
我有点新手,但我目前正在上Java课程,所以我对这种语言有一些了解。
我有点新手,但我目前正在上Java课程,所以我对这种语言有一些了解。
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;
}
}
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();
}
然后在您的“暂停/恢复”按钮中调用这些“暂停/开始绘画”方法:
if( e.getActionCommand().equals("Pause")){
growPanel.pause();
setText("Resume");
} else {
growPanel.startPaiting();
setText("Pause");
}
这是完整的源代码,以便查看其运行情况:
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;
}
}
}
我个人更喜欢使用 Timer
类 而不是 Thread
或者 Thread.sleep()
。定时器类可以同时处理周期性运行代码和取消执行。
你的代码应该像这样:
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();
你想在一个线程中运行你的模拟(查找Runnable接口)。 然后你可以向这个线程传递消息来暂停、继续和停止。
没错。看起来你是在事件分派线程上进行绘图。由于你从上一次调用中没有返回控制权,所以事件(例如按钮按下)永远没有机会被调用...
看一下wait() / notify()机制。简单来说,一个线程可以等待10秒钟,但仍然可以被通知外部事件已经发生。