Dmytro Kovalchuk avatar Dmytro Kovalchuk committed 3818692 Draft

Refactorings of menu service

Comments (0)

Files changed (6)

swing-api/src/main/java/net/anatolich/cstitch/ui/menu/MenuChangeListener.java

+/*
+ * Copyright 2012 Anatolich <anatolich@anatolich.net>.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package net.anatolich.cstitch.ui.menu;
+
+/**
+ *
+ * @author Anatolich <anatolich@anatolich.net>
+ */
+public interface MenuChangeListener {
+    
+}

swing-api/src/main/java/net/anatolich/cstitch/ui/menu/MenuService.java

 import java.util.List;
 import javax.swing.AbstractAction;
 import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
 
 /**
  * Creates application main menu.
     
     void registerMenuItem(String path, AbstractAction action, int position);
     
-    void registerCheckboxMenuItem(String path, String group, AbstractAction item, int position);
+    void registerCheckboxMenuItem(String path, AbstractAction item, int position);
     
     void registerRadioMenuItem(String path, String group, AbstractAction item, int position);
-    
-    /**
-     * Gets menu item associated with provided path.
-     * @param path
-     * @return menu item or null if no menu item is associated with this path.
-     */
-    <T extends JMenuItem> T getMenuItem(String path);
 
     /**
      * Gets list of top-level menus. Modification of returned list must not change
      * actual list of menus.
      * @return 
      */
-    public List<JMenu> getMenus();
+    List<JMenu> getMenus();
+    
+    void removeMenuItem(String path);
+    
+    void addMenuChangeListener(MenuChangeListener listener);
+    
+    void removeMenuChangeListener(MenuChangeListener listener);
     
 }

swing-api/src/main/java/net/anatolich/cstitch/ui/menu/impl/MenuServiceImpl.java

 package net.anatolich.cstitch.ui.menu.impl;
 
 import java.util.ArrayList;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 import javax.swing.*;
+import net.anatolich.cstitch.ui.menu.MenuChangeListener;
 import net.anatolich.cstitch.ui.menu.MenuService;
 
 /**
 public class MenuServiceImpl implements MenuService {
 
     private final MenuTree menuTree;
+    private final Map<String, ButtonGroup> buttonGroups;
 
     public MenuServiceImpl() {
         menuTree = new MenuTree();
+        buttonGroups = new HashMap<>();
     }
 
     @Override
     public void registerMenu(String path, String name, int position) {
-        createNode(new JMenu(name), position, path, null);
+        createNode(new JMenu(name), position, path);
     }
 
     @Override
     public void registerMenuItem(String path, AbstractAction action, int position) {
-        createNode(new JMenuItem(action), position, path, null);
+        createNode(new JMenuItem(action), position, path);
     }
 
     @Override
-    public void registerCheckboxMenuItem(String path, String group, AbstractAction action, int position) {
-        createNode(new JCheckBoxMenuItem(action), position, path, group);
+    public void registerCheckboxMenuItem(String path, AbstractAction action, int position) {
+        createNode(new JCheckBoxMenuItem(action), position, path);
     }
 
     @Override
         createNode(new JRadioButtonMenuItem(action), position, path, group);
     }
 
-    private void createNode(JMenuItem item, int position, String path, String group) {
-        MenuTreeNode node = new MenuTreeNode();
-        node.setItem(item);
-        node.setPosition(position);
-        if (group != null) {
-            node.setGroup(group);
+    private void createNode(JMenuItem item, int position, String path, String groupName) {
+        MenuTreeNode node = new MenuTreeNode(item, position);
+        
+        if (groupName != null) {
+            getOrCreateButtonGroup(groupName).add(item);
         }
-        menuTree.addNode(path, node);
+        
+        menuTree.addNode(path, position, node);        
+        
     }
-
-    @Override
-    public JMenuItem getMenuItem(String path) {
-        final MenuTreeNode node = menuTree.getNode(path);
-        if (node != null) {
-            return node.getItem();
-        }
-        return null;
+    
+    private void createNode(JMenuItem item, int position, String path) {
+        createNode(item, position, path, null);
+        
     }
 
     @Override
 
         return menus;
     }
+
+    @Override
+    public void removeMenuItem(String path) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void addMenuChangeListener(MenuChangeListener listener) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    @Override
+    public void removeMenuChangeListener(MenuChangeListener listener) {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    ButtonGroup getButtonGroup(String name) {
+        return buttonGroups.get(name);
+    }
+
+    private ButtonGroup getOrCreateButtonGroup(String group) {
+        if(buttonGroups.containsKey(group)){
+            return buttonGroups.get(group);
+        }
+        
+        final ButtonGroup buttonGroup = new ButtonGroup();
+        
+        buttonGroups.put(group, buttonGroup);
+        return buttonGroup;
+    }
 }

swing-api/src/main/java/net/anatolich/cstitch/ui/menu/impl/MenuTree.java

  */
 package net.anatolich.cstitch.ui.menu.impl;
 
