nighty

折腾的年华
posts - 37, comments - 143, trackbacks - 0, articles - 0

    许久没有弄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(800600));
        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部分,肯定收获会不少!

 

刚进场的时候戏就落幕

Feedback

# re: 学习RssOwl2中的添加隐藏工具栏和状态栏的功能  回复  更多评论   

2008-08-01 02:02 by 酒店咨询
好强,加油哦

# re: 学习RssOwl2中的添加隐藏工具栏和状态栏的功能  回复  更多评论   

2008-08-01 14:44 by mzclv
大哥们,能给小弟一个SVN地址吗?

# re: 学习RssOwl2中的添加隐藏工具栏和状态栏的功能  回复  更多评论   

2008-08-04 18:57 by 學習奮鬥
请问怎么样才能将源码导入eclipse里面呢?

# re: 学习RssOwl2中的添加隐藏工具栏和状态栏的功能  回复  更多评论   

2008-08-04 19:30 by 寒武纪
RssOwl2采用SVN做为版本管理,需要先安装Eclipse的SVN插件Subclipse,可以搜索一下,用法和CVS基本类似。SVN库地址就是:https://rssowl.svn.sourceforge.net/svnroot/rssowl/trunk/
匿名登录就可以。

# re: 学习RssOwl2中的添加隐藏工具栏和状态栏的功能  回复  更多评论   

2008-08-18 21:45 by gsvince
按你说的导入程序有错是怎么回事?

只有注册用户登录后才能发表评论。


网站导航: