将JConsole移植到Eclipse平台(1)--实现基于SWT的MDI风格界面

来源:互联网 发布:淘宝企业店能贷多少钱 编辑:程序博客网 时间:2024/06/01 07:32

JConsole是一个基于JMX的GUI工具,用于连接正在运行的JVM,它是一个MDI风格的Java桌面应用。SWing实现MDI风格界面的基础是JInternalFrame和JDesktopPane。那么如何基于SWT实现MDI风格界面呢?Eclipse平台中我们找不到这样的实现做参考(如果哪位网友发现有个非常好的这类实现一定要告诉我),但实际上SWT还是提供了类似的实现基础---那就是Decorations。从下图中的类继承关系看,既然Decorations是一个Control,而且没有说它不可以嵌到其他Composite中去,那它就应该可以(它的子类Shell明确声明为不可以)。

 

创建一个View作为主界面是个理所当然的选择,使用ViewMenu和ToolBar实现Sun Jconsole提供的菜单项(Help除外):

  • 创建一个JMX连接
  • 层铺所有内部窗口
  • 平铺所有内部窗口
  • 最小化所有内部窗口
  • 恢复所有内部窗口到normal状态
  • 将某个内部窗口切换到最前面。

下图为Sun的界面与本人实现的界面对比图:

 

 

对于目前实现的demo来说最重要的2个类就是MyJConsoleView和VMInternalFrame,其中VMInternalFrame继承Decorations并于Sun JConsole中的命名保持一致,MyJConsoleView的菜单中固定不变部分定义在plugin.xml中,而随着内部窗口增加、删除,对应的菜单项也将动态加到菜单中或从菜单中删除。

 

对于MDI风格界面层铺和平铺布局至关重要,本实例中采用了和Sun JConsole相类似的布局算法。

 

 

对于MDI界面,当有内部窗口处于最大化状态时,如果外部窗体(我们这就是view)的大小发生变化或最大化时,这个内部窗口也应该随之改变大小。为此VMInternalFrame实现了ControlListener用于监听view的变化。

 

在controlResized()方法中式所以用到了asyncExec是因为如果不这样当view最大化时,处于最大化状态的内部窗口并不随之变化。而定义变量isMax的原因是getMaximized()方法有问题,当view最大化时,处于normal状态的内部窗口的getMaximized()也返回true(我没有细究其中的原因,如果哪位细心的网友发现原因别忘了告诉我)。

注意:继承Decorations的类必须重载checkSubclass (),否则SWT验证通不过。

问题:

Decorations实现的内部窗口存在一些问题,有些甚至是目前无法解决的,以至于eclipse官方不建议使用Decorations。我发现2个比较重要的问题:

    1. Decorations在创建后style无法变更,因此不能在最大化时与主窗口融合。

    2. 因为在View中创建了Decorations,在退出eclipse时需要在“Confirm Exit”对话框上多点几下才能获取焦点,直接点“OK”按钮根本没反应。

网上有人建议使用ViewForm来实现内部窗口,但找不到一个像样的实例,用它模拟出内部窗口所具有的全部特性肯定需要费些周折。接下来我将使用Decorations先实现JConsole的基本功能(1.0),而在2.0中采用ViewForm模拟内部窗口。