利用继承高效率写程序

原创 2005年03月01日 13:55:00

2005年2月3日3:41:41

问题:
如果有两个JPopupMenu:a,b
a有个JMenu, b也有,但是b比a要多一个JMenuItem

我们用大写字母代表按钮上的名字
                  

                               __D
按钮a:   A__C__|__E
                              |__F

 

                           __D
                   C__|__E
                    |      |__F
按钮b    B--|  
                    |--G

         
我最初这样写的:

JPopupMenu a = new JPopupMenu("A");
JPopupMenu b = new JPopupMenu("B");
JMenu c = new JPopupMenu();        //想让a和b公有c     *_*
JMenuItem d = new JMenuItem("D");
JMenuItem e = new JMenuItem("E");
JMenuItem f = new JMenuItem("F");
c.add(d);
c.add(e);
c.add(f);
a.add(c);
现在的实际情况:a按钮是这样的
                __D
A__C__|__E
               |__F
好的,继续。
b.add(c);    //这条语句是后面失败的原因
JMenuItem g = new JMenuItem("G");
b.add(g);
到现在我想象的情况是:
                __D
A__C__|__E
               |__F

              __D
      C__|__E
       |      |__F
 B--|   
      |--G

但是一个组件是不能同时在两个Compoment里面的,所以
在b.add(c);这一句后,本来在a里面的c跑到b上面去了。
所以现在的实际情况是:

-


              __D
      C__|__E
      |      |__F
 B--|  
      |--G
正如我们所见,按钮a什么都没了:(

那么怎么办呢??
在我脑海里首先得到的解决方法是安步就班的一个一个写,
a和b重复的部分就要写两遍。
举个例子,这样写:(当然我没有这样写,为重复的每个按钮变量生成啊,取名啊,设置字体啊,设置颜色啊。。。太累了)

JPopupMenu a = new JPopupMenu("A");
JPopupMenu b = new JPopupMenu("B");
JMenu c = new JPopupMenu();
JMenuItem d = new JMenuItem("D");
JMenuItem e = new JMenuItem("E");
JMenuItem f = new JMenuItem("F");
c.add(d);
c.add(e);
c.add(f);
a.add(c);//a结束
JMenu g = new JPopupMenu();
JMenuItem h = new JMenuItem("D");
JMenuItem i = new JMenuItem("E");
JMenuItem j = new JMenuItem("F");
g.add(h);
g.add(i);
g.add(j);
JMenuItem k = new JMenuItem("G");
b.add(g);
b.add(k);//b结束
好了,现在的实际结果一定是正确的。
看上去假设这么写的好象没多少代码量,但是如前面所说,我们这只是做演示,加上字体、颜色、监听器等等实际上的代码量是非常大的!
其实最大的问题还不是代码量的问题,问题是你的程序的可读性大大降低了!!
要知道swing程序员不仅要构建复杂而且友好的界面,还要对大量的各种事件写监听器,在一大堆难读的代码中寻找按钮还不如要人家去电影院看100遍《2046》:)(2046实在难看,我直说好了)
我们需要让我们的程序可读性高,我不记得是哪位高手说的了:在一份程序的生命周期里,10%的时间用来写它,90%的时间是拿来给人家看的。
诸多原因,我们务必用优雅的方式解决问题:)

我最开始是这样想的:
能否自己写一个MyPopupMenu extends JPopupMenu
如果MyPopupMenu p = new MyPopupMenu();
有一部分MenuItem是已经存在在p里了?

