JavaSWT:包装syncExec和asyncExec以清理代码
我有一个使用SWT作为工具包的Java应用程序,我已经厌倦了更新GUI元素所需的所有难看的锅炉板代码 只需将禁用按钮设置为启用,我必须经历以下过程:JavaSWT:包装syncExec和asyncExec以清理代码,java,user-interface,swt,Java,User Interface,Swt,我有一个使用SWT作为工具包的Java应用程序,我已经厌倦了更新GUI元素所需的所有难看的锅炉板代码 只需将禁用按钮设置为启用,我必须经历以下过程: shell.getDisplay().asyncExec(new Runnable() { public void run() { buttonOk.setEnabled(true); } }); SWTUtils.asyncExec(display).on(this.getClass(), this).runIn
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
buttonOk.setEnabled(true);
}
});
SWTUtils.asyncExec(display).on(this.getClass(), this).runInUIThread(123);
我更喜欢尽可能地保持我的源代码的扁平化,但是我需要一个惊人的3级缩进来做一些简单的事情
有什么方法可以把它包起来吗?我想要一门课,比如:
public class UIUpdater {
public static void updateUI(Shell shell, *function_ptr*) {
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
//Execute function_ptr
}
});
}
}
并且可以这样使用:
UIUpdater.updateUI(shell, buttonOk.setEnabled(true));
像这样的东西对于隐藏SWT认为做任何事情都有必要的可怕的混乱是非常好的
据我所知,Java不能做函数指针。但是Java7将有一个叫做闭包的东西,这应该是我想要的。但与此同时,我能做些什么来传递一个函数指针或回调给另一个要执行的函数吗
顺便说一句,我开始认为在Swing中重做这个应用程序是值得的,我不必忍受这种丑陋的垃圾和SWT的非跨平台性。我的SWT代码中也有类似的问题 我编写了一个基类,它只有asyncExec和syncExec方法。我想调用的每个GUI方法都有一个方法 我的非GUI线程类扩展了基类 因此,在非GUI线程类中,我有一个类似于
setEnabled(shell,true)
在基类中,我将定义一个
public void setEnabled(Shell,boolean flag)
方法,该方法将在第一个示例中包含代码。我不久前在一个封闭源代码项目中解决了这个问题。我的API是这样工作的:
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
buttonOk.setEnabled(true);
}
});
SWTUtils.asyncExec(display).on(this.getClass(), this).runInUIThread(123);
此调用将在实例This
上使用参数123
运行方法runInUIThread(.)
。这里需要的是参数this.getClass()
您的示例重新编写:
SWTUtils.asyncExec(shell.getDisplay()).on(Button.class, buttonOk).setEnabled(true);
我的实现使用CGLib为给定类创建动态代理。此代理由(.)上的返回,方法调用及其参数被记录并传递到display.asynceec(.)
。我使用objeness来实例化代理
您可能会惊讶于没有可感知的性能影响。由于代理是缓存的,在Java1.6中调用实际方法所需的反射API速度非常快,因此我甚至将其用于事件侦听器
显然,这是一个相当疯狂的解决方案;)我不能发布它,但如果你和我一样对所有这些匿名内部类感到愤怒,你可能会想去做。事实上,代码并不太多。你说你想要这样的东西:
public class UIUpdater {
public static void updateUI(Shell shell, *function_ptr*) {
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
//Execute function_ptr
}
});
}
}
val enabled = model.isEditable
Swt {
text.setEnabled(enabled);
composite.refresh();
}
这不是SWT的函数,而是Java作为编程语言的函数。Java缺少高阶函数和闭包,因此无法创建一个好的DSL来为您隐藏这些缺点,因此,除非您更改语言,否则您收到的其他答案都一样好
现在,如果你使用的是Scala这样的语言,我想答案就大不相同了。您可能会创建某种类似于控制结构的函数,以确保您的SWT调用将在主SWT显示线程上执行
比如:
public class UIUpdater {
public static void updateUI(Shell shell, *function_ptr*) {
shell.getDisplay().asyncExec(new Runnable() {
public void run() {
//Execute function_ptr
}
});
}
}
val enabled = model.isEditable
Swt {
text.setEnabled(enabled);
composite.refresh();
}
这似乎是在没有函数指针和/或闭包的情况下完成这项工作的唯一方法。我希望您知道,Swing也是单线程的。因此,您必须像在SWT中一样从另一个线程更新GUI元素。唯一的区别是,当您从错误的线程调用Swting方法时,Swing不会抛出异常。但当你犯错误时,你会在你的应用程序中看到mayn weired bug。