313 XMenuPeer getShowingSubmenu() {
314 synchronized(getMenuTreeLock()) {
315 return showingSubmenu;
316 }
317 }
318
319 /**
320 * Adds item to end of items vector.
321 * Note that this function does not perform
322 * check for adding duplicate items
323 * @param item item to add
324 */
325 public void addItem(MenuItem item) {
326 XMenuItemPeer mp = (XMenuItemPeer)item.getPeer();
327 if (mp != null) {
328 mp.setContainer(this);
329 synchronized(getMenuTreeLock()) {
330 items.add(mp);
331 }
332 } else {
333 if (log.isLoggable(PlatformLogger.FINE)) {
334 log.fine("WARNING: Attempt to add menu item without a peer");
335 }
336 }
337 updateSize();
338 }
339
340 /**
341 * Removes item at the specified index from items vector.
342 * @param index the position of the item to be removed
343 */
344 public void delItem(int index) {
345 synchronized(getMenuTreeLock()) {
346 if (selectedIndex == index) {
347 selectItem(null, false);
348 } else if (selectedIndex > index) {
349 selectedIndex--;
350 }
351 if (index < items.size()) {
352 items.remove(index);
353 } else {
354 if (log.isLoggable(PlatformLogger.FINE)) {
355 log.fine("WARNING: Attempt to remove non-existing menu item, index : " + index + ", item count : " + items.size());
356 }
357 }
358 }
359 updateSize();
360 }
361
362 /**
363 * Clears items vector and loads specified vector
364 * @param items vector to be loaded
365 */
366 public void reloadItems(Vector items) {
367 synchronized(getMenuTreeLock()) {
368 this.items.clear();
369 MenuItem[] itemArray = (MenuItem[])items.toArray(new MenuItem[] {});
370 int itemCnt = itemArray.length;
371 for(int i = 0; i < itemCnt; i++) {
372 addItem(itemArray[i]);
373 }
374 }
375 }
376
377 /**
378 * Select specified item and shows/hides submenus if necessary
379 * We can not select by index, so we need to select by ref.
380 * @param item the item to be selected, null to clear selection
381 * @param showWindowIfMenu if the item is XMenuPeer then its
382 * window is shown/hidden according to this param.
383 */
384 void selectItem(XMenuItemPeer item, boolean showWindowIfMenu) {
385 synchronized(getMenuTreeLock()) {
386 XMenuPeer showingSubmenu = getShowingSubmenu();
387 int newSelectedIndex = (item != null) ? items.indexOf(item) : -1;
388 if (this.selectedIndex != newSelectedIndex) {
389 if (log.isLoggable(PlatformLogger.FINEST)) {
390 log.finest("Selected index changed, was : " + this.selectedIndex + ", new : " + newSelectedIndex);
391 }
392 this.selectedIndex = newSelectedIndex;
393 postPaintEvent();
394 }
395 final XMenuPeer submenuToShow = (showWindowIfMenu && (item instanceof XMenuPeer)) ? (XMenuPeer)item : null;
396 if (submenuToShow != showingSubmenu) {
397 XToolkit.executeOnEventHandlerThread(target, new Runnable() {
398 public void run() {
399 doShowSubmenu(submenuToShow);
400 }
401 });
402 }
403 }
404 }
405
406 /**
407 * Performs hiding of currently showing submenu
408 * and showing of submenuToShow.
409 * This function should be executed on eventHandlerThread
410 * @param submenuToShow submenu to be shown or null
411 * to hide currently showing submenu
412 */
413 private void doShowSubmenu(XMenuPeer submenuToShow) {
414 XMenuWindow menuWindowToShow = (submenuToShow != null) ? submenuToShow.getMenuWindow() : null;
415 Dimension dim = null;
416 Rectangle bounds = null;
417 //ensureCreated can invoke XWindowPeer.init() ->
418 //XWindowPeer.initGraphicsConfiguration() ->
419 //Window.getGraphicsConfiguration()
420 //that tries to obtain Component.AWTTreeLock.
421 //So it should be called outside awtLock()
422 if (menuWindowToShow != null) {
423 menuWindowToShow.ensureCreated();
424 }
425 XToolkit.awtLock();
426 try {
427 synchronized(getMenuTreeLock()) {
428 if (showingSubmenu != submenuToShow) {
429 if (log.isLoggable(PlatformLogger.FINEST)) {
430 log.finest("Changing showing submenu");
431 }
432 if (showingSubmenu != null) {
433 XMenuWindow showingSubmenuWindow = showingSubmenu.getMenuWindow();
434 if (showingSubmenuWindow != null) {
435 showingSubmenuWindow.hide();
436 }
437 }
438 if (submenuToShow != null) {
439 dim = menuWindowToShow.getDesiredSize();
440 bounds = menuWindowToShow.getParentMenuWindow().getSubmenuBounds(submenuToShow.getBounds(), dim);
441 menuWindowToShow.show(bounds);
442 }
443 showingSubmenu = submenuToShow;
444 }
445 }
446 } finally {
447 XToolkit.awtUnlock();
448 }
449 }
1105 wnd.selectItem(null, false);
1106 }
1107 } else {
1108 //Mouse is dragged outside menu windows
1109 //clear selection in leaf to reflect it
1110 if (cwnd != null) {
1111 cwnd.selectItem(null, false);
1112 }
1113 }
1114 break;
1115 }
1116 }
1117
1118 /**
1119 * Performs handling of java keyboard event
1120 * Note that this function should be invoked
1121 * only from root of menu window's hierarchy
1122 * that grabs input focus
1123 */
1124 void doHandleJavaKeyEvent(KeyEvent event) {
1125 if (log.isLoggable(PlatformLogger.FINER)) {
1126 log.finer(event.toString());
1127 }
1128 if (event.getID() != KeyEvent.KEY_PRESSED) {
1129 return;
1130 }
1131 final int keyCode = event.getKeyCode();
1132 XBaseMenuWindow cwnd = getShowingLeaf();
1133 XMenuItemPeer citem = cwnd.getSelectedItem();
1134 switch(keyCode) {
1135 case KeyEvent.VK_UP:
1136 case KeyEvent.VK_KP_UP:
1137 if (!(cwnd instanceof XMenuBarPeer)) {
1138 //If active window is not menu bar,
1139 //move selection up
1140 cwnd.selectItem(cwnd.getPrevSelectableItem(), false);
1141 }
1142 break;
1143 case KeyEvent.VK_DOWN:
1144 case KeyEvent.VK_KP_DOWN:
1145 if (cwnd instanceof XMenuBarPeer) {
|
313 XMenuPeer getShowingSubmenu() {
314 synchronized(getMenuTreeLock()) {
315 return showingSubmenu;
316 }
317 }
318
319 /**
320 * Adds item to end of items vector.
321 * Note that this function does not perform
322 * check for adding duplicate items
323 * @param item item to add
324 */
325 public void addItem(MenuItem item) {
326 XMenuItemPeer mp = (XMenuItemPeer)item.getPeer();
327 if (mp != null) {
328 mp.setContainer(this);
329 synchronized(getMenuTreeLock()) {
330 items.add(mp);
331 }
332 } else {
333 if (log.isLoggable(PlatformLogger.Level.FINE)) {
334 log.fine("WARNING: Attempt to add menu item without a peer");
335 }
336 }
337 updateSize();
338 }
339
340 /**
341 * Removes item at the specified index from items vector.
342 * @param index the position of the item to be removed
343 */
344 public void delItem(int index) {
345 synchronized(getMenuTreeLock()) {
346 if (selectedIndex == index) {
347 selectItem(null, false);
348 } else if (selectedIndex > index) {
349 selectedIndex--;
350 }
351 if (index < items.size()) {
352 items.remove(index);
353 } else {
354 if (log.isLoggable(PlatformLogger.Level.FINE)) {
355 log.fine("WARNING: Attempt to remove non-existing menu item, index : " + index + ", item count : " + items.size());
356 }
357 }
358 }
359 updateSize();
360 }
361
362 /**
363 * Clears items vector and loads specified vector
364 * @param items vector to be loaded
365 */
366 public void reloadItems(Vector items) {
367 synchronized(getMenuTreeLock()) {
368 this.items.clear();
369 MenuItem[] itemArray = (MenuItem[])items.toArray(new MenuItem[] {});
370 int itemCnt = itemArray.length;
371 for(int i = 0; i < itemCnt; i++) {
372 addItem(itemArray[i]);
373 }
374 }
375 }
376
377 /**
378 * Select specified item and shows/hides submenus if necessary
379 * We can not select by index, so we need to select by ref.
380 * @param item the item to be selected, null to clear selection
381 * @param showWindowIfMenu if the item is XMenuPeer then its
382 * window is shown/hidden according to this param.
383 */
384 void selectItem(XMenuItemPeer item, boolean showWindowIfMenu) {
385 synchronized(getMenuTreeLock()) {
386 XMenuPeer showingSubmenu = getShowingSubmenu();
387 int newSelectedIndex = (item != null) ? items.indexOf(item) : -1;
388 if (this.selectedIndex != newSelectedIndex) {
389 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
390 log.finest("Selected index changed, was : " + this.selectedIndex + ", new : " + newSelectedIndex);
391 }
392 this.selectedIndex = newSelectedIndex;
393 postPaintEvent();
394 }
395 final XMenuPeer submenuToShow = (showWindowIfMenu && (item instanceof XMenuPeer)) ? (XMenuPeer)item : null;
396 if (submenuToShow != showingSubmenu) {
397 XToolkit.executeOnEventHandlerThread(target, new Runnable() {
398 public void run() {
399 doShowSubmenu(submenuToShow);
400 }
401 });
402 }
403 }
404 }
405
406 /**
407 * Performs hiding of currently showing submenu
408 * and showing of submenuToShow.
409 * This function should be executed on eventHandlerThread
410 * @param submenuToShow submenu to be shown or null
411 * to hide currently showing submenu
412 */
413 private void doShowSubmenu(XMenuPeer submenuToShow) {
414 XMenuWindow menuWindowToShow = (submenuToShow != null) ? submenuToShow.getMenuWindow() : null;
415 Dimension dim = null;
416 Rectangle bounds = null;
417 //ensureCreated can invoke XWindowPeer.init() ->
418 //XWindowPeer.initGraphicsConfiguration() ->
419 //Window.getGraphicsConfiguration()
420 //that tries to obtain Component.AWTTreeLock.
421 //So it should be called outside awtLock()
422 if (menuWindowToShow != null) {
423 menuWindowToShow.ensureCreated();
424 }
425 XToolkit.awtLock();
426 try {
427 synchronized(getMenuTreeLock()) {
428 if (showingSubmenu != submenuToShow) {
429 if (log.isLoggable(PlatformLogger.Level.FINEST)) {
430 log.finest("Changing showing submenu");
431 }
432 if (showingSubmenu != null) {
433 XMenuWindow showingSubmenuWindow = showingSubmenu.getMenuWindow();
434 if (showingSubmenuWindow != null) {
435 showingSubmenuWindow.hide();
436 }
437 }
438 if (submenuToShow != null) {
439 dim = menuWindowToShow.getDesiredSize();
440 bounds = menuWindowToShow.getParentMenuWindow().getSubmenuBounds(submenuToShow.getBounds(), dim);
441 menuWindowToShow.show(bounds);
442 }
443 showingSubmenu = submenuToShow;
444 }
445 }
446 } finally {
447 XToolkit.awtUnlock();
448 }
449 }
1105 wnd.selectItem(null, false);
1106 }
1107 } else {
1108 //Mouse is dragged outside menu windows
1109 //clear selection in leaf to reflect it
1110 if (cwnd != null) {
1111 cwnd.selectItem(null, false);
1112 }
1113 }
1114 break;
1115 }
1116 }
1117
1118 /**
1119 * Performs handling of java keyboard event
1120 * Note that this function should be invoked
1121 * only from root of menu window's hierarchy
1122 * that grabs input focus
1123 */
1124 void doHandleJavaKeyEvent(KeyEvent event) {
1125 if (log.isLoggable(PlatformLogger.Level.FINER)) {
1126 log.finer(event.toString());
1127 }
1128 if (event.getID() != KeyEvent.KEY_PRESSED) {
1129 return;
1130 }
1131 final int keyCode = event.getKeyCode();
1132 XBaseMenuWindow cwnd = getShowingLeaf();
1133 XMenuItemPeer citem = cwnd.getSelectedItem();
1134 switch(keyCode) {
1135 case KeyEvent.VK_UP:
1136 case KeyEvent.VK_KP_UP:
1137 if (!(cwnd instanceof XMenuBarPeer)) {
1138 //If active window is not menu bar,
1139 //move selection up
1140 cwnd.selectItem(cwnd.getPrevSelectableItem(), false);
1141 }
1142 break;
1143 case KeyEvent.VK_DOWN:
1144 case KeyEvent.VK_KP_DOWN:
1145 if (cwnd instanceof XMenuBarPeer) {
|