以下程序运行后产生一个红色的小球在窗口来回弹,如在小球结束运动之前关闭窗口(shell)则产生:
Exception in thread "main" org.eclipse.swt.SWTException: Widget is disposed
at org.eclipse.swt.SWT.error(SWT.java:2942)
at org.eclipse.swt.SWT.error(SWT.java:2865)
at org.eclipse.swt.SWT.error(SWT.java:2836)
at org.eclipse.swt.widgets.Widget.error(Widget.java:395)
at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:297)
at org.eclipse.swt.widgets.Control.internal_new_GC(Control.java:1104)
at org.eclipse.swt.graphics.GC.<init>(GC.java:132)
at org.eclipse.swt.graphics.GC.<init>(GC.java:99)
at ballThread.clean(BounceBall.java:115)
at ballThread$2.run(BounceBall.java:135)
at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35)
at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:123)
at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3057)
at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:2716)
at org.eclipse.swt.widgets.Display.release(Display.java:2765)
at org.eclipse.swt.graphics.Device.dispose(Device.java:261)
at BounceBall.main(BounceBall.java:58)
原因应该是仍然在使用对象时将该对象清除了导致异常的产生,应该怎样改动程序呢??思考中.........
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.graphics.Color;
public class BounceBall {
private Shell sShell = null; // @jve:decl-index=0:visual-constraint="10,10"
private Canvas canvas = null;
private Button startButton = null;
ballThread bt = null;
Display display = null;
public BounceBall() {
super();
// TODO Auto-generated constructor stub
// bt = new ballThread(canvas);
display = Display.getDefault();
}
/**
* This method initializes canvas
*
*/
private void createCanvas() {
canvas = new Canvas(sShell, SWT.NONE);
canvas.setBackground(new Color(Display.getCurrent(), 0, 0, 255));
canvas.setBounds(new org.eclipse.swt.graphics.Rectangle(26,14,527,242));
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
/* Before this is run, be sure to set up the launch configuration (Arguments->VM Arguments)
* for the correct SWT library path in order to run with the SWT dlls.
* The dlls are located in the SWT plugin jar.
* For example, on Windows the Eclipse SWT 3.1 plugin jar is:
* installation_directory\plugins\org.eclipse.swt.win32_3.1.0.jar
*/
// Display display = Display.getDefault();
BounceBall thisClass = new BounceBall();
thisClass.createSShell();
thisClass.sShell.open();
while (!thisClass.sShell.isDisposed()) {
if (!thisClass.display.readAndDispatch())
thisClass.display.sleep();
}
thisClass.display.dispose();
}
/**
* This method initializes sShell
*/
private void createSShell() {
sShell = new Shell();
sShell.setText("Shell");
createCanvas();
sShell.setSize(new org.eclipse.swt.graphics.Point(588,367));
startButton = new Button(sShell, SWT.NONE);
startButton.setBounds(new org.eclipse.swt.graphics.Rectangle(87,284,76,33));
startButton.setText("Start");
startButton.addSelectionListener(new org.eclipse.swt.events.SelectionAdapter() {
public void widgetSelected(org.eclipse.swt.events.SelectionEvent e) {
//System.out.println("widgetSelected()"); // TODO Auto-generated Event stub widgetSelected()
new ballThread(40,40,canvas).start();
}
});
}
}
class ballThread extends Thread {
int x, y, xsize, ysize, addx, addy;
Rectangle rc = null;
GC gc = null;
Canvas c = null;
Color red = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
public ballThread(int x,int y,Canvas ca) {
c = ca;
this.x = x;
this.y = y;
xsize = 10;
ysize = 10;
addx = 1;
addy = 2;
rc = c.getBounds();
}
public void draw(int x, int y, int xsize, int ysize) {
gc = new GC(c);
gc.drawOval(x, y, xsize, ysize);
gc.setBackground(red);
gc.fillOval(x, y, xsize, ysize);
gc.dispose();
}
public void clean() {
gc = new GC(c);
// Rectangle rt = canvas.getBounds();
gc.drawRectangle(rc.x - 100, rc.y - 100, rc.width + 100,
rc.height + 100);
gc.fillRectangle(rc.x - 100, rc.y - 100, rc.width + 100,
rc.height + 100);
gc.dispose();
}
public void run() {
for (int i = 1; i < 1500; i++) {
try{
Display.getDefault().asyncExec(new Thread () {
public void run(){
draw(x, y, xsize, ysize);}});
Thread.sleep(10);
Display.getDefault().asyncExec(new Thread () {
public void run(){
clean();}});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (rc.contains(x, y)) {
x += addx;
y += addy;
} else {
if (x >= rc.width || x <= 26) {
addx = -addx;
x += addx;
y += addy;
} else if (y >= rc.height || y <= 14) {
addy = -addy;
x += addx;
y += addy;
}
}
}
}
}
想到一个办法能够去除那些exceptions,就是在display.dispose()前加一句Thread.currentThread().stop();强制终止线程,不过这个办法肯定是最垃圾的办法.......