我正在尝试复合模式以创建菜单栏
这是代码:
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;
}
}
问题是当我启动应用程序时子菜单没有显示,在这个测试示例中,我只能看到打开菜单和退出菜单。我可以使用复合图案的变体吗?
答案 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);
}
}
}
}
}