Posted on 2008-07-31 15:13
寒武纪 阅读(2078)
评论(5) 编辑 收藏 所属分类:
Eclipse
许久没有弄RCP了,刚好近来闲暇一点,找来个RSSOwl的源代码看看,有点收获。RssOwl非常出名,只是可能很多人不知道它是用Java做的。以前看过RssOwl第一版的源码,没有详细研究,down下来之后放上公司的共享CVS服务器,倒是几个同事饶有兴趣地研究起来。第一个版本写得较早,可能Eclipse的RCP框架都还没有出来,所以全部采用的SWT/JFace实现,主窗体就用的JFace里面的ApplicationWindow包装起来的。粗看了一下,感觉代码划分和设计得不错,把UI编码的大部分重复功能都抽取出来,那时候做项目,就经常从里面挖些代码出来用。现在上它的主页http://www.rssowl.org/,新设计的RssOwl 2 是基于RCP重构的,已经到了M8版本,主页的download没有直接的源代码包下载,只提供了SVN库,可以从里面check出来,地址是:https://rssowl.svn.sourceforge.net/svnroot/rssowl。拿出来后,总共是12个插件项目,相互关联。示意图如下:
从org.rssowl.build项目中的rssowl.product启动该RCP程序。可以预览到全部界面。看一张预览图。
非常漂亮,具体功能可以自己感受一下。
主要的代码都集中中org.rssowl.ui和org.rssowl.core二个插件,看标题就明白是什么意思,它本身的存储采用的是db4o,看来还是比较前卫哦。上面的主菜单中有一个view,也就是我们常在IE外壳等上面看到的“查看”菜单,里面有,“工具栏,侧边栏,状态栏”等等这些,可以隐藏或是显示,菜单项是check风格的。由于现在RssOwl 2仍处于Milestone阶段,所以很多代码仍是internal包里面的,以后肯定会慢慢变成公开的,做法和Eclpise如出一辙。
看一下org.rssowl.ui里面的代码,下面这几个非常熟悉的类。
菜单的设置就在ApplicationActionBarAdvisor.java类里面。为了简单起见,我把它的代码抽取出来,重新修改了一部分。如下:
@Override
protected void fillMenuBar(IMenuManager menuBar) {
//创建其它菜单
createViewMenu(menuBar);
MenuManager toolMenu = new MenuManager("工具(&T)",
IWorkbenchActionConstants.M_WINDOW);
menuBar.add(toolMenu);
toolMenu.add(prefAction);
MenuManager helpMenu = new MenuManager("帮助(&H)",
IWorkbenchActionConstants.M_HELP);
menuBar.add(helpMenu);
helpMenu.add(helpAction);
helpMenu.add(aboutAction);
}
/**//* Menu: View */
private void createViewMenu(IMenuManager menuBar) {
// final IPreferenceScope preferences = Activator.getDefault().getPreferenceStore();
MenuManager viewMenu = new MenuManager("查看(&V)", M_VIEW);
viewMenu.setRemoveAllWhenShown(true);
menuBar.add(viewMenu);
/**//* Add dummy action to show the top level menu */
viewMenu.add(new Action("") {
@Override
public void run() {}
});
/**//* Build Menu dynamically */
viewMenu.addMenuListener(new IMenuListener() {
public void menuAboutToShow(IMenuManager manager) {
manager.add(new GroupMarker(M_VIEW_START));
/**//* Toggle State of Toolbar Visibility */
manager.add(new Action("工具栏", IAction.AS_CHECK_BOX) {
@Override
public void run() {
ApplicationWorkbenchWindowAdvisor configurer = ApplicationWorkbenchAdvisor.WorkbenchWindowAdvisor;
boolean isToolBarVisible = preferences.getBoolean(DefaultPreferences.SHOW_TOOLBAR);
configurer.setToolBarVisible(!isToolBarVisible);
preferences.putValue(DefaultPreferences.SHOW_TOOLBAR, !isToolBarVisible + "");
}
@Override
public boolean isChecked() {
return preferences.getBoolean(DefaultPreferences.SHOW_TOOLBAR);
}
});
/**//* Toggle State of Status Bar Visibility */
manager.add(new Action("状态栏", IAction.AS_CHECK_BOX) {
@Override
public void run() {
ApplicationWorkbenchWindowAdvisor configurer = ApplicationWorkbenchAdvisor.WorkbenchWindowAdvisor;
boolean isStatusVisible = preferences.getBoolean(DefaultPreferences.SHOW_STATUS);
configurer.setStatusVisible(!isStatusVisible);
preferences.putValue(DefaultPreferences.SHOW_STATUS, !isStatusVisible + "");
}
@Override
public boolean isChecked() {
return preferences.getBoolean(DefaultPreferences.SHOW_STATUS);
}
});
/**//* Toggle State of Bookmarks Visibility */
manager.add(new Separator());
manager.add(new Action("任务管理", IAction.AS_CHECK_BOX) {
@Override
public void run() {
IWorkbenchPage page = JDownUI.getPage();
if (page != null) {
IViewPart mgrView = page.findView(TaskMgrView.ID);
/**//* Hide Bookmarks */
if (mgrView != null)
page.hideView(mgrView);
/**//* Show Bookmarks */
else {
try {
page.showView(TaskMgrView.ID);
} catch (PartInitException e) {
Activator.getDefault().logError(e.getMessage(), e);
}
}
}
}
@Override
public boolean isChecked() {
IWorkbenchPage page = JDownUI.getPage();
if (page != null)
return page.findView(TaskMgrView.ID) != null;
return false;
}
});
manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
manager.add(new GroupMarker(M_VIEW_START));
}
});
}
无法就是从MenuManager创建几个Check Style的Action而已。主要看怎么实现这几个Action的主功能。以工具栏为例。
ApplicationWorkbenchWindowAdvisor configurer = ApplicationWorkbenchAdvisor.WorkbenchWindowAdvisor;
boolean isToolBarVisible = preferences.getBoolean(DefaultPreferences.SHOW_TOOLBAR);
configurer.setToolBarVisible(!isToolBarVisible);
preferences.putValue(DefaultPreferences.SHOW_TOOLBAR, !isToolBarVisible + "");
首先要获取WorkbenchWindowAdvisor对象,隐藏的功能是在它方法中实现的,另外preferences是插件的首选项存储对象。把是否隐藏的状态持久化。我们再详看WorkbenchAdvisor的代码。
public class ApplicationWorkbenchAdvisor extends WorkbenchAdvisor {
private static final String PERSPECTIVE_ID = "com.jdown.perspective";
public static ApplicationWorkbenchWindowAdvisor WorkbenchWindowAdvisor;
public WorkbenchWindowAdvisor createWorkbenchWindowAdvisor(
IWorkbenchWindowConfigurer configurer) {
WorkbenchWindowAdvisor = new ApplicationWorkbenchWindowAdvisor(configurer);
return WorkbenchWindowAdvisor;
}
public String getInitialWindowPerspectiveId() {
return PERSPECTIVE_ID;
}
}
稍微修改一下自动生成的代码就可以,它本身也是这么实现的。程序窗口的基本功能都是在ApplicationWorkbenchWindowAdvisor中配置的, 所以最终功能还是在它的上面实现的。
public class ApplicationWorkbenchWindowAdvisor extends WorkbenchWindowAdvisor {
public ApplicationWorkbenchWindowAdvisor(IWorkbenchWindowConfigurer configurer) {
super(configurer);
}
public ActionBarAdvisor createActionBarAdvisor(
IActionBarConfigurer configurer) {
return new ApplicationActionBarAdvisor(configurer);
}
public void preWindowOpen() {
IWorkbenchWindowConfigurer configurer = getWindowConfigurer();
configurer.setInitialSize(new Point(800, 600));
configurer.setShowCoolBar(true);
configurer.setShowStatusLine(true);
configurer.setTitle("JDown");
}
void setToolBarVisible(boolean visible) {
getWindowConfigurer().setShowCoolBar(visible);
/**//* Hack: To avoid cheese, update Status Line Too */
boolean showsStatus = getWindowConfigurer().getShowStatusLine();
getWindowConfigurer().setShowStatusLine(!showsStatus);
getWindowConfigurer().setShowStatusLine(showsStatus);
getWindowConfigurer().getWindow().getShell().layout();
}
void setStatusVisible(boolean visible) {
getWindowConfigurer().setShowStatusLine(visible);
getWindowConfigurer().setShowProgressIndicator(visible);
/**//* Hack: To avoid cheese, update ToolBar Too */
boolean showsToolBar = getWindowConfigurer().getShowCoolBar();
getWindowConfigurer().setShowCoolBar(!showsToolBar);
getWindowConfigurer().setShowCoolBar(showsToolBar);
getWindowConfigurer().getWindow().getShell().layout();
}
}
看到IWorkbenchWindowConfigurer其实才是问题的关键。限于篇幅原因,这里只做了一个简单的介绍,如果你有兴趣,可以详细看看它的源代码,还可以学到更多的技巧,当然不是唯一办法,只是学现成的比自己摸索要快。还有另一个功能点,就是工具栏的下拉菜单实现,毕竟看Eclipse的源代码太大,不容易理清楚关系,看它(RssOwl)就感觉清晰得多了。有时间再介绍一下。
慢慢研读,特别是core部分,肯定收获会不少!
刚进场的时候戏就落幕