001 // GraphLab Project: http://graphlab.sharif.edu 002 // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology 003 // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/ 004 package graphlab.ui.components.gmenu; 005 006 import javax.swing.*; 007 import java.awt.*; 008 import java.util.Arrays; 009 import java.util.Comparator; 010 import java.util.HashMap; 011 import java.util.StringTokenizer; 012 013 /** 014 * this class is the menu bar of GFrame. it has a difference with JMenuBar which is, if you add 2 menu bars with the 015 * same name, they will be put in one bar. 016 * 017 * @author root 018 */ 019 public class GMenuBar extends javax.swing.JMenuBar { 020 /** 021 * 022 */ 023 private static final long serialVersionUID = 2020939077780205134L; 024 private HashMap<String, JMenu> menues = new HashMap<String, JMenu>(); 025 026 public GMenuBar() { 027 // setBackground(new Color(245,245,255)); 028 // setBorder(new EmptyBorder(0,0,0,0)); 029 } 030 031 /** 032 * stores the places given for components 033 */ 034 private static HashMap<Component, Integer> componentPlaces = new HashMap<Component, Integer>(); 035 036 /** 037 * inserts the child to parent with the given places, 038 * it doesn't forget the place in the next times that you want to insert another childs 039 * with another places 040 */ 041 public static Component insert(JMenu parent, Component child, int place) { 042 place = checkPlaceValue(place, child); 043 int n = parent.getMenuComponentCount(); 044 Component[] items = new Component[n + 1]; 045 Component[] c = parent.getMenuComponents(); 046 System.arraycopy(c, 0, items, 0, n); 047 items[items.length - 1] = child; 048 sortPlacedComponents(items); 049 parent.removeAll(); 050 for (int i = 0; i < items.length; i++) { 051 parent.add(items[i], -1); 052 } 053 return child; 054 // return 055 } 056 057 private static Component insert(JMenuBar parent, Component child, int place) { 058 place = checkPlaceValue(place, child); 059 int n = parent.getMenuCount(); 060 Component[] items = new Component[n + 1]; 061 MenuElement[] c = parent.getSubElements(); 062 System.arraycopy(c, 0, items, 0, n); 063 items[items.length - 1] = child; 064 sortPlacedComponents(items); 065 parent.removeAll(); 066 for (int i = 0; i < items.length; i++) { 067 parent.add(items[i], -1); 068 } 069 return child; 070 // return 071 } 072 073 private static int checkPlaceValue(int place, Component child) { 074 if (place == -1) { 075 if (componentPlaces.containsKey(child)) 076 place = componentPlaces.get(child); //it has given a place before 077 else 078 place = 1000; 079 } 080 componentPlaces.put(child, place); 081 return place; 082 } 083 084 private static void sortPlacedComponents(Component[] items) { 085 Arrays.sort(items, new Comparator<Component>() { 086 public int compare(Component o1, Component o2) { 087 if (componentPlaces.containsKey(o1) && componentPlaces.containsKey(o2)) { 088 return componentPlaces.get(o1) - componentPlaces.get(o2); 089 } 090 return 1; 091 } 092 }); 093 } 094 095 /** 096 * returns a new JMenu with the given label that added to this menu bar 097 * if there was created a menu with the same label before, the old menu 098 * will be returned and no new menu will be created 099 */ 100 private JMenu requestMenu(String label) { 101 JMenu jm = menues.get(label); 102 if (jm == null) { 103 JMenu ret = new JMenu(label); 104 menues.put(label, ret); 105 add(ret); 106 // validate(); 107 return ret; 108 } else 109 return jm; 110 } 111 112 /** 113 * generates a menu from the given path, the path delimiter is "." , so this means 114 * a path in a tree, for example file.generate.star means a 3 layer menu. 115 * it doesn't create duplicate menues if you request it twice the same menu 116 * it just return the privious one,... 117 * <p/> 118 * it is suggested to ONLY use this method for creating sub menues 119 * <p/> 120 * if you have no idea on place just take it -1 , (in this case it normally sets it to 1000, but if it was given some value to it before it takes the older value) 121 * <p/> 122 * if some place was given for path before, the older value will discarded. 123 */ 124 public JMenu getUniqueMenu(String path, int place) { 125 StringTokenizer s = new StringTokenizer(path, "."); 126 // Scanner s = new Scanner(mname); 127 // s.useDelimiter("."); 128 if (!path.contains(".")) { //if it is only a first level menu 129 JMenu ret = requestMenu(path); 130 insert(this, ret, place); 131 return ret; 132 133 } //other wise we have more things to do ... 134 JMenu mnu = new JMenu("---"); 135 if (s.hasMoreTokens()) { 136 mnu = requestMenu(s.nextToken()); 137 boolean dontSearch_YouCantFindIt = false; 138 while (s.hasMoreTokens()) { //each token is a level in menu tree 139 String ss = s.nextToken(); 140 JMenu _mnu = null; 141 if (!dontSearch_YouCantFindIt) { //try to find the next level of the menu 142 for (int i = 0; i < mnu.getMenuComponentCount(); i++) { 143 Component menuComponent = mnu.getMenuComponent(i); 144 if (menuComponent instanceof JMenu) { 145 JMenu _ = (JMenu) menuComponent; 146 if (_.getText().equals(ss)) { 147 _mnu = _; 148 break; //:D it is found 149 } 150 } 151 } 152 } 153 if (_mnu == null) { // if it is not found 154 _mnu = new JMenu(ss); 155 dontSearch_YouCantFindIt = true; //the next levels are also can't be found, so don;t search for them 156 //so create the next levels 157 if (s.hasMoreTokens()) mnu.add(_mnu); 158 else 159 insert(mnu, _mnu, place); //the given place applied to last level. 160 } else if (!s.hasMoreTokens()) 161 insert(mnu, _mnu, place); //the given place applied to last level. 162 163 // else { 164 // } 165 mnu = _mnu; 166 } 167 } 168 return mnu; 169 170 } 171 } 172 // for (int i = 1; i < items.length - 1; i++) { 173 // if (items[i] == child) { 174 // int rightPlace = componentPlaces.get(items[i + 1]); 175 // int leftPlace = componentPlaces.get(items[i - 1]); 176 // componentPlaces.put(child, (rightPlace + leftPlace) / 2); 177 // found = true; 178 // } 179 // ; 180 // } 181 // if (!found){ //it was at item[0] or at the end 182 // if (items[0]==child){ 183 // componentPlaces.put(child,componentPlaces.get(items[2])/2); 184 // } 185 // if (items[items.length-1]==child){ 186 // componentPlaces.put(child,componentPlaces.get(items[items.length-1])+10); 187 // } 188 // } 189 // 190 //