使用Eclipse Galileo 已经半个多月了,对Galileo 的这次升级感到很满意!从Europa 到Ganymede 再到Galileo, Eclipse 在每年6 月底发布一个新版本,每年为用户带来创新成果、每年为用户带来新的喜悦。我的工作是从事电子政务软件开发,开发的项目和产品,有的采用C/S 结构、有的采用B/S 结构、或者是采用C/S 与B/S 的混合结构。对我来说,Eclipse 是值得信赖的,我的工作和生活已经离不开她。下面谈谈我是如何利用Eclipse 解决工作中面临的问题,以及我比较喜欢Galileo 的一些特性。
1 、 RCP 软件开发
我们的产品基本上都包括数据采集、数据传输、综合应用和数据仓库几个部分。鉴于政府窗口办公实时性和可靠性的要求,我们的数据采集部分大多采用C/S 结构模式,采用本地数据库,开发语言大多采用Visual Basic 、Pasic(Delphi)或Visual C++ ;数据综合应用部分采用B/S 结构模式,基于J2EE 体系结构。原来系统存在的主要问题是维护工作量大,如果新增加一个需求,则可能需要变更前端、通信及台后三个部分的代码,编码与测试都是一件很痛苦的事情。
经过多方面的比较选型后,我们决定基于C/S 结构的项目,采用Eclipse 富客户端平台(Eclipse RCP), 前端是RCP、后端是JavaEE 应用服务器和数据库,数据持久化采用EclipseLink 。Eclipse RCP 解决了富客户端软件开发的大部分问题,让开发人员将关注重点转移到客户的业务需求,简化了应用软件的开发。另外,Eclipse RCP 基于插件的体系结构,解决了软件复用问题。
2 、 Web 应用开发
Web 应用开发我们主要使用JBoss Seam 框架,JBoss Seam 将标准的JavaEE 技术和几个非标准但很有趣的技术集成为一个具有统一规范的编程模型,这些技术包括JSF 、EJB3 、JPA 、Hibernate 、JBPM 、Drools 、Ajax4jsf、Facelets 、RichFaces 、 GWT 、Wicket 等,Seam 切实简化了Web 应用软件开发。
随着Galileo 版本的发布,JBoss 紧跟着也发布了基于Galileo 的JBoss Seam tools 插件,为Galileo 版本提供了Seam 开发工具。JBoss Seam tools 可以通过更新管理器,从更新站点http://download.jboss.org/jbosstools/updates/development 升级。也可以下载压缩包,解压到Galileo 相应目录。下载Seam 开发工具后,需要配置Seam Window”—>“Preferences” 打开属性编辑窗口,找到“Jboss Tools”-->“Web”-->“Seam” 项。 运行时。单击“
单击“Add” 按钮,出现编辑Seam 运行时窗口:
设置Seam 运行时所在文件夹( 如“/opt/jboss-seam-2.1.2”) 后,即可在Eclipse 环境进行Seam 开发了。利用Seam-gen 可以从数据库生成我们需要的Java 类和Facelets 页面文件;可以可视化编辑Facelets 文件、页面流及Drools 规则等;还可以自定义FreeMarker 文件,生成我们想要的任何文件。
在ubuntu 9.0.4 下使用Jboss Tools HTML 编辑器打开xhtml 文件时如果出现错误:
Could not open the Visual Page Editor: /opt/eclipse/plugins/org.mozilla.xulrunner.gtk.linux.x86_1.8.1.3-20070904/xulrunner/libjavaxpcomglue.so: libstdc++.so.5: cannot open shared object file: 没有该文件或目录 |
则需要安装libstdc++5 库:
yawolf@yawolf:-$ sudo apt-get install libstdc++5 |
Web2.0 应用开发离不开CSS 、JavaScript 和AJAX ,本次发布的Galileo 版本提供了JavaScript 编辑器 ,为JavaScript 的编辑和校验提供很大的便利。
3 、C/C++ 开发工具
很希望我们的应用全部基于JavaEE 平台,但目前这只能是一个奢望,我们的软件需要跟硬件设备打交道:驱动图像扫描仪、驱动第二代居民身份证读取机具、调用其他一些DLL 动态库或OLE/COM 组件等等,所有这些都需要C 或C++ 编辑器,封装JNI 以便实现Java 调用。还好,Eclipse 为我们提供了C/C++ 开发工具,可以让我们方便地进行C/C++ 开发。
4 、我喜欢Galileo 的一些特性
( 1)Java 对比编辑器(compare editor)
在进行版本控制时,我们需要比较前后究竟做了哪些修改?Galileo 对Java 对比编辑器(compare editor) 的增强,使得版本变化比较直观、方便。
(2) 增强的JavaScript 桥
现在SWT 浏览器控件不但可以从java 调用JavaScript 代码,也可以从JavaScript 调用Java 代码。这可以使我们的RCP 应用可以紧密地与Web 浏览器结合起来。例如,在我们的RCP 应用中,可以调用Google 地图,通过Google 地图返回的地理位置信息,在RCP 中显示相关该地理位置的建筑物名称、使用单位、居住人员等信息。
在下图中,左边是通过SWT 浏览器调用Google 地图,显示温州市区地图,当在地图上单击某点时,左边通过JavaScript 显示地理位置信息,右边通过Java 显示地理位置信息。如果,我们在数据库中存储地名与地理信息的关联,就不难实现通过地理位置信息查询其他与应用相关的信息。
下面是Java 类:
- /*******************************************************************************
- * Copyright (c) 2000, 2004 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * IBM Corporation - initial API and implementation
- *******************************************************************************/
- package org.eclipse.swt.snippets;
- import java.io.File;
- import java.io.IOException;
- import org.eclipse.swt.SWT;
- import org.eclipse.swt.SWTError;
- import org.eclipse.swt.browser.Browser;
- import org.eclipse.swt.browser.BrowserFunction;
- import org.eclipse.swt.custom.SashForm;
- import org.eclipse.swt.events.ControlEvent;
- import org.eclipse.swt.events.ControlListener;
- import org.eclipse.swt.layout.FillLayout;
- import org.eclipse.swt.layout.GridData;
- import org.eclipse.swt.layout.GridLayout;
- import org.eclipse.swt.widgets.Composite;
- import org.eclipse.swt.widgets.Display;
- import org.eclipse.swt.widgets.List;
- import org.eclipse.swt.widgets.Shell;
- public class Snippet308 {
- static List list;
- static Browser browser;
- public static void main(String[] args) throws IOException {
- File f = new File("map.html");
- Display display = new Display();
- final Shell shell = new Shell(display);
- shell.setText("SWT & JavaScript");
- shell.setLayout(new FillLayout());
- SashForm sash = new SashForm(shell, SWT.HORIZONTAL);
- try {
- browser = new Browser(sash, SWT.MOZILLA);
- browser.addControlListener(new ControlListener() {
- public void controlResized(ControlEvent e) {
- browser
- .execute("document.getElementById('map_canvas').style.width= "
- + (browser.getSize().x - 20) + ";");
- browser
- .execute("document.getElementById('map_canvas').style.height= "
- + (browser.getSize().y - 20) + ";");
- }
- public void controlMoved(ControlEvent e) {
- }
- });
- } catch (SWTError e) {
- System.out.println("Could not instantiate Browser: "
- + e.getMessage());
- display.dispose();
- return;
- }
- new CustomFunction(browser, "theJavaFunction");
- Composite c = new Composite(sash, SWT.BORDER);
- c.setLayout(new GridLayout(1, true));
- list = new List(c, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
- list.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
- browser.setUrl(f.toURI().toString());
- sash.setWeights(new int[] { 4, 1 });
- shell.open();
- while (!shell.isDisposed()) {
- if (!display.readAndDispatch())
- display.sleep();
- }
- display.dispose();
- }
- static class CustomFunction extends BrowserFunction {
- CustomFunction(Browser browser, String name) {
- super(browser, name);
- }
- public Object function(Object[] arguments) {
- // 获取从JavaScript传递的变量值
- double lat = ((Double) arguments[0]).doubleValue();
- double lng = ((Double) arguments[1]).doubleValue();
- double zoom = ((Double) arguments[2]).doubleValue();
- list.add("东经: " + lng);
- list.add("北纬: " + lat);
- list.add("缩放级别为: " + zoom);
- list.add("---------------------");
- return null;
- }
- }
- }
下面是Html 文件:
- <!DOCTYPE html "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
- <title>Google Maps JavaScript API Example</title>
- <mce:script src="http://maps.google.com/maps?file=api&v=2&key=abcdefg&sensor=false" mce_src="http://maps.google.com/maps?file=api&v=2&key=abcdefg&sensor=false"
- type="text/javascript"></mce:script>
- <mce:script type="text/javascript"><!--
- var map;
- function initialize() {
- if (GBrowserIsCompatible()) { //用于检查浏览器兼容性
- map = new GMap2(document.getElementById("map_canvas"));//初始化一个地图实例
- map.setCenter(new GLatLng(28.017815, 120.644388), 14);//设置地图中心的坐标及缩放级别
- map.disableDoubleClickZoom();
- map.setUIToDefault();
- GEvent.addListener(map,"click", function(overlay,latlng) {
- //var myHtml = "GPoint 为: " + map.fromLatLngToDivPixel(latlng) + ",<br>缩放级别为:" + map.getZoom();
- var myHtml = "经度:" + latlng.lng() + ", 纬度:"+ latlng.lat() + ",<br>缩放级别为:" + map.getZoom();
- theJavaFunction(latlng.lat(), latlng.lng(), map.getZoom());//将当前位置传递给Java
- map.openInfoWindow(latlng, myHtml);
- });
- map.addControl(new GSmallMapControl());
- map.addControl(new GMapTypeControl());
- }
- }
- // --></mce:script>
- </head>
- <body onload="initialize()" >
- <div id="map_canvas" style="width: 600px; height: 400px">
- <!-- 这里放置地图实例-->
- </div>
- </body>
- </html>
(3) 表格标题行菜单
可以对表格或树表的标题行设置弹出菜单,选择要显示或隐藏的列。这样,我们就可以定制显示输出,为不同的用户提供相应的缺省显示内容。有关表头标题菜单的例子,请参考Snippet311 ;有关树表表头标题菜单的例子,请参考Snippet312
(4) 未保存提示
现在可能设置Shell 的更改状态,如果在Shell 处于更改状态时关闭窗口,将弹出修改信息未保存的提示对话框,提醒用户保存。示例代码请参考Snippet314
在开发中能够很快地升级到Galileo版本,除了Galileo自身功能增强外,其他Eclipse插件软件开发商也积极提供了对Galileo的支持,除了JBoss Seam Tools 外,还有Scala 、TestNG 、JSON 、Wicket 、Obfuscate4e 、jgit 等等。Eclipse 越来越人性化、越来越强大、真让人爱不释手。工欲善其事必先利其器,Eclipse 让我的工作事半功倍。以上我所用到的、知道的,仅仅是Eclipse 强大功能 之冰山一角、皮毛而已,还有好多东西需要我们去学习、去挖掘、去实践。