Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaSWT:包装syncExec和asyncExec以清理代码_Java_User Interface_Swt - Fatal编程技术网

JavaSWT:包装syncExec和asyncExec以清理代码

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

我有一个使用SWT作为工具包的Java应用程序,我已经厌倦了更新GUI元素所需的所有难看的锅炉板代码

只需将禁用按钮设置为启用,我必须经历以下过程:

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。