经过实践,实践是真理:)
很快就搞定了。方法是这样的:
制作我们自己的MyJPopupMenu类,它继承自JPopupMenu,把公有的部分全部写进去,这样无论要怎么增加JMenuItem都不会烦了.
MyJPopupButton类如下:
假设在主类ManagerUI.java里面
public class ManagerUI
{
    private ...
    private Font font = new Font(...);
    private Color buttonColor = new Color(...);
    ...
    public ManagerUI()
    {
    ......
    }
    //这里是JPopupMenu的监听器
    private class MyPopupMenuListener implements ActionListener
    {
        ......
    }
    private class MyJPopupMenu extends JPopupMenu
    {
        private JMenuItem d = new JMenuItem("D");
        private JMenuItem e = new JMenuItem("E");
        private JMenuItem f = new JMenuItem("F");
        public MyJPopupMenu()
        {
        }
        public MyJPopupMenu(String name)
        {
            super(name);
        }
        //全部在这个方法里面一次性搞顶了,每个组件等会只需调用一下这个
        //public方法就ok了
        public void addPublicMenuItem()
        {
            //设置字体
            d.setFont(font);
            //设置颜色            
            d.setBackgroundColor(buttonColor); 
            e.setFont(font);
            e.setBackgroundColor(buttonColor);
            f.setFont(font);
            f.setBackgroundColor(buttonColor); 
            MyPopopMenuListener mp = new MyPopopMenuListener();
            d.addActionListener(mp); 
            e.addActionListener(mp);
            f.addActionListener(mp);        
            c.add(d);
            c.add(e);
            c.add(f);
            add(c);     //注意add()方法是继承超类JPopupMenu的
        }
    }
}

在原来需要产生JPopupMenu的地方加上我们的对象,代码是这样的:
public class ManagerUI
{
    private ...
    private Font font = new Font(...);
    private Color buttonColor = new Color(...);
    private JPopupMenu a;//注意这里我们是用公共类,MyJPopupMenu的
    private JPopupMenu b;//父类做的声明,等会需要向下转型
    ...
    public ManagerUI()
    {
        ......
   
        a = new MyJPopupMenu("A");               //非常简洁
        (MyJPopupMenu)a.addPublicMenuItem();     //记得向下转型
        b = new MyJPopupMenu("B");            
        (MyJPopupMenu)b.addPublicMenuItem();  
        JMenuItem c = new JMenuItem("G");      
        b.add(c);  
       
        .....                      
   
    }
    //这里是JPopupMenu的监听器
    private class MyPopupMenuListener implements ActionListener
    {
        public void actionPerformed(ActionEvent event)
        {
            String id = ((JMenuItem)event.getSource()).getActionCommand();
            if(id.equals("D"))
            {...}
            else if(id.equals("E"))
            {...}
            else if(id.equals("F"))
            {...}
            else if(id.equals("G"))
            {...}
        }
    }
    private class MyJPopupMenu
    extends JPopupMenu
    implement ActionListener
    {
        private JMenuItem d = new JMenuItem("D");
        private JMenuItem e = new JMenuItem("E");
        private JMenuItem f = new JMenuItem("F");
        public MyJPopupMenu()
        {
        }
        public MyJPopupMenu(String name)
        {
            super(name);
        }
        public void addPublicMenu()
        {
            d.setFont(font);
            d.setBackgroundColor(buttonColor);
            e.setFont(font);
            e.setBackgroundColor(buttonColor);
            f.setFont(font);
            f.setBackgroundColor(buttonColor); 
            MyPopopMenuListener mp = new MyPopopMenuListener();
            d.addActionListener(mp); 
            e.addActionListener(mp);
            f.addActionListener(mp);        
            c.add(d);
            c.add(e);
            c.add(f);
            add(c);
        }
    }
}

最后运行的情况不用我说了,绝对正确无误:)
完了吗?
记得James Cooper说过反正他认为类越多就越难管理,我们可以进一步进行优化,
把JPopupMenu按钮的监听器类删掉吧,为什么不呢?
很简单,只需要用MyJPopupMenu类实现ActionListener接口就可以了
这样完整代码变成这样:

