blob: 7aa4ac7d0e96a513367bda53517f6ade66ff34ce [file] [log] [blame]
/**
* Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Florian Pirchner - Initial implementation
*/
package org.eclipse.osbp.runtime.web.vaadin.common.shortcuts;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeCallback;
import org.eclipse.osbp.runtime.common.keystroke.KeyStrokeDefinition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.vaadin.event.ActionManager;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.Component;
import com.vaadin.ui.Panel;
// TODO: Auto-generated Javadoc
/**
* Is responsible to add shortcut listeners to the root panel. And to remove
* them too.
* <p>
* Attention: There must be a panel in the parent hierarchy of the component be
* available. Otherwise an Exception is thrown during activate.
*/
public class ShortcutHandler {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory
.getLogger(ShortcutHandler.class);
/** The def. */
private KeyStrokeDefinition def;
/** The callback. */
private KeyStrokeCallback callback;
/** The component. */
private Component component;
/** The root panel. */
private Panel rootPanel;
/** The listener. */
private ShortcutListener listener;
/**
* Instantiates a new shortcut handler.
*
* @param def
* the def
* @param callback
* the callback
* @param component
* the component
*/
public ShortcutHandler(KeyStrokeDefinition def, KeyStrokeCallback callback,
Component component) {
super();
this.def = def;
this.callback = callback;
this.component = component;
}
/**
* Tries to find a panel in the parent hierarchy.
*
* @param component
* the component
* @return the panel
*/
protected Panel findPanel(Component component) {
if (component == null) {
return null;
}
if (component instanceof Panel) {
return (Panel) component;
}
return findPanel(component.getParent());
}
/**
* Activate.
*/
@SuppressWarnings("serial")
public void activate() {
if (rootPanel == null) {
this.rootPanel = findPanel(component);
if (rootPanel == null) {
throw new IllegalStateException(
"No root panel found. Can not attach shortcutListener to component.");
}
}
if (listener == null) {
this.listener = new ShortcutListener(def.getCaption(),
def.getKeyCode(), def.getModifierKeys()) {
@Override
public void handleAction(Object sender, Object target) {
callback.callback(sender, target);
}
};
}
ActionManager manager = getActionManager();
manager.addAction(listener);
}
/**
* Deactivate.
*/
public void deactivate() {
ActionManager manager = getActionManager();
manager.removeAction(listener);
}
/**
* Gets the action manager.
*
* @return the action manager
*/
protected ActionManager getActionManager() {
ActionManager actionManager = null;
try {
Method m = AbstractComponent.class.getDeclaredMethod(
"getActionManager", new Class[0]);
if (!m.isAccessible()) {
m.setAccessible(true);
}
actionManager = (ActionManager) m.invoke(rootPanel, new Object[0]);
} catch (NoSuchMethodException | IllegalAccessException
| InvocationTargetException e) {
LOGGER.error("{}", e);
}
return actionManager;
}
}