-
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个答案 按时间排序 按投票排序
-
采纳的答案
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中多线程的使用,特别是与UI交互相关的多线程原理。 首先,我们需要理解UI线程,也称为事件调度线程或AWT/SWT线程,它负责处理所有的用户界面更新和事件处理。在SWT中,所有的GUI操作必须在UI线程...
在SWT中,我们可以使用`Display.asyncExec`或`Display.syncExec`方法来在事件调度线程中执行代码,而使用`new Thread()`来创建并启动新的后台线程来执行耗时任务。以下是一个基本的示例: ```java Button button = ...
在使用SWT(Standard Widget Toolkit)进行图形界面开发时,开发者往往会遇到一个常见的问题——线程冲突。由于SWT组件的设计原则是基于单线程模型,即所有的UI操作必须在UI主线程中执行,因此在多线程环境下容易...
7. **异步执行:** 图像处理可能会消耗一定时间,因此通常在后台线程(通过`Display.asyncExec()`或`Display.syncExec()`)执行,以避免阻塞UI。 **SWT截图程序的优势:** 1. **原生体验:** SWT直接调用操作系统...
在多线程方面,SWT提供了一个安全的线程模型,确保所有的UI更新都在主线程(通常称为UI线程或Event Dispatch Thread)中执行。这避免了因多线程操作界面导致的竞态条件和死锁问题。开发者可以通过`Display.syncExec...
通常,使用Display.asyncExec()和Display.syncExec()方法来确保在正确的线程(即UI线程)中更新界面元素,防止出现线程安全问题。 **学习资源:** 博文链接提到的是一个关于SWT的博客文章,可能包含一些实用的示例...
例如,使用`Display.asyncExec`或`Display.syncExec`方法在GUI线程中更新界面,确保界面操作的线程安全。 **Bank子文件** 在"Bank"这个子文件中,很可能是实现了一款与银行相关的模拟软件,可能包括账户管理、交易...
SWT(Standard Widget Toolkit)是Java编程环境中用于创建图形用户界面(GUI)的一种开源库,它是Eclipse项目的一部分。SWT提供了与操作系统底层更紧密的交互,使得开发出的程序性能更优,外观与操作系统的原生应用...
在SWT中,UI操作应始终在主线程(也称为AWT/SWT线程)上执行,以避免界面卡死。为了实现异步处理,可以使用`Display.asyncExec`和`Display.syncExec`方法,它们能够在正确的线程上下文中执行回调。 ### 9. 高级特性...
SWT(Standard Widget Toolkit)是Java中用于构建图形用户界面(GUI)的一种库,它是Eclipse项目的一部分。与Java Swing不同,SWT直接利用操作系统提供的原生控件,因此可以提供更好的性能和与操作系统的集成。这篇...
7. **动画框架**:虽然SWT没有内置的动画框架,但开发者可以自定义实现,例如通过使用`Display.syncExec`或`Display.asyncExec`来在 SWT 线程中更新图形状态,实现平滑的动画效果。 8. **布局管理**:SWT 提供了...
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { window....
### 使用Eclipse RCP进行桌面程序开发:详细指南 #### 一、Eclipse RCP简介与快速起步 **Eclipse RCP** (Rich Client Platform) 是一种基于Java的开源框架,用于开发桌面应用程序。自从Eclipse 3.0版本以来,RCP...
在`run()`方法中,我们可以调用`Display.getDefault().asyncExec()`来确保UI更新在Eclipse的主线程中执行,然后弹出一个对话框显示"Hello World"。 4. **注册动作** 将`HelloWorldAction`类与`plugin.xml`关联,...