0 0

swt 界面假死 使用asyncExec(runnable),没出现多线程的效果10

我现在做网络抓取数据包后再还原成html的一个实验,使用swt实现界面,点击开始按钮开始抓包,点击停止按钮停止抓包,想法是抓取到一个数据包就在表格显示,也就是动态刷新界面,当抓取的数据包上千上万的时候界面就假死了,要停止抓包根本停止不了,有时候只有点击鼠标界面就出现无法响应的情况。整个界面代码如下,现在做一个小实验,点击开始按钮,表格创建1000行,第一列为名称,第二列为进度条。但是我想在1000行生成之前停止,但是1000行没生成完之前stop根本不好使,在1000行生成完之后点stop才能停止进度条。哪位大侠,帮忙修改一下吧

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ProgressBar;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;

public class MutiTaskGUI {

    private Shell shell = null;

    private Table table = null;

    public MutiTaskGUI( ){

        //构造方法中调用初始化窗口的方法

        init();

    }

    //初始化窗口方法

    public void init() {

        shell = new Shell();
        shell.setSize(282, 240);    
        shell.setLayout(new GridLayout());

        shell.setText("多线程");

        Button bt = new Button ( shell , SWT.NONE);

        bt.setText("开始一个任务");
        //停止线程
        Button stop = new Button(shell, SWT.NONE);
        stop.setText("stop");
        table = new Table(shell, SWT.BORDER);

        table.setLayoutData( new GridData(SWT.FILL,SWT.FILL,true,true));

        table.setHeaderVisible(true);

        table.setLinesVisible(true);
     

        String[] header = new String[]{"任务","进度","操作"};

        // 创建表头

        for (int i = 0; i < 3; i++) {

            TableColumn col = new TableColumn(table, SWT.NONE);

            col.setText( header[i] );

        }

        //设置表头宽度

        table.getColumn(0).setWidth(80);

        table.getColumn(1).setWidth(150);

        table.getColumn(2).setWidth(80);

        shell.pack();

        //注册创建任务按钮事件

        bt.addSelectionListener( new SelectionAdapter(){

            //当单击创建一个任务按钮时

            public void widgetSelected(SelectionEvent e) {

                //首先创建一个Task对象
            	for(int i = 0 ; i < 1000; i++){
            		Task task = new Task();
                //然后在表格中添加一行            		
                task.createTableItem(table);
                //最后启动该任务,该任务为一个线程
                task.start();
            	}
            }
        });
        stop.addSelectionListener(new SelectionAdapter() {
    		@Override
			public void widgetSelected(SelectionEvent arg0) {
				// TODO Auto-generated method stub
				Task.setDone(true);
			}

		});
			
	

    }

    //获得和设置属性的getter和setter方法

    public Shell getShell() {

        return shell;

    }

    public void setShell(Shell shell) {

        this.shell = shell;

    }

    public Table getTable() {

        return table;

    }

    public void setTable(Table table) {

        this.table = table;

    }
    public static void main(String[] args) {

        Display display = Display.getDefault();

        MutiTaskGUI mutiTask= new MutiTaskGUI();

        mutiTask.getShell().open();

        while (!mutiTask.getShell().isDisposed()) {

            if (!display.readAndDispatch()) {

                display.sleep();

            }

        }


    }
}

class Task extends Thread {

    //该类的一些属性

    private Table table = null;

    //是否停止的标志

    public static boolean done = false;

    //声明进度条对象

    private ProgressBar bar = null;

    private int min = 0;

    private int max = 100;
    int i = 0;

    //创建表格中的一行

    public void createTableItem(Table table) {
    	done = false;
        TableItem item = new TableItem(table, SWT.NONE);
      item.setText(this.getName());
      //  item.setText(new String[]{k +"",i+2+""});

        // 创建一个进度条

        bar = new ProgressBar(table, SWT.NONE);

        bar.setMinimum(min);

        bar.setMaximum(max);

        // 创建一个可编辑的表格对象

       TableEditor editor = new TableEditor(table);

        editor.grabHorizontal = true;

        editor.grabVertical = true;

        // 将进度条绑定到第二列中
       editor.setEditor(bar, item, 1);

    }

    //线程方法体,与前面单个的进度条的程序类似

    public void run() {

        for (int i = min; i < max; i++) {

            if (isDone()) {

                break;

            }
            try {

                Thread.sleep(100);

            } catch (InterruptedException e) {

                e.printStackTrace();

            }
            Display.getDefault().asyncExec(new Runnable(){
          //  table.getDisplay().asyncExec(new Runnable() {
            	
                public void run() {

                    if (bar.isDisposed())

                        return;

                    bar.setSelection(bar.getSelection() + 1);

                }

            });

            //如果停止,则结束该线程


        }

    }

