求助 SWT界面线程问题

Typhoon19890815 2009-12-16 09:39:11
在一个登录界面中设置了注册按钮,想在点击注册按钮的同时弹出一个新的注册页面,可是出现了线程的错误:
Exception in thread "main" org.eclipse.swt.SWTException: Invalid thread access
求高手解答,感谢!

这个是登录界面中注册按钮的设置:

Button registerButton = new Button(buttonComp,SWT.NONE|SWT.CENTER); //注册按钮
registerButton.setText(" 注册 ");
registerButton.addSelectionListener(new SelectionAdapter(){
public void widgetSelected(SelectionEvent e)
{
new newUser();
}
});

这个是新的注册界面的代码:
package cn.chenxiang.Interface;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class newUser
{
public newUser()
{
Display display = new Display();
FillLayout fillLayout = new FillLayout();
Shell shell = new Shell(SWT.CLOSE|SWT.MIN|SWT.TITLE);
shell.setText("期刊管理系统");
shell.setBounds(200,250,300,210);
shell.setLayout(fillLayout);

Composite comp = new Composite(shell,SWT.NONE);
GridLayout gridLayout = new GridLayout(2,false);
gridLayout.verticalSpacing = 10 ;
gridLayout.marginTop = 5 ;
gridLayout.marginRight = 10 ;
comp.setLayout(gridLayout);
comp.setToolTipText("读者信息注册");

GridData gridData = new GridData(GridData.FILL_HORIZONTAL);
gridData.grabExcessHorizontalSpace = true ;

GridData gridDataT = new GridData(GridData.FILL_HORIZONTAL);

Label label1 = new Label(comp,SWT.NONE|SWT.CENTER);
label1.setText("读者姓名:");
label1.setLayoutData(gridData);
Text text1 = new Text(comp,SWT.NONE|SWT.BORDER);
text1.setLayoutData(gridDataT);
Label label2 = new Label(comp,SWT.NONE|SWT.CENTER);
label2.setText("年龄:");
label2.setLayoutData(gridData);
Text text2 = new Text(comp,SWT.NONE|SWT.BORDER);
text2.setLayoutData(gridDataT);
Label label3 = new Label(comp,SWT.NONE|SWT.CENTER);
label3.setText("性别:");
label3.setLayoutData(gridData);
Text text3 = new Text(comp,SWT.NONE|SWT.BORDER);
text3.setLayoutData(gridDataT);
Label label4 = new Label(comp,SWT.NONE|SWT.CENTER);
label4.setText("TEL:");
label4.setLayoutData(gridData);
Text text4 = new Text(comp,SWT.NONE|SWT.BORDER);
text4.setLayoutData(gridDataT);
Label label5 = new Label(comp,SWT.NONE|SWT.CENTER);
label5.setText("E-mail:");
label5.setLayoutData(gridData);
Text text5 = new Text(comp,SWT.NONE|SWT.BORDER);
text5.setLayoutData(gridDataT);

GridData gridB1 = new GridData();
gridB1.horizontalAlignment = GridData.END;
Button button1 = new Button(comp,SWT.NONE|SWT.ARROW_LEFT);
button1.setText(" 注册 ");
button1.setLayoutData(gridB1);
Button button2 = new Button(comp,SWT.NONE);
button2.setText(" 取消 ");


shell.open();
while(!shell.isDisposed())
{
if(!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
}

public static void main(String[] args)
{
new newUser();
}
}
...全文
129 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
dracularking 2009-12-16
  • 打赏
  • 举报
回复
Applications which are built with SWT will almost always require only a single display. In particular, some platforms which SWT supports will not allow more than one active display. In other words, some platforms do not support creating a new display if one already exists that has not been sent the dispose() message.
在建立swt的程序时一般总是只需要一个display对象。但也有特别的情况,有的平台不支持swt创建多个活动的display对象。也就是说,如果已存在一个display对象,但是给它没有发送disose()消息来销毁它,有的平台是不支持再创建一个新的display对象。

SWT实现的是单线程UI模型,在这个模型里,只有UI线程(创建首个Display对象的线程)才能调用UI操作,如果从UI线程外访问SWT对象就会得到异常"org.eclipse.swt.SWTException: Invalid thread access".
但我想重复new Display对象也未必和多线程挂得上勾,查看了一些资料,应该基于所创建新Display对象之线程已经存在的判断:
if (Displays [i].thread == thread) SWT.error (SWT.ERROR_THREAD_INVALID_ACCESS);
GreenVesture 2009-12-16
  • 打赏
  • 举报
回复
Display display = new Display(); 这句有问题,你不能在同一个线程中创建2个Display,可以改为 Display display = Display.getCurrent();
x-teamer团队 2009-12-16
  • 打赏
  • 举报
回复
public void widgetSelected(SelectionEvent e)
{
new newUser();
}
});

这里要避免ui线程和主线程相互访问:
final Display display = Display.getDefault();
if ((display != null) && (!display.isDisposed())) {
display.asyncExec(new Runnable() {
}

将方法写在上述代码段中。

50,523

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