Hallo zusammen,
ich habe vor kurzem begonnen eine Anwendung noch ein wenig zu "pimpen".
Dazu fiel mir auf, das vor allem viele Tabellen und Trees keine Menüs haben und viele Funktionen umständliche (also: weiter Weg mit der Maus) nur über Buttons steuerbar sind (add/edit/remove/...)
Ich habe daher angefangen mittels MenuManager das ganze aufzupeppen:
Das funktioniert für meinen ersten TreeViewer hervorragend, für einen anderen aber überhaupt nicht.
Ich wollte zur fillContextMenu-Methode debuggen, stellte aber einfach fest, dass der Listener offenbar nie ausgelöst wurde.
Der folgende Hack zeigt beim ersten Rechtsklick das Menü (mit DropDown-Menü-Item), beim zweiten Klick sind die DropDown-Items auf einmal auf der Hauptebene der Menü-Items. Beim dritten Klick verrent sich (reproduzierbar) offenbar mein fglrx Graphiktreiber (Ubuntu 11.04/Unity).
Ich versteh aber schlicht und ergreifend nicht, warum der grundsätzlich gleiche Code in einem Composite geht, und in einem anderen nicht.
Kann es an inkompatibilitäten mit anderen Listenern liegen, die die Ausführung des IMenuListener des MenuManagers verhindern?
Vielen Dank und Grüße,
Daniel
PS: meine fillContextMenu-Methode:
PPS: Die Action(s), die ich in den MenuManager rein werfe (gekürzt, da zu lang):
ich habe vor kurzem begonnen eine Anwendung noch ein wenig zu "pimpen".
Dazu fiel mir auf, das vor allem viele Tabellen und Trees keine Menüs haben und viele Funktionen umständliche (also: weiter Weg mit der Maus) nur über Buttons steuerbar sind (add/edit/remove/...)
Ich habe daher angefangen mittels MenuManager das ganze aufzupeppen:
Java:
final MenuManager menuManager = new MenuManager();
menuManager.setRemoveAllWhenShown(true);
final Menu menu = menuManager.createContextMenu(tableViewer
.getControl());
menuManager.addMenuListener(new IMenuListener() {
@Override
public void menuAboutToShow(final IMenuManager manager) {
manager.setRemoveAllWhenShown(true);
fillContextMenu(ssdModel, tableViewer, manager);
}
});
tableViewer.getControl().setMenu(menu);
Das funktioniert für meinen ersten TreeViewer hervorragend, für einen anderen aber überhaupt nicht.
Ich wollte zur fillContextMenu-Methode debuggen, stellte aber einfach fest, dass der Listener offenbar nie ausgelöst wurde.
Der folgende Hack zeigt beim ersten Rechtsklick das Menü (mit DropDown-Menü-Item), beim zweiten Klick sind die DropDown-Items auf einmal auf der Hauptebene der Menü-Items. Beim dritten Klick verrent sich (reproduzierbar) offenbar mein fglrx Graphiktreiber (Ubuntu 11.04/Unity).
Java:
ispTableViewer.getTable().addMenuDetectListener(
new MenuDetectListener() {
@Override
public void menuDetected(MenuDetectEvent e) {
if (!menuManager.getMenu().isDisposed())
menuManager.getMenu().setVisible(true);
}
});
Ich versteh aber schlicht und ergreifend nicht, warum der grundsätzlich gleiche Code in einem Composite geht, und in einem anderen nicht.
Kann es an inkompatibilitäten mit anderen Listenern liegen, die die Ausführung des IMenuListener des MenuManagers verhindern?
Vielen Dank und Grüße,
Daniel
PS: meine fillContextMenu-Methode:
Java:
private void fillContextMenu(SSDModel ssdModel, TableViewer viewer,
IMenuManager manager) {
Object[] selection = ((IStructuredSelection) viewer.getSelection())
.toArray();
Action action = new AddEditRemoveEntryAction(ssdModel, selection,
viewer, AddEditRemoveEntryAction.Type.ADD);
manager.add(action);
action = new AddEditRemoveEntryAction(ssdModel, selection, viewer,
AddEditRemoveEntryAction.Type.EDIT);
if (selection == null || selection.length == 0 || selection.length > 1) {
action.setEnabled(false);
}
manager.add(action);
action = new AddEditRemoveEntryAction(ssdModel, selection, viewer,
AddEditRemoveEntryAction.Type.REMOVE);
if (selection == null || selection.length == 0) {
action.setEnabled(false);
}
manager.add(action);
manager.add(new Separator());
action = new AddEditRemoveEntryAction(ssdModel, selection, viewer,
AddEditRemoveEntryAction.Type.MENU);
if (selection == null || selection.length == 0 || selection.length > 1) {
action.setEnabled(false);
}
manager.add(action);
}
PPS: Die Action(s), die ich in den MenuManager rein werfe (gekürzt, da zu lang):
Java:
public class AddEditRemoveEntryAction extends Action {
private static final Image ADD = IconProvider.getImageByIconName(
"fugue_plus.png", true); //$NON-NLS-1$
private static final Image REMOVE = IconProvider.getImageByIconName(
"fugue_minus.png", true); //$NON-NLS-1$
private static final Image EDIT = IconProvider.getImageByIconName(
"fugue_pencil.png", true); //$NON-NLS-1$
private static final Image CALENDAR = IconProvider
.getImageByIconName("fugue_calendar--pencil.png", true); //$NON-NLS-1$
public static enum Type {
ADD, EDIT, REMOVE, MENU;
}
private SSDModel ssdModel;
private Object[] selection;
private Viewer parentViewer;
private AddEditRemoveEntryAction.Type type;
// used only if Type == MENU
private MenuCreatorImpl menuCreator = null;
public AddEditRemoveEntryAction(SSDModel ssdModel, Object[] selection,
Viewer parentViewer, AddEditRemoveEntryAction.Type type) {
super("", Type.MENU == type ? AS_DROP_DOWN_MENU : AS_PUSH_BUTTON); //$NON-NLS-1$
this.ssdModel = ssdModel;
this.selection = selection;
this.parentViewer = parentViewer;
this.type = type;
switch (type) {
case ADD:
setText(Messages
.getString("EntrySettingsComposite.addButton.text")); //$NON-NLS-1$
setImageDescriptor(ImageDescriptor.createFromImage(ADD));
break;
case EDIT:
setText(Messages
.getString("EntrySettingsComposite.editButton.text")); //$NON-NLS-1$
setImageDescriptor(ImageDescriptor.createFromImage(EDIT));
break;
case REMOVE:
setText(Messages
.getString("EntrySettingsComposite.deleteButton.text")); //$NON-NLS-1$
setImageDescriptor(ImageDescriptor.createFromImage(REMOVE));
break;
case MENU:
setText("Edit Retention Time");
setImageDescriptor(ImageDescriptor.createFromImage(CALENDAR));
// create MenuCreatorImpl (private class at the end of this one)
menuCreator = new MenuCreatorImpl();
setMenuCreator(menuCreator);
break;
}
}
@Override
public void run() {
switch (type) {
case ADD:
handleAdd();
break;
case EDIT:
handleEdit();
break;
case REMOVE:
handleRemove();
break;
case MENU:
// create menu
handleMenu();
break;
}
}
private void handleAdd() {
[...]
}
private void handleEdit() {
[...]
}
private void handleRemove() {
[...]
}
private void handleMenu() {
setMenuCreator(menuCreator);
Menu menu = menuCreator.getMenu(parentViewer.getControl());
if (menu != null && !menu.isDisposed())
menu.setVisible(true);
}
private class MenuCreatorImpl implements IMenuCreator {
private Menu menu;
@Override
public void dispose() {
if (menu != null) {
menu.dispose();
}
}
@Override
public Menu getMenu(Menu parent) {
return getMenu(parent.getShell());
}
@Override
public Menu getMenu(Control parent) {
if (menu != null) {
menu.dispose();
}
menu = new Menu(parent);
int i = 0;
for (LookupTimes.Day day : LookupTimes.Day.values()) {
LookupTimeAction action = new LookupTimeAction(day,
selection[0]);
addActionToMenu(menu, action, i + 1);
i++;
}
return menu;
}
private void addActionToMenu(Menu parent, Action action, int accelerator) {
if (accelerator < 10) {
StringBuffer label = new StringBuffer();
// add the numerical accelerator
label.append("&"); //$NON-NLS-1$
label.append(accelerator);
label.append(" "); //$NON-NLS-1$
label.append(action.getText());
action.setText(label.toString());
}
ActionContributionItem item = new ActionContributionItem(action);
item.fill(parent, -1);
}
}
private class LookupTimeAction extends Action {
private lookupTimes.Day day;
private Object firstSelection;
public LookupTimeAction(LookupTimes.Day day, Object firstSelection) {
super(day.getName(), AS_PUSH_BUTTON);
this.day = day;
this.firstSelection = firstSelection;
}
@Override
public void run() {
if (day == null)
return;
Entry e = (Entry) firstSelection;
if (e == null)
return;
ModifyLookupTimeShell shell = new ModifyLookupTimeShell(
parentViewer.getControl().getDisplay());
shell.setData(e, day);
Point location = parentViewer.getControl().getDisplay()
.getCursorLocation();
if (location != null)
shell.openShellAtLocation(location, true);
else
shell.openShellOverlay(parentViewer.getControl(), true);
ModifyLookupTimeResult result = shell.getRetentionTime();
if (result.isCanceled()) {
return;
}
if (result.getEntry() != null && result.getDay() != null) {
Entry e = result.getEntry();
LookupTimes lookupTimes = entry.getLookupTimes();
if (result.getLookupTime() != null) {
lookupTimes.setLookupTime(result.getLookupTime());
} else {
lookupTimes.setLookupTime(new LookupTime(result
.getDay()));
}
parentViewer.refresh();
}
}
}
}