package steve; import org.eclipse.swt.*; import org.eclipse.swt.events.*; import org.eclipse.swt.widgets.*; public class PR_25467 { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); Menu menu = new Menu(shell, SWT.BAR); shell.setMenuBar(menu); MenuItem fileItem = new MenuItem(menu, SWT.CASCADE); fileItem.setText("File"); Menu fileMenu = new Menu(fileItem); fileItem.setMenu(fileMenu); AcceleratorMenu acceleratorMenu = new AcceleratorMenu(fileMenu); int[] accelerators = new int[128]; for (int i = 0; i < accelerators.length; i++) { if (i < 32) accelerators[i] = SWT.CTRL + 'A' + i; else if (i < 64) accelerators[i] = SWT.SHIFT + 'A' + i - 32; else if (i < 96) accelerators[i] = SWT.ALT + 'A' + i - 64; else accelerators[i] = SWT.CTRL + SWT.SHIFT + 'A' + i - 96; } long t0 = System.currentTimeMillis(); acceleratorMenu.setAccelerators(accelerators); long t1 = System.currentTimeMillis(); System.out.println("time: " + (t1 - t0)); shell.pack(); shell.open(); while (!shell.isDisposed()) if (!display.readAndDispatch()) display.sleep (); display.dispose(); } } class AcceleratorMenu { private int[] accelerators; private Menu parent, menu; private MenuItem item; private Control focusControl; private SelectionListener selectionListener; private VerifyListener verifyListener; private Listener menuItemListener, parentListener, focusControlListener; public AcceleratorMenu(Menu parent) { this.parent = parent; menu = new Menu(parent.getParent(), SWT.DROP_DOWN); if (!parent.isVisible()) { item = new MenuItem(parent, SWT.CASCADE,0); item.setText(""); item.setMenu(menu); } focusControlListener = new Listener () { public void handleEvent (Event event) { if (verifyListener == null || menu.isDisposed()) return; if (event.type == SWT.KeyDown) { switch (event.keyCode) { case SWT.CONTROL: case SWT.SHIFT: case SWT.ALT: return; } } VerifyEvent verifyEvent = new VerifyEvent (event); if (event.text == null) event.text = ""; verifyListener.verifyText(verifyEvent); event.text = verifyEvent.text; event.doit = verifyEvent.doit; } }; menuItemListener = new Listener() { public void handleEvent(Event event) { if (selectionListener != null) { SelectionEvent selectionEvent = new SelectionEvent (event); //FIX ME or get EP to just call getAccelerator MenuItem item = (MenuItem) event.widget; selectionEvent.detail = item.getAccelerator(); selectionListener.widgetSelected(selectionEvent); } } }; parentListener = new Listener () { public void handleEvent(Event event) { switch (event.type) { case SWT.Dispose: dispose (); break; case SWT.Show: if(item == null || item.isDisposed()) break; item.setMenu(null); item.dispose(); item = null; break; case SWT.Hide: item = new MenuItem(AcceleratorMenu.this.parent, SWT.CASCADE,0); if(menu.isDisposed()) { //doing more than needed; setAccelerators(getAccelerators()); } else { item.setMenu(menu); } break; } } }; parent.addListener(SWT.Show, parentListener); parent.addListener(SWT.Hide, parentListener); parent.addListener(SWT.Dispose, parentListener); } public void addSelectionListener(SelectionListener selectionListener) { this.selectionListener = selectionListener; } public void addVerifyListener(VerifyListener listener) { verifyListener = listener; setMultiMode(true); } public boolean isDisposed() { return item == null || item.isDisposed(); } public void dispose() { setMultiMode(false); parent.removeListener(SWT.Show, parentListener); parent.removeListener(SWT.Hide, parentListener); parent.removeListener(SWT.Dispose, parentListener); menu.dispose(); menu = null; if (item != null) item.dispose(); item = null; focusControl = null; parent = null; verifyListener = null; parentListener = null; selectionListener = null; focusControlListener = null; menuItemListener = null; } public int[] getAccelerators() { if (accelerators == null) return null; int[] accelerators = new int[this.accelerators.length]; System.arraycopy(this.accelerators, 0, accelerators, 0, this.accelerators.length); return accelerators; } public void removeSelectionListener(SelectionListener selectionListener) { selectionListener = null; } public void removeVerifyListener(VerifyListener listener) { verifyListener = null; setMultiMode(false); } public void setAccelerators(final int[] accelerators) { if (accelerators == null) { this.accelerators = null; } else { this.accelerators = new int[accelerators.length]; System.arraycopy(accelerators, 0, this.accelerators, 0, accelerators.length); } menu.dispose(); menu = new Menu(parent.getParent(), SWT.DROP_DOWN); if (item != null) item.setMenu (menu); for (int i = 0; i < accelerators.length; i++) { final int key = accelerators[i]; MenuItem keyMenuItem = new MenuItem(menu, SWT.PUSH); keyMenuItem.setAccelerator(key); keyMenuItem.addListener(SWT.Selection, menuItemListener); } } private void setMultiMode (boolean mode) { if (focusControl != null && !focusControl.isDisposed ()) { focusControl.removeListener (SWT.KeyDown, focusControlListener); focusControl.removeListener (SWT.Verify, focusControlListener); focusControl.removeListener (SWT.FocusOut, focusControlListener); focusControl.removeListener (SWT.Dispose, focusControlListener); } if (mode) { Display display = menu.getDisplay (); focusControl = display.getFocusControl (); if (focusControl != null) { focusControl.addListener (SWT.KeyDown, focusControlListener); focusControl.addListener (SWT.Verify, focusControlListener); focusControl.addListener (SWT.FocusOut, focusControlListener); focusControl.addListener (SWT.Dispose, focusControlListener); } } } }