Eclipse GUI 线程方面的问题

当做 widget toolkit 方面的工作时,理解底下的线程模型很重要,它用来读取和分发平台的GUI事件。当使用Java线程时,UI线程的实现影响到应用必须遵循的规则。

本地时间分发

操作系统将时间分发给应用程序

SWT UI 线程

UI有自己的独立的线程,Display 里创建。

应用的主线程负责负责处理 event loop,SWT 应用一般都有下面对结构:

public static void main(String[] args){
Display display = new Display();
Shell shell = new Shell(display);
shell.open();
// start the event loop. We stop when th euser has done
// something to dispose our window.
while(!shell.isDisposed()) {
if(!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}

在一个非UI 线程那里执行代码

同步
syncExec(Runnable)

非UI线程需要从 UI 代码那里获得返回值,或者 在返回到线程之前,确保 runnable 运行完成。

异步
asyncExec(Runnable)

在应用程序需要执行一些UI操作,并不依赖操作的完成再继续。

下面是一个使用这些方法的演示:
// do time-intensive computations
...
// now update the UI. We don't depend on the result,
// so use async.
display.asyncExec (new Runnable () {
public void run () {
if (!myWindow.isDisposed())
myWindow.redraw ();
}
});
// now do more computations
...

一个好的练习,使用 asyncExec 在你的 runnable 里面检查 你的 widget 是否已经被销毁。由于在UI线程内部,调用asyncExec和你的runnable的执行时间内,其他的事情可能发生,因此,你不能确认在你的runnable执行期间,你的widget是什么状态。

工作台和线程

当你从底部往上,实现一个 SWT 应用,由于你控制了event loop 的创建和fork计算线程的决定,线程的规则就变得非常明确。

当你将插件的代码发布到工作台,事情就有一点复杂了。当使用平台UI类s,下面的规则可以被考虑成“承诺的规则“,虽然随着版本的更新,这些规则会有一些异常:

• 一般情况下,你增加到平台的任何工作台UI扩展,都在工作台的UI线程内执行,除非它们与线程s或者背景工作s都特别相关(例如背景工作进度表示)。
• 如果你从工作台那里接收到一个事件,但不敢保证,它在工作台的UI线程内执行。查阅javadoc里面的特定的类,这个类定了监听器或者事件。如果没有描述线程的相关文档,并且该类明显是一个UI相关的测类,你可以期望这个事件在工作台线程内到达。
• 同样,一个平台UI库不需要考虑线程安全,否则特别给它做文档。注意,大多数的平台UI类从触发事件的调用线程分发监听器。工作台和JFace API的调用不检查调用者是否在UI线程内。如果你调用从一个非UI线程里面调用一个触发事件的方法,你的插件将产生一个问题。这种情况,SWT触发一个SWTException。一般情况下,避免从另一个线程那里调用平台UI代码,除非javaodc特别允许。
• 如果你的插件 fork一个计算线程或者使用一个工作台的job,必须使用 Display 的 asyncExec(Runnable) 或者 syncExec(Runnable)方法(为工作台,JFace或者SWT调用任意API),除非相关的API特别允许被背景线程call-in。
• 如果你的插件使用JFace的IRunnableContext接口调用一个进度监视器和运行一个操作,它提供一个参数,指明是否为运行的操作fork一个计算线程。

Posted in Eclipse | Leave a comment

Maven插件开发

Mojo是 Maven plain Old Java Object。在Maven里面,每一个mojo都是一个可执行的goal。一个插件由一个或者多个相关的mojo组成。

• 你的第一个Mojo,学习编写第一个插件

这里介绍如何为Maven2.0开发Java插件。

+ 第一个插件

在这一段,我们将建造一个简单的插件,这个插件没有参数,只是在运行时简单的在屏幕上显示一条信息。沿着这个方法,我们将学到创建一个插件项目的基础步骤,一个Java mojo的最小内容,一组执行mojo的方法。

用最简单的方法,一个Java mojo由单个class来组成。不像EJBs那样需要多个类,一个插件由一定数理的同类mojos组成,就如使用一个抽象的超类,对所有的mojos统一代码。

一个简单的Mojo

下面是一个没有参数的简单mojo类。这已经是最简单的mojo类了。

package sample.plugin;

import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;

/**
* Says "Hi" to the user.
* @goal sayhi
*/
public class GreetingMojo extends AbstractMojo
{
public void execute() throws MojoExecutionException
{
getLog().info("Hello, world.");
}
}

+ Maven插件项目定义

例子:

<project>
<modelVersion>4.0.0</modelVersion>
<groupId>sample.plugin</groupId>
<artifactId>maven-hello-plugin</artifactId>
<packaging>maven-plugin</packaging>
<version>1.0-SNAPSHOT</version>
<name>Sample Parameter-less Maven Plugin</name>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>2.0</version>
</dependency>
</dependencies>
</project>

+ 建造目标

compile Compiles the Java code for the plugin and builds the plugin descriptor
test Runs the plugin’s unit tests
package Builds the plugin jar
install Installs the plugin jar in the local repository
deploy Deploys the plugin jar to the remote repository

+ 执行插件

在建造过程中执行:

<build>
<plugins>
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>maven-hello-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
</plugin>
</plugins>
</build>

通过命令行执行的方法:

mvn groupID:artifactID:version:goal

+ 缩短命令行

• 如果你使用的某插件的最新版本,可省略到版本号
• “maven-$name-plugin” 和 “$name-maven-plugin”这类名字的插件,有特殊待遇。在输入时,只需输入$name代表的字符串就可以执行。执行时,如果没有找到相应的插件,还会继续添加maven和plugin两个字符串的插件。
• 最后,你可以添加插件的groupId到 ${user.home}/.m2/settings.xml文件,是的该groupId作为缺省的groupId,下面是一个例子:

<pluginGroups>
<pluginGroup>sample.plugin</pluginGroup>
</pluginGroups>

+ 在指定的声明周期内加入Mojo

<build>
<plugins>
<plugin>
<groupId>sample.plugin</groupId>
<artifactId>maven-hello-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>sayhi</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

+ Mojo 的原型

mvn archetype:create \
-DgroupId=sample.plugin \
-DartifactId=maven-hello-plugin \
-DarchetypeGroupId=org.apache.maven.archetypes \
-DarchetypeArtifactId=maven-archetype-mojo

+ 参数

参数可以在 Mojo 里面定义,定义的方式如下:

/**
* The greeting to display.
*
* @parameter expression="${sayhi.greeting}" default-value="Hello World!"
*/
private String greeting;

或者在一个项目中定义:

<plugin>
<groupId>sample.plugin</groupId>
<artifactId>maven-hello-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<configuration>
<greeting>Welcome</greeting>
</configuration>
</plugin>

+ 参数的类型

Boolean, Integer, Double, Date, File/Directory, URL, Plain Text( char, Character, StringBuffer, and String), Array, Collection, Map, Properties, Other Object.

+ 关于 Setters

编写可重用的Mojo,可以在 Maven 外部使用。

Posted in Maven | Tagged | Leave a comment

生活不能没有绿色

办公室里每个人负责一盘植物,右边是我的。

Posted in 生活 | Leave a comment