    public boolean isDone() {

        return done;

    }

    public static void setDone(boolean done) {

        Task.done = done;

    }

}



 

2010年10月13日 19:05

1个答案 按时间排序 按投票排序

0 0

采纳的答案

1,对于长时间的任务,不应该在图像线程中完成,如这里的增加1000项表项。应该另起一个线程,然后让图形线程来调度。

public class MutiTaskGUI {
	private Shell shell = null;   
	private Table table = null;  
	private addItem t;

	public MutiTaskGUI( ){   
		init();   
	}   

	//初始化窗口方法   
	public void init() {
		shell = new Shell();   
		shell.setSize(282, 240);       
		shell.setLayout(new GridLayout());
		Button bt = new Button ( shell , SWT.NONE);   
		bt.setText("开始一个任务");   
		//停止线程   
		Button stop = new Button(shell, SWT.NONE);   
		stop.setText("stop");   
		table = new Table(shell, SWT.BORDER);   
		table.setLayoutData( new GridData(SWT.FILL,SWT.FILL,true,true));   
		table.setHeaderVisible(true);   
		table.setLinesVisible(true);   
		String[] header = new String[]{"任务","进度","操作"};   
		// 创建表头   
		for (int i = 0; i < 3; i++) {
			TableColumn col = new TableColumn(table, SWT.NONE);   
			col.setText( header[i] );
		}

		//设置表头宽度   
		table.getColumn(0).setWidth(80);
		table.getColumn(1).setWidth(150);
		table.getColumn(2).setWidth(80);  
//		shell.pack();

		//注册创建任务按钮事件   
		bt.addSelectionListener( new SelectionAdapter(){   
			//当单击创建一个任务按钮时   
			public void widgetSelected(SelectionEvent e) {
				t = new addItem(table);
				t.start();
				
				/*
				//首先创建一个Task对象   
				for(int i = 0 ; i < 1000; i++) {
					Task task = new Task();
					//然后在表格中添加一行                       
					task.createTableItem(table);   
					//最后启动该任务,该任务为一个线程   
					task.start();
				}*/
			}
		});   
		stop.addSelectionListener(new SelectionAdapter() {   
			public void widgetSelected(SelectionEvent arg0) {   
				t.setDone(true);  
			}
		});   
	}   

	public Shell getShell() {return shell;}   

	public static void main(String[] args) {
		Display display = Display.getDefault();   
		MutiTaskGUI mutiTask= new MutiTaskGUI();   
		mutiTask.getShell().open();
		
		while (!mutiTask.getShell().isDisposed()) {   
			if (!display.readAndDispatch()) {   
				display.sleep();   
			}
		}
	}   
}   

class addItem extends Thread {
	private Table table;
	public boolean done = false; 
	public addItem(Table table) {
		this.table = table;
	}
	
	public void run() {
		//首先创建一个Task对象   
		for(int i = 0 ; i < 1000; i++) {
			//然后在表格中添加一行 
			try {Thread.sleep(100);	} catch (InterruptedException e) {e.printStackTrace();}   
			if(isDone()) break;
			Display.getDefault().asyncExec(new Runnable() {
				public void run() {
					Task task = new Task();
					task.createTableItem(table);   
					task.start();
				}
			});
			//最后启动该任务,该任务为一个线程   
		}
	}
	public boolean isDone() {return done;}
	public void setDone(boolean done) { 
		this.done = done;   
	}
}

class Task extends Thread {
	//是否停止的标志   
	public static boolean done = false;   

	//声明进度条对象   
	private ProgressBar bar = null;   
	private int min = 0;   
	private int max = 100;   
	int i = 0;   

	//创建表格中的一行   
	public void createTableItem(Table table) {
//		done = false;   
		TableItem item = new TableItem(table, SWT.NONE);   
		item.setText(this.getName());   
		// 创建一个进度条   
		bar = new ProgressBar(table, SWT.NONE);   
		bar.setMinimum(min);   
		bar.setMaximum(max);   
		// 创建一个可编辑的表格对象   
		TableEditor editor = new TableEditor(table);   
		editor.grabHorizontal = true;   
		editor.grabVertical = true;   
		// 将进度条绑定到第二列中   
		editor.setEditor(bar, item, 1);
	}

	//线程方法体,与前面单个的进度条的程序类似   
	public void run() {
		for (int i = min; i < max; i++) {
			if (isDone()) {break;}   
			try {Thread.sleep(100);	} catch (InterruptedException e) {e.printStackTrace();}   
			Display.getDefault().asyncExec(new Runnable(){   
				//  table.getDisplay().asyncExec(new Runnable() {   
				public void run() {   
					if (bar.isDisposed())
						return;   
					bar.setSelection(bar.getSelection() + 1);   
				}
			});   
			//如果停止,则结束该线程   
		}   
	}   

