1 7 package javax.swing; 8 9 import java.awt.*; 10 import java.util.*; 11 import java.awt.event.*; 12 import javax.swing.event.*; 13 14 20 public class MenuSelectionManager { 21 private static final MenuSelectionManager instance = 22 new MenuSelectionManager (); 23 24 private Vector selection = new Vector(); 25 26 27 private static final boolean TRACE = false; private static final boolean VERBOSE = false; private static final boolean DEBUG = false; 31 36 public static MenuSelectionManager defaultManager() { 37 return instance; 38 } 39 40 45 protected transient ChangeEvent changeEvent = null; 46 protected EventListenerList listenerList = new EventListenerList(); 47 48 59 public void setSelectedPath(MenuElement [] path) { 60 int i,c; 61 int currentSelectionCount = selection.size(); 62 int firstDifference = 0; 63 64 if(path == null) { 65 path = new MenuElement [0]; 66 } 67 68 if (DEBUG) { 69 System.out.print("Previous: "); printMenuElementArray(getSelectedPath()); 70 System.out.print("New: "); printMenuElementArray(path); 71 } 72 73 for(i=0,c=path.length;i<c;i++) { 74 if(i < currentSelectionCount && (MenuElement )selection.elementAt(i) == path[i]) 75 firstDifference++; 76 else 77 break; 78 } 79 80 for(i=currentSelectionCount - 1 ; i >= firstDifference ; i--) { 81 MenuElement me = (MenuElement )selection.elementAt(i); 82 selection.removeElementAt(i); 83 me.menuSelectionChanged(false); 84 } 85 86 for(i = firstDifference, c = path.length ; i < c ; i++) { 87 if (path[i] != null) { 88 selection.addElement(path[i]); 89 path[i].menuSelectionChanged(true); 90 } 91 } 92 93 fireStateChanged(); 94 } 95 96 101 public MenuElement [] getSelectedPath() { 102 MenuElement res[] = new MenuElement [selection.size()]; 103 int i,c; 104 for(i=0,c=selection.size();i<c;i++) 105 res[i] = (MenuElement ) selection.elementAt(i); 106 return res; 107 } 108 109 113 public void clearSelectedPath() { 114 if (selection.size() > 0) { 115 setSelectedPath(null); 116 } 117 } 118 119 124 public void addChangeListener(ChangeListener l) { 125 listenerList.add(ChangeListener.class, l); 126 } 127 128 133 public void removeChangeListener(ChangeListener l) { 134 listenerList.remove(ChangeListener.class, l); 135 } 136 137 145 public ChangeListener[] getChangeListeners() { 146 return (ChangeListener[])listenerList.getListeners( 147 ChangeListener.class); 148 } 149 150 157 protected void fireStateChanged() { 158 Object [] listeners = listenerList.getListenerList(); 160 for (int i = listeners.length-2; i>=0; i-=2) { 163 if (listeners[i]==ChangeListener.class) { 164 if (changeEvent == null) 166 changeEvent = new ChangeEvent(this); 167 ((ChangeListener)listeners[i+1]).stateChanged(changeEvent); 168 } 169 } 170 } 171 172 178 public void processMouseEvent(MouseEvent event) { 179 int screenX,screenY; 180 Point p; 181 int i,c,j,d; 182 Component mc; 183 Rectangle r2; 184 int cWidth,cHeight; 185 MenuElement menuElement; 186 MenuElement subElements[]; 187 MenuElement path[]; 188 Vector tmp; 189 int selectionSize; 190 p = event.getPoint(); 191 192 Component source = (Component)event.getSource(); 193 194 if (!source.isShowing()) { 195 return; 198 } 199 200 int type = event.getID(); 201 int modifiers = event.getModifiers(); 202 if ((type==MouseEvent.MOUSE_ENTERED|| 204 type==MouseEvent.MOUSE_EXITED) 205 && ((modifiers & (InputEvent.BUTTON1_MASK | 206 InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) !=0 )) { 207 return; 208 } 209 210 SwingUtilities.convertPointToScreen(p,source); 211 212 screenX = p.x; 213 screenY = p.y; 214 215 tmp = (Vector)selection.clone(); 216 selectionSize = tmp.size(); 217 boolean success = false; 218 for (i=selectionSize - 1;i >= 0 && success == false; i--) { 219 menuElement = (MenuElement ) tmp.elementAt(i); 220 subElements = menuElement.getSubElements(); 221 222 path = null; 223 for (j = 0, d = subElements.length;j < d && success == false; j++) { 224 if (subElements[j] == null) 225 continue; 226 mc = subElements[j].getComponent(); 227 if(!mc.isShowing()) 228 continue; 229 if(mc instanceof JComponent ) { 230 cWidth = ((JComponent )mc).getWidth(); 231 cHeight = ((JComponent )mc).getHeight(); 232 } else { 233 r2 = mc.getBounds(); 234 cWidth = r2.width; 235 cHeight = r2.height; 236 } 237 p.x = screenX; 238 p.y = screenY; 239 SwingUtilities.convertPointFromScreen(p,mc); 240 241 244 if( 245 (p.x >= 0 && p.x < cWidth && p.y >= 0 && p.y < cHeight)) { 246 int k; 247 if(path == null) { 248 path = new MenuElement [i+2]; 249 for(k=0;k<=i;k++) 250 path[k] = (MenuElement )tmp.elementAt(k); 251 } 252 path[i+1] = subElements[j]; 253 MenuElement currentSelection[] = getSelectedPath(); 254 255 if (currentSelection[currentSelection.length-1] != 257 path[i+1] && 258 (currentSelection.length < 2 || 259 currentSelection[currentSelection.length-2] != 260 path[i+1])) { 261 Component oldMC = currentSelection[currentSelection.length-1].getComponent(); 262 263 MouseEvent exitEvent = new MouseEvent(oldMC, MouseEvent.MOUSE_EXITED, 264 event.getWhen(), 265 event.getModifiers(), p.x, p.y, 266 event.getClickCount(), 267 event.isPopupTrigger()); 268 currentSelection[currentSelection.length-1]. 269 processMouseEvent(exitEvent, path, this); 270 271 MouseEvent enterEvent = new MouseEvent(mc, 272 MouseEvent.MOUSE_ENTERED, 273 event.getWhen(), 274 event.getModifiers(), p.x, p.y, 275 event.getClickCount(), 276 event.isPopupTrigger()); 277 subElements[j].processMouseEvent(enterEvent, path, this); 278 } 279 MouseEvent mouseEvent = new MouseEvent(mc, event.getID(),event. getWhen(), 280 event.getModifiers(), p.x, p.y, 281 event.getClickCount(), 282 event.isPopupTrigger()); 283 subElements[j].processMouseEvent(mouseEvent, path, this); 284 success = true; 285 event.consume(); 286 } 287 } 288 } 289 } 290 291 private void printMenuElementArray(MenuElement path[]) { 292 printMenuElementArray(path, false); 293 } 294 295 private void printMenuElementArray(MenuElement path[], boolean dumpStack) { 296 System.out.println("Path is("); 297 int i, j; 298 for(i=0,j=path.length; i<j ;i++){ 299 for (int k=0; k<=i; k++) 300 System.out.print(" "); 301 MenuElement me = (MenuElement ) path[i]; 302 if(me instanceof JMenuItem ) { 303 System.out.println(((JMenuItem )me).getText() + ", "); 304 } else if (me instanceof JMenuBar ) { 305 System.out.println("JMenuBar, "); 306 } else if(me instanceof JPopupMenu ) { 307 System.out.println("JPopupMenu, "); 308 } else if (me == null) { 309 System.out.println("NULL , "); 310 } else { 311 System.out.println("" + me + ", "); 312 } 313 } 314 System.out.println(")"); 315 316 if (dumpStack == true) 317 Thread.dumpStack(); 318 } 319 320 332 public Component componentForPoint(Component source, Point sourcePoint) { 333 int screenX,screenY; 334 Point p = sourcePoint; 335 int i,c,j,d; 336 Component mc; 337 Rectangle r2; 338 int cWidth,cHeight; 339 MenuElement menuElement; 340 MenuElement subElements[]; 341 Vector tmp; 342 int selectionSize; 343 344 SwingUtilities.convertPointToScreen(p,source); 345 346 screenX = p.x; 347 screenY = p.y; 348 349 tmp = (Vector)selection.clone(); 350 selectionSize = tmp.size(); 351 for(i=selectionSize - 1 ; i >= 0 ; i--) { 352 menuElement = (MenuElement ) tmp.elementAt(i); 353 subElements = menuElement.getSubElements(); 354 355 for(j = 0, d = subElements.length ; j < d ; j++) { 356 if (subElements[j] == null) 357 continue; 358 mc = subElements[j].getComponent(); 359 if(!mc.isShowing()) 360 continue; 361 if(mc instanceof JComponent ) { 362 cWidth = ((JComponent )mc).getWidth(); 363 cHeight = ((JComponent )mc).getHeight(); 364 } else { 365 r2 = mc.getBounds(); 366 cWidth = r2.width; 367 cHeight = r2.height; 368 } 369 p.x = screenX; 370 p.y = screenY; 371 SwingUtilities.convertPointFromScreen(p,mc); 372 373 376 if (p.x >= 0 && p.x < cWidth && p.y >= 0 && p.y < cHeight) { 377 return mc; 378 } 379 } 380 } 381 return null; 382 } 383 384 390 public void processKeyEvent(KeyEvent e) { 391 MenuElement [] sel2 = new MenuElement [0]; 392 sel2 = (MenuElement [])selection.toArray(sel2); 393 int selSize = sel2.length; 394 MenuElement [] path; 395 396 if (selSize < 1) { 397 return; 398 } 399 400 for (int i=selSize-1; i>=0; i--) { 401 MenuElement elem = sel2[i]; 402 MenuElement [] subs = elem.getSubElements(); 403 path = null; 404 405 for (int j=0; j<subs.length; j++) { 406 if (subs[j] == null || !subs[j].getComponent().isShowing() 407 || !subs[j].getComponent().isEnabled()) { 408 continue; 409 } 410 411 if(path == null) { 412 path = new MenuElement [i+2]; 413 System.arraycopy(sel2, 0, path, 0, i+1); 414 } 415 path[i+1] = subs[j]; 416 subs[j].processKeyEvent(e, path, this); 417 if (e.isConsumed()) { 418 return; 419 } 420 } 421 } 422 423 path = new MenuElement [1]; 425 path[0] = sel2[0]; 426 path[0].processKeyEvent(e, path, this); 427 if (e.isConsumed()) { 428 return; 429 } 430 } 431 432 435 public boolean isComponentPartOfCurrentMenu(Component c) { 436 if(selection.size() > 0) { 437 MenuElement me = (MenuElement )selection.elementAt(0); 438 return isComponentPartOfCurrentMenu(me,c); 439 } else 440 return false; 441 } 442 443 private boolean isComponentPartOfCurrentMenu(MenuElement root,Component c) { 444 MenuElement children[]; 445 int i,d; 446 447 if (root == null) 448 return false; 449 450 if(root.getComponent() == c) 451 return true; 452 else { 453 children = root.getSubElements(); 454 for(i=0,d=children.length;i<d;i++) { 455 if(isComponentPartOfCurrentMenu(children[i],c)) 456 return true; 457 } 458 } 459 return false; 460 } 461 } 462 463 464 | Popular Tags |