以下swt程序用多线程实现简单的画线功能,可是在释放GC时会抛出异常不知为何,GC对象应该在何时释放?
import java.awt.Dimension;
import java.awt.Toolkit;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;public class Homework8 
{
//主方法
public static void main(String[] args)
{
MainShell shell=new MainShell();
}
}
class MainShell
{
//控件及常量声明
private Toolkit tk=Toolkit.getDefaultToolkit();
private Dimension d=tk.getScreenSize();
private Display display;
private Shell shell;
private Canvas c1,c2;
private Button startButton1,startButton2,stopButton1,stopButton2,clearButton;
private boolean stop1,stop2;
//构造器,用以初始化个面板
public MainShell()
{
//初始化主面板及display对象
display=Display.getDefault();
shell=new Shell(display,SWT.BORDER|SWT.MIN|SWT.CLOSE|SWT.TITLE);
shell.setText("Draw Line Shell");
shell.setBounds((int)(d.getWidth()-600)/2,(int)(d.getHeight()-400)/2,600, 400);
//初始化画布
c1=new Canvas(shell,SWT.BORDER);
c1.setBounds(50,20,200,200);
c1.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
c2=new Canvas(shell,SWT.BORDER);
c2.setBounds(350,20,200,200);
c2.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
//初始化按钮
clearButton=new Button(shell,SWT.NONE);
clearButton.setBounds(250,250,100,40);
clearButton.setText("clear");
startButton1=new Button(shell,SWT.NONE);
startButton1.setBounds(60,320,70,30);
startButton1.setText("start");
startButton1.setToolTipText("多次单击可加速画线!");
stopButton1=new Button(shell,SWT.NONE);
stopButton1.setBounds(170,320,70,30);
stopButton1.setText("stop");
startButton2=new Button(shell,SWT.NONE);
    startButton2.setBounds(360,320,70,30);
    startButton2.setText("start");
    startButton2.setToolTipText("多次单击可加速画线!");
stopButton2=new Button(shell,SWT.NONE);
stopButton2.setBounds(470,320,70,30);
stopButton2.setText("stop");
//事件处理:
//startButton1事件处理
startButton1.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
stop1=false;
new Thread(new drawLineThread1()).start();
}
});
//startButton2事件处理
startButton2.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
stop2=false;
new Thread(new drawLineThread2()).start();
}
});
//stopButton1事件处理
stopButton1.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
stop1=true;
}
});
//stopButton2事件处理
stopButton2.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
stop2=true;
}
});
//clearButton事件处理
clearButton.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
GC gc1=new GC(c1);
GC gc2=new GC(c2);
gc1.fillRectangle(0,0,c1.getSize().x,c1.getSize().y);
gc2.fillRectangle(0,0,c2.getSize().x,c2.getSize().y);
                                     gc1.dispose();
                                     gc2.dispose();
}
});
//显示面板
shell.open();
while(!shell.isDisposed())
{
if(!display.readAndDispatch())
display.sleep();
}
      //关闭面板后结束所有线程
stop1=true;
stop2=true;
                  display.dispose();
}
//自定义线程1,实现在左边窗口画线
class drawLineThread1 implements Runnable
{
GC gc=new GC(c1);
public void run() 
{
while(!stop1)
{
randomDraw(gc);
try 
{
Thread.sleep(200);

catch (InterruptedException e) 
{

}
}
gc.dispose();
}
}
// 自定义线程2,实现在右边窗口画线
class drawLineThread2 implements Runnable
{
GC gc=new GC(c2);
public void run() 
{
while(!stop2)
{
randomDraw(gc);
try
{
Thread.sleep(200);
}
catch(InterruptedException e)
{

}
}
gc.dispose();
}
}
//自定义方法,实现随机画线,颜色也随机
private void randomDraw(GC gc)
{
RGB rgb=new RGB((int)(Math.random()*255),(int)(Math.random()*255),(int)(Math.random()*255));
Color color=new Color(display,rgb);
gc.setForeground(color);
gc.drawLine((int)(Math.random()*200),(int)(Math.random()*200),(int)(Math.random()*200),(int)(Math.random()*200));
}
}

解决方案 »

  1.   

    Java提供的GC功能可以自动监测对象是否超过作用域从而达到自动回收内存的目的,Java语言没有提供释放已分配内存的显示操作方法。
      

  2.   

    我说的GC是指swt的画图工具,不是垃圾处理器。
      

  3.   

    这个是线程访问的问题,不能在非UI线程中改变UI,给个简单修改的代码:class drawLineThread2 implements Runnable {
            GC gc = new GC(c2);        public void run() {
                while (!stop2) {
                    randomDraw(gc);
                    try {
                        Thread.sleep(200);
                    } catch (InterruptedException e) {                }
                }
                Display.getDefault().asyncExec(new Runnable() {
                    public void run() {
                        gc.dispose();
                    }                
                });
            }
        }