public class ManagerUI
{
    private ...
    private Font font = new Font(...);
    private Color buttonColor = new Color(...);
    private JPopupMenu a;
    private JPopupMenu b;
    ...
    public ManagerUI()
    {
        ......
   
        a = new MyJPopupMenu("A");              
        (MyJPopupMenu)a.addPublicMenuItem();    
        b = new MyJPopupMenu("B");            
        (MyJPopupMenu)b.addPublicMenuItem();  
        JMenuItem c = new JMenuItem("G");      
        b.add(c);  
       
        .....                      
   
    }
    private class MyJPopupMenu
    extends JPopupMenu
    implement ActionListener
    {
        private JMenuItem d = new JMenuItem("D");
        private JMenuItem e = new JMenuItem("E");
        private JMenuItem f = new JMenuItem("F");
        public MyJPopupMenu()
        {
        }
        public MyJPopupMenu(String name)
        {
            super(name);
        }
        public void addPublicMenu()
        {
            d.setFont(font);
            d.setBackgroundColor(buttonColor);
            e.setFont(font);
            e.setBackgroundColor(buttonColor);
            f.setFont(font);
            f.setBackgroundColor(buttonColor); 
            MyPopopMenuListener mp = new MyPopopMenuListener();
            d.addActionListener(this); //注意:记得把这里改成this
            e.addActionListener(this);
            f.addActionListener(this);        
            c.add(d);
            c.add(e);
            c.add(f);
            add(c);
        }
        //把actionPerformed()方法写到这里
        public void actionPerformed(ActionEvent event)
        {
            String id = ((JMenuItem)event.getSource()).getActionCommand();
            if(id.equals("D"))
            {...}
            else if(id.equals("E"))
            {...}
            else if(id.equals("F"))
            {...}
            else if(id.equals("G"))
            {...}
        }
    }
}
终于搞定了,以上代码为了方便阅读用a,b,c...等字母表示的,实际情况当然不是这样:)
小结:
没有什么技术含量...:)
我是菜鸟,平时注意自我总结小经验对自己的Java水平一定有帮助的:)

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

高效率嵌入式ARM程序开发.pdf

  • 2010年01月11日 19:42
  • 148KB
  • 下载

高效率matlab程序设计宝典.doc

  • 2008年10月30日 11:08
  • 51KB
  • 下载

做个高效率的程序猿,使用VS内置的ASP.NET Web 服务器调试

前言:上周出差支持二次开发, 发现二开现场开发环境用的是IIS进行开发和调试,重启IIS服务器成本很大,而且本人的是超级本只装了VS没装数据库和产品。按二开他们目前的模式, 把Cloud产品+VS开...

高效率嵌入式程序开发

引言     在多媒体、通信等计算复杂度高的应用中,为了满足制造费用、功耗、性能以及实时性等诸多限制条件的要求,嵌入式系统程序往往需要特殊设计。这使得设计师在设计面向特定应用的嵌入式软件时,需要有一...

高效率3D图形程序中的骨骼-皮肤系统实现

骨骼--皮肤动画技术是3D动画领域的一项比较高级的技术。由于其生动、逼真的效果,在影视制作、动态仿真等领域起着重要的作用。只有使用骨骼--皮肤技术,才能制作出广播级的动画作品。  顾名思义,骨骼--皮...
  • szygy
  • szygy
  • 2011年11月16日 10:40
  • 188

如何做一个高效率的程序员,对程序员也是很重要。。

如何做一个高效率的人,对一个人的成功很重要,如何做一个高效率的程序员,对程序员也是很重要。大家好,我是:OpenEIM,下面与大家交流一些经验。   这是一则笑话。Shlemiel是一位油漆工,他...

LabVIEW 程序中的线程 2 - LabVIEW 的执行系统 [编写高效率的代码]

LabVIEW 程序中的线程 2 - LabVIEW 的执行系统 二、LabVIEW 的执行系统 1. 什么是执行系统     早期 LabVIEW 的 VI 都是单线程运行的,La...

LabVIEW 程序中的线程 3 - 线程的优先级 [编写高效率的代码]

LabVIEW 程序中的线程 3 - 线程的优先级 三、线程的优先级     在 VI 的属性设置面板 VI Properties -> Execution 中还有一个下拉选项控件是用...

LabVIEW 程序中的线程 1 - LabVIEW 是自动多线程语言 [编写高效率的代码]

一. LabVIEW 是自动多线程语言      一般情况下,运行一个 VI,LabVIEW 至少会在两个线程内运行它:一个界面线程(UI Thread),用于处理界面刷新,用户对控件的操作等等...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用继承高效率写程序
举报原因:
原因补充:

(最多只允许输入30个字)