菜单和复合图案

时间:2012-10-17 19:40:13

标签: java swing design-patterns

我正在尝试复合模式以创建菜单栏 这是代码:

    public class TestMenu {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        MenuComponent openMenu = new MyMenu("Open Menu");
        MenuComponent openMenuItem1 = new MyMenuItem("Open Menu Item 1");
        MenuComponent openMenuItem2 = new MyMenuItem("Open Menu Item 2");
        openMenu.addMenu(openMenuItem1);
        openMenu.addMenu(openMenuItem2);
        MenuComponent exitMenuItem = new MyMenuItem("Exit Menu");

        MenuComponent mainMenu = new MyMenu("Main");
        mainMenu.addMenu(openMenu);
        mainMenu.addMenu(exitMenuItem);

        TestMenuFrame frame = new TestMenuFrame();
        frame.getMyMenuBar().addMainMenu(mainMenu);
        frame.setVisible(true);
    }
}


   public class MenuBar extends JComponent {

    public MenuBar() {
        setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));

    }

    void addMainMenu(MenuComponent mainMenu) {
        JButton btn = new JButton(mainMenu.getName());
        final JPopupMenu popupMenu = new JPopupMenu();
        Iterator<MenuComponent> iterator = mainMenu.iterator();
        if (iterator != null) {
            while (iterator.hasNext()) {
                MenuComponent menuComponent = iterator.next();
                JMenuItem item = new JMenuItem(menuComponent.getName());
                popupMenu.add(item);
            }
        }
        btn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                JButton btn = (JButton) e.getSource();
                popupMenu.show(e.getComponent(), e.getX(), e.getY());
            }
        });
        add(btn);
    }
}


    public abstract class MenuComponent {

    protected String name;

    public MenuComponent(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public abstract void addMenu(MenuComponent menu);

    public abstract Iterator<MenuComponent> iterator();

}


   public class MyMenu extends MenuComponent {

    private List<MenuComponent> listMenu = new ArrayList<>();

    public MyMenu(String name) {
        super(name);
    }

    @Override
    public void addMenu(MenuComponent menu) {
        listMenu.add(menu);
    }

    @Override
    public Iterator<MenuComponent> iterator() {
        return listMenu.iterator();
    }
}


    public class MyMenuItem extends MenuComponent {

    public MyMenuItem(String name) {
        super(name);
    }

    @Override
    public void addMenu(MenuComponent menu) {
//        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public Iterator<MenuComponent> iterator() {
//        throw new UnsupportedOperationException("Not supported yet.");
        return null;
    }
}


问题是当我启动应用程序时子菜单没有显示,在这个测试示例中,我只能看到打开菜单和退出菜单。我可以使用复合图案的变体吗?

2 个答案:

答案 0 :(得分:1)

当然你的子菜单没有显示。以下循环

while (iterator.hasNext()) {
  MenuComponent menuComponent = iterator.next();
  JMenuItem item = new JMenuItem(menuComponent.getName());
  popupMenu.add(item);
}

只有一个深度。您不会考虑变量menuComponent也具有非空Iterator的情况。

答案 1 :(得分:0)

我使用2个单独的方法让它工作,但如果有人有更好的我总是接受它。
例如,只使用一种方法,因为两种方法几乎完全相同。

          public class MenuBar extends JComponent {

            public MenuBar() {
                setLayout(new FlowLayout(FlowLayout.LEFT, 2, 2));

            }

            void addMainMenu(MenuComponent mainMenu) {
                JButton btn = new JButton(mainMenu.getName());
                final JPopupMenu popupMenu = new JPopupMenu();
                addPopupMenus(mainMenu);
                btn.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        JButton btn = (JButton) e.getSource();
                        popupMenu.show(e.getComponent(), e.getX(), e.getY());
                    }
                });
                add(btn);
            }

    private void addPopupMenus(final MenuComponent menu) {
                final Iterator<MenuComponent> iterator = menu.iterator();
                JMenuItem main;
                while (iterator.hasNext()) {
                    final MenuComponent abstractMenu = iterator.next();
                    if (abstractMenu.iterator().hasNext()) {
                        main = new JMenu(abstractMenu.getMenuName());
                    } else {
                        main = new JMenuItem(abstractMenu.getMenuName());
                    }
                    addPopupMenus(abstractMenu, main);
                    popupMenu.add(main);
                }
            }

            private void addPopupMenus(MenuComponent menu, JMenuItem jMenuItem) {
                final Iterator<MenuComponent> iterator = menu.iterator();
                JMenuItem main;
                while (iterator.hasNext()) {
                    final MenuComponent abstractMenu = iterator.next();
                    if (abstractMenu.iterator().hasNext()) {
                        main = new JMenu(abstractMenu.getMenuName());
                        addPopupMenus(abstractMenu, main);
                    } else {
                        main = new JMenuItem(abstractMenu.getMenuName());
                    }
                    jMenuItem.add(main);
                }
            }
        }

    }
}