-import java.util.*;
-import javax.swing.ButtonGroup;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+import javax.swing.JMenu;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 
     private static final Logger log = LoggerFactory.getLogger(MenuTree.class);
     private final MenuTreeNode root;
-    private final Map<String, ButtonGroup> groups;
 
     public MenuTree() {
         root = new MenuTreeNode();
-        groups = new HashMap<>();
     }
 
-    public void addNode(String path, MenuTreeNode node) {
+    public void addNode(String path, int position, MenuTreeNode node) {
         log.debug(String.format("Adding menu %1$s", path));
         log.debug("Parsing path");
 
         MenuTreeNode parentNode = root;
         List<String> pathSteps = Arrays.asList(path.split("/"));
         Iterator<String> pathIterator = pathSteps.iterator();
+        
         while (pathIterator.hasNext()) {
             String step = pathIterator.next();
 
             if (pathIterator.hasNext()) {
                 log.debug(String.format("Processing step %1$s", step));
-                MenuTreeNode stepNode = parentNode.getOrCreateChild(step);
+                MenuTreeNode stepNode = parentNode.getChild(step);
+                if (stepNode == null){
+                    stepNode = new MenuTreeNode(new JMenu(step), position, step);
+                    parentNode.addChild(stepNode, position);
+                }
                 parentNode = stepNode;
-            } else {
-                node.setId(step);
-                parentNode.addChild(node);
+            } else {                
+                node.setName(step);
+                parentNode.addChild(node, position);
             }
         }
 
     }
 
-    private JMenuItem traverseNode(MenuTreeNode node) {
-        JMenuItem menuItem = node.getItem();
-        if (node.getGroup() != null) {
-            log.debug(String.format("Adding node to group %1$s", node.getGroup()));
-            ButtonGroup group = getOrCreateGroup(node.getGroup());
-            group.add(node.getItem());
-        }
-        for (MenuTreeNode menuTreeNode : node.getChildren()) {
-            menuItem.add(traverseNode(menuTreeNode));
-        }
-        return menuItem;
-    }
-
-    private ButtonGroup getOrCreateGroup(String groupName) {
-        ButtonGroup group = groups.get(groupName);
-        if (group == null) {
-            log.debug(String.format("Creating group %1$s", groupName));
-            group = new ButtonGroup();
-            groups.put(groupName, group);
-        }
-        return group;
-    }
-
     MenuTreeNode getRootNode() {
         return root;
     }

swing-api/src/main/java/net/anatolich/cstitch/ui/menu/impl/MenuTreeNode.java

  *
  * @author Anatolich <anatolich@anatolich.net>
  */
-class MenuTreeNode implements Comparable<MenuTreeNode> {
+final class MenuTreeNode implements Comparable<MenuTreeNode> {
 
     private static final Logger log = LoggerFactory.getLogger(MenuTreeNode.class);
+    
     private JMenuItem item;
     private MenuTreeNode parent;
     private List<MenuTreeNode> children;
     private int position;
-    private String path;
-    private String id;
-    private String group;
+    private String name;
 
     public MenuTreeNode() {
         children = new ArrayList<>();
     }
 
+    public MenuTreeNode(JMenuItem item, int position) {
+        this();
+        this.item = item;
+        this.position = position;
+    }
+
+    public MenuTreeNode(JMenuItem item, int position, String name) {
+        this();
+        this.item = item;
+        this.position = position;
+        this.name = name;
+    }
+    
+    
+
     public List<MenuTreeNode> getChildren() {
         return children;
     }
         this.children = children;
     }
 
-    public String getId() {
-        return id;
+    public String getName() {
+        return name;
     }
 
-    public void setId(String id) {
-        this.id = id;
+    public void setName(String name) {
+        this.name = name;
     }
 
     public JMenuItem getItem() {
         this.parent = parent;
     }
 
-    public String getPath() {
-        return path;
-    }
-
-    public void setPath(String path) {
-        this.path = path;
-    }
-
     public int getPosition() {
         return position;
     }
         this.position = position;
     }
 
-    public String getGroup() {
-        return group;
-    }
-
-    public void setGroup(String group) {
-        this.group = group;
-    }
-
     /**
      * Gets named child of current node.
      *
-     * @param id
+     * @param name
      * @return instance of MenuTreeNode or null if no item exists.
      */
-    public MenuTreeNode getChild(String id) {
+    public MenuTreeNode getChild(String name) {
         for (MenuTreeNode menuTreeNode : children) {
-            if (menuTreeNode.getId().equals(id)) {
+            if (menuTreeNode.getName().equals(name)) {
                 return menuTreeNode;
             }
         }
         return null;
     }
 
-    public MenuTreeNode getOrCreateChild(String id) {
-        log.debug(String.format("Searching for node %1$s", id));
-        
-        MenuTreeNode child = getChild(id);
-        if (child != null) {
-            return child;
+    void addChild(MenuTreeNode node, int nodePosition) {
+        log.debug(String.format("Adding new child %1$s", node));
+        children.add(node);
+        node.setParent(this);
+        Collections.sort(children);
+
+        if (item != null) {
+            item.add(node.getItem(), children.indexOf(node));
         }
 
-        log.debug("Node not found. Creating new one");
-        MenuTreeNode newChildNode = new MenuTreeNode();
-        newChildNode.setId(id);
-        newChildNode.setParent(this);
-        newChildNode.setItem(new JMenu(id));
-        children.add(newChildNode);
-        return newChildNode;
-    }
-
-    void addChild(MenuTreeNode node) {
-        log.debug(String.format("Adding new child %1$s", node));
-        MenuTreeNode child = getOrCreateChild(node.id);
-        
-        child.setId(node.getId());
-        child.setItem(node.getItem());
-        child.setGroup(node.getGroup());
-        child.setPosition(node.getPosition());
-        child.setChildren(new ArrayList<MenuTreeNode>());
-        Collections.sort(children);
-        
-        if(item != null){
-            item.add(node.getItem());
-        }
-        
     }
 
     @Override
     public String toString() {
-        return "MenuTreeNode{" + "item=" + item + ", parent=" + parent + ", children=" + children + ", position=" + position + ", path=" + path + ", id=" + id + '}';
+        return "MenuTreeNode{" + "item=" + item + ", position=" + position + ", id=" + name + '}';
     }
 
     @Override
     public int compareTo(MenuTreeNode o) {
         final int comparation = position - o.position;
         if (comparation == 0) {
-            return id.compareTo(o.id);
+            return name.compareTo(o.name);
         }
         return comparation;
     }

swing-api/src/test/java/net/anatolich/cstitch/ui/menu/impl/MenuServiceImplTest.java

 package net.anatolich.cstitch.ui.menu.impl;
 
 import java.awt.event.ActionEvent;
+import java.util.List;
 import javax.swing.AbstractAction;
+import javax.swing.ButtonGroup;
 import javax.swing.JMenu;
-import javax.swing.JMenuBar;
 import javax.swing.JMenuItem;
 import static org.junit.Assert.*;
 import org.junit.Before;
         
         menuManagerImpl.registerMenu(path, itemTitle, position);
         
-        JMenuItem fileMenu = menuManagerImpl.getMenuItem(path);
+        JMenuItem fileMenu = menuManagerImpl.getMenus().get(0);
         assertEquals(itemTitle, fileMenu.getText());
     }
     
         
         menuManagerImpl.registerMenuItem(path, saveAction, position);
         
-        JMenuItem fileMenu = menuManagerImpl.getMenuItem("File");
+        JMenu fileMenu = menuManagerImpl.getMenus().get(0);
         
         assertEquals("File", fileMenu.getText());
         
-        JMenuItem fileSaveItem = menuManagerImpl.getMenuItem(path);
+        JMenuItem fileSaveItem = fileMenu.getItem(0);
         
         assertEquals(itemTitle, fileSaveItem.getText());
     }
         menuManagerImpl.registerMenuItem("A2/A2", new EmptyAction("A2"), 0);
         
         assertEquals(2, menuManagerImpl.getMenus().size());
+        JMenu a1Menu = menuManagerImpl.getMenus().get(0);
+        JMenu a2Menu = menuManagerImpl.getMenus().get(1);
         
-        assertEquals("A1", menuManagerImpl.getMenuItem("A1/A1").getText());
-        assertEquals("A2", menuManagerImpl.getMenuItem("A2/A2").getText());
+        assertEquals("A1", a1Menu.getItem(0).getText());
+        assertEquals("A2", a2Menu.getItem(0).getText());
     }
     
     @Test
         menuManagerImpl.registerMenuItem("A2/A2", new EmptyAction("A2A2"), 20);
         menuManagerImpl.registerMenuItem("A2/A1", new EmptyAction("A2A1"), 10);
         
-        assertEquals(2, menuManagerImpl.getMenus().size());
-        
-        final JMenu menuA1 = (JMenu) menuManagerImpl.getMenuItem("A1");
-        final JMenu menuA2 = (JMenu) menuManagerImpl.getMenuItem("A2");
-        
-        assertEquals("A1", menuA1.getText());
-        assertEquals("A2", menuA2.getText());
-        
-        final JMenuItem a1a1 = menuManagerImpl.getMenuItem("A1/A1");        
-        assertEquals("A1A1", a1a1.getText());
-        
-        final JMenuItem a2a1 = menuManagerImpl.getMenuItem("A2/A1");        
-        assertEquals("A2A1", a2a1.getText());
-        
-        final JMenuItem a2a2 = menuManagerImpl.getMenuItem("A2/A2");
-        assertEquals("A2A2", a2a2.getText());
+        checkThreeItems(menuManagerImpl.getMenus());
         
     }
+
     
     @Test
     public void testAddThreeRadioItems(){
         menuManagerImpl.registerRadioMenuItem("A2/A2", "A2G", new EmptyAction("A2A2"), 20);
         menuManagerImpl.registerRadioMenuItem("A2/A1", "A2G", new EmptyAction("A2A1"), 10);
         
-        assertEquals(2, menuManagerImpl.getMenus().size());
+        checkThreeItems(menuManagerImpl.getMenus());
         
-        final JMenu menuA1 = (JMenu) menuManagerImpl.getMenuItem("A1");
-        final JMenu menuA2 = (JMenu) menuManagerImpl.getMenuItem("A2");
+    }
+    
+       
+    @Test
+    public void testButtonGroups(){
+        menuManagerImpl.registerRadioMenuItem("A1/A1", "A1G", new EmptyAction("A1A1"), 10);
         
-        assertEquals("A1", menuA1.getText());
-        assertEquals("A2", menuA2.getText());
+        ButtonGroup a1g = menuManagerImpl.getButtonGroup("A1G");
         
-        final JMenuItem a1a1 = menuManagerImpl.getMenuItem("A1/A1");        
-        assertEquals("A1A1", a1a1.getText());
-        
-        final JMenuItem a2a1 = menuManagerImpl.getMenuItem("A2/A1");        
-        assertEquals("A2A1", a2a1.getText());
-        
-        final JMenuItem a2a2 = menuManagerImpl.getMenuItem("A2/A2");
-        assertEquals("A2A2", a2a2.getText());
-        
+        assertEquals(1, a1g.getButtonCount());
     }
     
     @Test
     public void testGetMenuItem(){
         menuManagerImpl.registerMenuItem("A1/A1", new EmptyAction("A1A1"), 10);
         
-        final JMenuItem a1 = menuManagerImpl.getMenuItem("A1");
+        final JMenu a1 = menuManagerImpl.getMenus().get(0);
         
         assertNotNull(a1);
-        assertTrue(a1 instanceof JMenu);
         assertEquals("A1", a1.getText());
         
-        final JMenuItem a1a1 = menuManagerImpl.getMenuItem("A1/A1");
+        final JMenuItem a1a1 = a1.getItem(0);
         assertNotNull(a1a1);
         assertEquals("A1A1", a1a1.getText());
         
-        assertNull(menuManagerImpl.getMenuItem("A1/A1/A1"));
+        assertEquals(0, a1a1.getSubElements().length);
         
     }
+    
+    private void checkThreeItems(final List<JMenu> menus) {
+        assertEquals(2, menus.size());
+        
+        final JMenu menuA1 = (JMenu) menus.get(0);
+        final JMenu menuA2 = (JMenu) menus.get(1);
+        
+        assertEquals("A1", menuA1.getText());
+        assertEquals("A2", menuA2.getText());
+        
+        final JMenuItem a1a1 = menuA1.getItem(0);
+        assertEquals("A1A1", a1a1.getText());
+        
+        final JMenuItem a2a1 = menuA2.getItem(0);
+        assertEquals("A2A1", a2a1.getText());
+        
+        final JMenuItem a2a2 = menuA2.getItem(1);
+        assertEquals("A2A2", a2a2.getText());
+    }
 
     private class EmptyAction extends AbstractAction {
 
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.