功能如下:所谓动态,可能是菜单的文字、图片、是否可用(enable)、是否选择(selected)都随着环境变化而变化。要求如下:
请大家给出一个解决方案,不要要代码,只要说明白就行。另外模块与模块之间耦合性尽量小,要严格考虑可扩展性。个人说明:
一、本人已经有5年Swing经验,但是一直无法用一个较好的方法解决这个问题。当然如果你认为我很无能,我能够接受,毕竟我对这个无能为力。
二、本人准备创业,J2SE、J2ME、J2EE同吃,但是最喜欢做的就是Swing,如果有志同道合者可以联系我QQ:22530630。自己最初的构想:
所有的菜单选项一一做成AbstractAction,然后通过配置文件来读入,但是现在遇到一个非常别扭的问题就是如何通过环境变化来控制裁断选项?1、难道要用Observer,我认为用了Observer不利于项目的扩展。因为:如果有一天我需要Observe另外一个Subject,难道又要修改这个Subject使他变为Observable,这非常不适合设计模式的“开闭原则”。
2、重载JMenuItem#isEnabled(),大家可以试一试。我是这么做的,但是发现一个问题,这些JMenuItem显示和快捷键(Accelerator)都存在一些不正常的效果,具体的问题我无法用文字来描述,请抱歉。
希望大家能够帮忙!

解决方案 »

  1.   

    所谓环境,是指当不同的状态。比如用户选择文本和没有选择文本就是两种不同的环境。假如用户选择文本,delete菜单就会是enabled状态;而未选中时,就是disabled状态。现在就像把这个菜单独立做成一个deleteAction,以避免和系统过多耦合,达到更好的扩展
      

  2.   

    不是特别清楚你的意思,好像没有那么麻烦
    比如用户选择文本的时候Delete菜单要变成enable状态。
    先得到这个Delete菜单的引用deleteMenuItem,然后调用deleteMenuItem.setEnable(true)不就可以了
    至于怎么得到Delete菜单的引用,可以先得到主界面的引用,再getmenubar得到menubar,再递归查找这个menubar(根据menu的text,比如"Delete",也可以根据path[Edit|Delete])得到对应菜单的引用就可以了吧 ,这样作的前提是必须知道Delete菜单的文本,这个应该知道吧。
      

  3.   

    菜单我做过,但没有遇到楼主那样复杂的情况。
    我觉得,真的那样复杂,可以做一个菜单的上下文context。
    对于每一个菜单项,我都注册到上下文中,通过上下文我可以找到它的引用,
    这样,你要控制他的状态,可以做事件模式也可以用abstractAction。
    然后对于菜单,你可做一个菜单的管理类,用来加载,显示,不同的菜单项。
    比如说,我要动态的控制文件菜单的退出菜单项,我只需要把退出菜单项引用拿到,然后修改其状态,然后再刷新文件菜单就可以了。我见过我们公司的一个产品就是这样做的。
    建议而已。
      

  4.   

    楼上的,很感谢你的帮忙,我把我们的聊天记录片断贴上来,供大家思考。要实现容易,要做到少修改原来的系统着就比较难了 '& 桜 就是本人了 '& 桜 14:05:13
    但是每当我要新加一个菜单项就的修改Context代码啊 
    10194830 14:07:00
    不用啊。你可把菜单信息都写在xml里,启动时加载一次。对每一个xml记录建一个菜单项对象。就行了。 
     '& 桜 14:06:32
    修改菜单的状态是通过context修改吗? 
    10194830 14:08:28
    context只能来保存每一个菜单项的引用,
    你拿到了系统中某个菜单项的引用难道还不能修改它的状态。
    就象做web一样,做一个servlet上下文。 
     '& 桜 14:07:40
    其实我也想过,但是就写了个接口EidtorModel,应该和你想得差不多,后来又被我删掉了 
    10194830 14:09:02
    呵呵,我也不太清楚。反正他们那样做了。感觉还行。 
     '& 桜 14:08:22
    关键是系统的环境和这些菜单耦合性太大,不知道怎么分散好 
    10194830 14:09:53
    可以做事件模式,你只要通知菜单,那他自己改变状态就行了。 
     '& 桜 14:10:05
    而且被监听的对象随时可能变化。
    比如我某一时刻会监听A的某一个状态,在另外一些条件下又会监听B的另一种状态 
    10194830 14:14:09
    我不管你监听那个状态。菜单项只管接受通知。因为菜单项在整个系统中是唯一的,我把他的引用加到a对象的通知池中,然后再把他的引用加到b对象的引用池中。我不管你a 变还是b 变,我都通知到了同一个菜单项。 
     '& 桜 14:13:39
    哦。我知道你的意思了 
     '& 桜 14:13:58
    最初就是这么弄的 
    10194830 14:15:04
    哦,那出了什么问题》 
     '& 桜 14:15:17
    一旦要实现新的菜单,就必须得修改操作context的类的代码 
     '& 桜 14:15:26
    和context 
     '& 桜 14:16:24
    你这个context起到了调停者作用而已 
     '& 桜 14:17:10
    我最希望的就是不改context和context以外的代码 
    10194830 14:18:14
    实现新的菜单,不要修改context 吧。
    只需要xml中配置就行了啊。 
     '& 桜 14:17:22
    这样可以任意配置文件 
    10194830 14:18:49
    context只是一个容器,用来取引用的。
    为什么修改他呢? 
     '& 桜 14:18:51
    关键我还不知道你的context是什么,就是不修改context也会修改context依赖的类 
     '& 桜 14:19:47
    我现在的动态并不只是数目上的动态,而且会存在属性上的动态 
    10194830 14:21:12
    你的意思就是可能是某个菜单项触发的事件不同吗? 
    10194830 14:21:45
    某个菜单项触发的事件因环境不同而不同? 
     '& 桜 14:20:54
    假如我要实现一个历史记录,因为用户进行了一系列的操作就会改变这个历史记录,但是我又非常不想对原来的系统进行修改 
     '& 桜 14:21:12
    某个菜单项触发的事件因环境不同而不同? 这个都不是关键,其实有不有都是小事 
     '& 桜 14:21:55
    我现在唯一能够实现历史记录的就是通过对用户操作监听,来实现历史记录。 
     '& 桜 14:22:03
    这样就可以不修改原来的系统。。 
    10194830 14:23:34
    你是要向原有系统中加入一个历史记录的功能,又不修改原有系统? 
     '& 桜 14:23:11
    这只是一个例子。要加的东西很多的,尽量不修改原来的系统 
     '& 桜 14:23:45
    而你那种方法每当加入一个新的菜单,就要考虑这个菜单在什么情况下会变化,就必须得修改原来的代码了 
    10194830 14:24:57
    嗯,我明白了。
     
     '& 桜 14:24:59
    优秀的实际就是在增加新功能是尽量不修改其他地方的代码 
    10194830 14:25:56
    你是说,现在要给原有系统新加菜单,让原有系统的一些操作可以改变菜单的状态,又要不修改原有系统的代码是吗》 
     '& 桜 14:25:16
    对! 
     '& 桜 14:25:44
    其实我也知道不修改是不可能的,只是保证尽量少,不能是加一个就要修改一个 
    10194830 14:26:47
    呵呵,这个问题倒没有考虑过。原有的设计肯定是不合理的。不然也不会这么难加。