我用的是swing,不过跟这个没有关系。你自己的线程需要这样: public class ThreadTimer extends Thread { public final int STATE_STOPPED = 0; public final int STATE_RUNNING = 1; public final int STATE_WAITTING = 2; private int timerState = STATE_STOPPED; private boolean bRunning = false;
public void run(){ bRunning = true; while(bRunning){
setTimerState(STATE_RUNNING); yield();
doSomething();
setTimerState(STATE_WAITTING); try{ sleep(N * 1000); } catch(Exception e){ e.printStackTrace(); } } } /** * @param timerState 要设置的 timerState。 */ public void setTimerState(int timerState) { this.timerState = timerState; } //查询当前运行状态 public int getTimerState(){ return this.timerState; } public void doSomething(){} }
SWING里面有个ACTION的嘛,可以实现你说的
写了个简单的例子,用的AWT,你要的应该是这样吧。 import java.awt.*; import java.awt.event.*; class Run extends Thread { Button button; public Run(Button button) { this.button = button; } public void run() { button.setName("running..."); boolean flag = true; while(flag) { //做其它事情; try {Thread.sleep(5000);} catch(Exception e) {} flag = false; } button.setName("run over."); button.setEnabled(true); } } class test3 extends Frame { Button button = new Button("click"); public test3() { button.setBounds(150,100,100,30); button.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { button.setEnabled(false); new Run(button).start(); } }); this.setLayout(null); this.add(button); } public static void main(String [] args) { test3 frame = new test3(); frame.addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.setSize(400,300); frame.setVisible(true); } }
谢谢楼上的几位 pdvv(我爱花猫)和lh8748(LH)的方法我都试过了,swing和awt都是没问题的,但是swt在另一个线程里操作控件的时候会抛异常: org.eclipse.swt.SWTException: Invalid thread access at org.eclipse.swt.SWT.error(SWT.java:2691) at org.eclipse.swt.SWT.error(SWT.java:2616) at org.eclipse.swt.SWT.error(SWT.java:2587) at org.eclipse.swt.widgets.Widget.error(Widget.java:381) at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:284) at org.eclipse.swt.widgets.Button.setText(Button.java:602) at test.Run.run(Run.java:16)我把lh8748(LH)的代码改成SWT的运行就是上面的结果,当然,原本awt的环境是没问题的 修改后的代码如下: import org.eclipse.swt.events.SelectionEvent; import org.eclipse.swt.events.SelectionListener; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell;class test3 { public test3() { Display display = new Display(); Shell shell = new Shell(display); shell.setLocation(250, 100); final Button button = new Button(shell, 0); button.setBounds(150, 100, 100, 30); button.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e) { new Run(button).start(); button.setEnabled(false); } public void widgetDefaultSelected(SelectionEvent e) { // TODO Auto-generated method stub } }); shell.pack(); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); System.exit(0); } public static void main(String[] args) { test3 frame = new test3(); } }import org.eclipse.swt.widgets.Button;class Run extends Thread { Button button; public Run(Button button) { this.button = button; } public void run() { button.setText("running..."); boolean flag = true; while (flag) { //做其它事情; try { Thread.sleep(5000); } catch (Exception e) { } flag = false; } button.setText("run over."); button.setEnabled(true); } }
楼主,俺又转回来了,我今天刚开始学习使用SWT(不好意思),有点感觉,联想到你的问题,可能对你有帮助。java语言本身支持多线程,虽然很好但是不利于GUI编程,因为它不能保证图形控件操作的同步。但是在SWT中,采用的是一种简化,通常只允许唯一一个“用户线程”对图形控件进行操作。其他线程中如果调用,就会抛出org.eclipse.swt.SWTException。如果非要这么作,在包org.eclipse.swt.widget.Display中提供方法syncExec(Runnable)、asyncExec(Runnable)方法。所以,你的程序稍作修改就可以了: public void widgetSelected(SelectionEvent e) { Display.getCurrent().syncExec(new Run(button));
private Thread 你的线程; private void initialize() {
创建控件
按钮1
……
启动检测线程();
} //单击按钮后启动你的线程
启动检测线程(){
class RedrawThread extends Thread{
public void run(){
if(别的线程.状态 == null){
设置“按钮1”状态
}
else if(别的线程.状态 == "运行"){
……
}
}
RedrawThread redraw = new RedrawThread();
redraw.start();
}
}你自己写的那个线程必须定义几种状态。
public class ThreadTimer extends Thread {
public final int STATE_STOPPED = 0;
public final int STATE_RUNNING = 1;
public final int STATE_WAITTING = 2;
private int timerState = STATE_STOPPED; private boolean bRunning = false;
public void run(){
bRunning = true;
while(bRunning){
setTimerState(STATE_RUNNING);
yield();
doSomething();
setTimerState(STATE_WAITTING);
try{
sleep(N * 1000);
}
catch(Exception e){
e.printStackTrace();
}
}
} /**
* @param timerState 要设置的 timerState。
*/
public void setTimerState(int timerState) {
this.timerState = timerState;
} //查询当前运行状态
public int getTimerState(){
return this.timerState;
} public void doSomething(){}
}
import java.awt.*;
import java.awt.event.*;
class Run extends Thread
{
Button button;
public Run(Button button)
{
this.button = button;
}
public void run()
{
button.setName("running...");
boolean flag = true;
while(flag)
{ //做其它事情;
try
{Thread.sleep(5000);}
catch(Exception e) {}
flag = false;
}
button.setName("run over.");
button.setEnabled(true);
}
}
class test3 extends Frame
{
Button button = new Button("click");
public test3()
{
button.setBounds(150,100,100,30);
button.addActionListener(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
button.setEnabled(false);
new Run(button).start();
}
});
this.setLayout(null);
this.add(button);
}
public static void main(String [] args)
{
test3 frame = new test3();
frame.addWindowListener(
new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
frame.setSize(400,300);
frame.setVisible(true);
}
}
pdvv(我爱花猫)和lh8748(LH)的方法我都试过了,swing和awt都是没问题的,但是swt在另一个线程里操作控件的时候会抛异常:
org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:2691)
at org.eclipse.swt.SWT.error(SWT.java:2616)
at org.eclipse.swt.SWT.error(SWT.java:2587)
at org.eclipse.swt.widgets.Widget.error(Widget.java:381)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:284)
at org.eclipse.swt.widgets.Button.setText(Button.java:602)
at test.Run.run(Run.java:16)我把lh8748(LH)的代码改成SWT的运行就是上面的结果,当然,原本awt的环境是没问题的
修改后的代码如下:
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;class test3
{ public test3()
{ Display display = new Display();
Shell shell = new Shell(display);
shell.setLocation(250, 100); final Button button = new Button(shell, 0);
button.setBounds(150, 100, 100, 30);
button.addSelectionListener(new SelectionListener() { public void widgetSelected(SelectionEvent e)
{
new Run(button).start();
button.setEnabled(false);
} public void widgetDefaultSelected(SelectionEvent e)
{
// TODO Auto-generated method stub } }); shell.pack();
shell.open(); while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
System.exit(0);
} public static void main(String[] args)
{ test3 frame = new test3(); }
}import org.eclipse.swt.widgets.Button;class Run extends Thread
{
Button button; public Run(Button button)
{
this.button = button;
} public void run()
{
button.setText("running...");
boolean flag = true;
while (flag)
{ //做其它事情;
try
{
Thread.sleep(5000);
}
catch (Exception e)
{
}
flag = false;
}
button.setText("run over.");
button.setEnabled(true);
}
}
{
Display.getCurrent().syncExec(new Run(button));
//button.setEnabled(false);我把这句放到了Run.run()中了,为了和button.setEnabled(true);对应
新学SWT,有不懂之处请多指教。
}
org.eclipse.swt.SWTException: Invalid thread access
at org.eclipse.swt.SWT.error(SWT.java:2691)
at org.eclipse.swt.SWT.error(SWT.java:2616)
at org.eclipse.swt.SWT.error(SWT.java:2587)
at org.eclipse.swt.widgets.Widget.error(Widget.java:381)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:284)
at org.eclipse.swt.widgets.Button.setText(Button.java:602)
at test.Run.run(Run.java:16)
我觉得这个应该是线程异常,现在问题解决了,理解不太深,好像是这样的:SWT里对控件的管理只能由一个主线程来完成,任何其他线程试图修改控件都会抛出上面这个异常。解决方法就是让其他线程完成工作是,给主线程发一个消息,还是由主线程来完成控件的修改工作。//主线程
public class MainWindow { public Outputer out = null;
Object o = new Object();
....
....
....
Button bRun = new Button(shell,SWT.NONE);
registerCallback(bRun, SWT.Selection, this, "doRun");
....
....
....
public void doRun(Event event) { bRun.setEnabled(false);
// start a new thread to wait
new Thread(new Runnable() {
public void run() {
try {
synchronized (o) {
o.wait();
}
} catch (InterruptedException ex) {
ex.printStackTrace();
}
display.asyncExec(new Runnable() {
public void run() {
bRun.setEnabled(true);
}
});
}
}).start(); // start outputer processor
new Outputer(o);
}
}
public class Outputer extends Thread
{
String COMMAND = null;
String line;
Process p = null;
Object o = null; public Outputer(Object o)
{
this.o = o;
start();
} public void run()
{
//你要作的事情
SomethingYouWantToDo(); synchronized (o)
{
o.notify();
}
}
}不知道说清楚没有,反正运行结果是满足我的需求的。