	public boolean isDone() {
		return done;
	}

	public static void setDone(boolean done) { 
		Task.done = done;   
	}

}


改了一下你的例子,你看看,改了一些你的格式,不要介意啊。
希望 对你有帮助。

2010年10月14日 17:02

相关推荐

    swt 多线程

    本文将深入探讨SWT中多线程的使用,特别是与UI交互相关的多线程原理。 首先,我们需要理解UI线程,也称为事件调度线程或AWT/SWT线程,它负责处理所有的用户界面更新和事件处理。在SWT中,所有的GUI操作必须在UI线程...

    SWT并发例子(后台耗时线程)

    在SWT中,我们可以使用`Display.asyncExec`或`Display.syncExec`方法来在事件调度线程中执行代码,而使用`new Thread()`来创建并启动新的后台线程来执行耗时任务。以下是一个基本的示例: ```java Button button = ...

    swt线程冲突与解决

    在使用SWT(Standard Widget Toolkit)进行图形界面开发时,开发者往往会遇到一个常见的问题——线程冲突。由于SWT组件的设计原则是基于单线程模型,即所有的UI操作必须在UI主线程中执行,因此在多线程环境下容易...

    java SWT编写的截图程序

    7. **异步执行:** 图像处理可能会消耗一定时间,因此通常在后台线程(通过`Display.asyncExec()`或`Display.syncExec()`)执行,以避免阻塞UI。 **SWT截图程序的优势:** 1. **原生体验:** SWT直接调用操作系统...

    swt源码以及jar

    在多线程方面,SWT提供了一个安全的线程模型,确保所有的UI更新都在主线程(通常称为UI线程或Event Dispatch Thread)中执行。这避免了因多线程操作界面导致的竞态条件和死锁问题。开发者可以通过`Display.syncExec...

    swt

    通常,使用Display.asyncExec()和Display.syncExec()方法来确保在正确的线程(即UI线程)中更新界面元素,防止出现线程安全问题。 **学习资源:** 博文链接提到的是一个关于SWT的博客文章,可能包含一些实用的示例...

    基于swt的小软件

    例如,使用`Display.asyncExec`或`Display.syncExec`方法在GUI线程中更新界面,确保界面操作的线程安全。 **Bank子文件** 在"Bank"这个子文件中,很可能是实现了一款与银行相关的模拟软件,可能包括账户管理、交易...

    SWT综合教程及安装指导

    SWT(Standard Widget Toolkit)是Java编程环境中用于创建图形用户界面(GUI)的一种开源库,它是Eclipse项目的一部分。SWT提供了与操作系统底层更紧密的交互,使得开发出的程序性能更优,外观与操作系统的原生应用...

    SWT API 资料

    在SWT中,UI操作应始终在主线程(也称为AWT/SWT线程)上执行,以避免界面卡死。为了实现异步处理,可以使用`Display.asyncExec`和`Display.syncExec`方法,它们能够在正确的线程上下文中执行回调。 ### 9. 高级特性...

    SWT应用的开发实例:没有使用到OSGi

    SWT(Standard Widget Toolkit)是Java中用于构建图形用户界面(GUI)的一种库,它是Eclipse项目的一部分。与Java Swing不同,SWT直接利用操作系统提供的原生控件,因此可以提供更好的性能和与操作系统的集成。这篇...

    Graphics Moving Package

    7. **动画框架**:虽然SWT没有内置的动画框架,但开发者可以自定义实现,例如通过使用`Display.syncExec`或`Display.asyncExec`来在 SWT 线程中更新图形状态,实现平滑的动画效果。 8. **布局管理**:SWT 提供了...

    Eclipse插件开发问题

    PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { window....

    使用Eclipse RCP进行桌面程序开发

    ### 使用Eclipse RCP进行桌面程序开发:详细指南 #### 一、Eclipse RCP简介与快速起步 **Eclipse RCP** (Rich Client Platform) 是一种基于Java的开源框架,用于开发桌面应用程序。自从Eclipse 3.0版本以来,RCP...

    一个eclipse的helloworld的插件

    在`run()`方法中,我们可以调用`Display.getDefault().asyncExec()`来确保UI更新在Eclipse的主线程中执行,然后弹出一个对话框显示"Hello World"。 4. **注册动作** 将`HelloWorldAction`类与`plugin.xml`关联,...

Global site tag (gtag.js) - Google Analytics