com.jidesoft.swing.DelegateAction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jide-oss Show documentation
Show all versions of jide-oss Show documentation
JIDE Common Layer (Professional Swing Components)
/*
* @(#)DelegateAction.java 10/2/2006
*
* Copyright 2002 - 2006 JIDE Software Inc. All rights reserved.
*/
package com.jidesoft.swing;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* DelegateAction is a special AbstractAction which can do something then delegate to another action depending on the
* return value of {@link #delegateActionPerformed(java.awt.event.ActionEvent)}. There are two usages of it. First, you
* can use {@link #replaceAction(javax.swing.JComponent, int, javax.swing.KeyStroke, DelegateAction)} to replace the action
* associated with the specified keystroke with the DelegateAction. The DelegateAction will be triggered when the
* keystroke is pressed. After DelegateAction is done, it can return true or false. If false, the original action
* associated with the keystroke will be triggered as well. This solves the problem that {@link
* JComponent#registerKeyboardAction(java.awt.event.ActionListener, String, javax.swing.KeyStroke, int)} will replace the
* original action so that the original action will never be triggered.
*
* The second way to use DelegateAction is to delegate the action from one component to another component using {@link
* #replaceAction(javax.swing.JComponent, int, javax.swing.JComponent, int, javax.swing.KeyStroke, DelegateAction)}. In this
* case, the keystroke on the first component parameter will be triggered the DelegateAction. If DelegateAction returns
* false, the registered action on the second component parameter will be triggered. If you pass in {@link
* PassthroughDelegateAction}, the registered action on the second component will always be triggered.
*
* Please notes, if you call replaceAction several times on the same component with the same keystroke, it will form a
* chain of DelegateActions. In this case, the first call will be the first DelegateAction. In the other words, the
* first one will have the highest priority and will be triggered first. Ideally, we should assign a priority to each
* DelegateAction. But for the sake of simplicity, we decided not doing it for now. So because of this, this class is
* not ready to be used as public API. We have to make it public because different packages in JIDE need to use it. If
* you want to use, please use it with caution. We don't guarantee that we will not change the public methods on this
* classes.
*
*/
abstract public class DelegateAction extends AbstractAction {
private static final long serialVersionUID = -3867985431184738600L;
private Action _action;
private JComponent _target;
public DelegateAction() {
}
public DelegateAction(Action action) {
_action = action;
}
public DelegateAction(Action action, JComponent target) {
_action = action;
_target = target;
}
/**
* Returns true if either delegateIsEnabled or the action is enabled.
*
* {@inheritDoc}
*/
// Should be final like actionPerformed but not done for backward compatibility.
@Override
public boolean isEnabled() {
return isDelegateEnabled() || (_action != null && _action.isEnabled());
}
final public void actionPerformed(ActionEvent e) {
if (!delegateActionPerformed(e)) {
if (_action != null) {
if (_target == null) {
_action.actionPerformed(e);
}
else {
_action.actionPerformed(new ActionEvent(getTarget(), e.getID(), e.getActionCommand(), e.getWhen(), e.getModifiers()));
}
}
}
}
protected Action getAction() {
return _action;
}
protected void setAction(Action action) {
_action = action;
}
protected JComponent getTarget() {
return _target;
}
protected void setTarget(JComponent target) {
_target = target;
}
/**
* Checks if an action can be performed. Returns true if delegateActionPerformed would perform an action. Otherwise
* returns false.
*
* @return true
if the action can be performed.
*/
// Should be abstract like delegateActionPerformed but not done for backward compatibility.
public boolean isDelegateEnabled() {
return super.isEnabled();
}
/**
* Performs an action. Returns true if no further action should be taken for this keystroke. Otherwise, returns
* false.
*
* @param e the action event.
* @return true if no further action should be taken for this keystroke. Otherwise, returns false.
*/
abstract public boolean delegateActionPerformed(ActionEvent e);
public static class PassthroughDelegateAction extends DelegateAction {
private static final long serialVersionUID = -1555177105658867899L;
@Override
public boolean delegateActionPerformed(ActionEvent e) {
return false;
}
@Override
public boolean isDelegateEnabled() {
return false;
}
}
public static void replaceAction(JComponent component, int condition, KeyStroke keyStroke, DelegateAction delegateAction) {
replaceAction(component, condition, component, condition, keyStroke, delegateAction);
}
public static void replaceAction(JComponent component, int condition, KeyStroke keyStroke, DelegateAction delegateAction, boolean first) {
replaceAction(component, condition, component, condition, keyStroke, delegateAction, first);
}
public static void replaceAction(JComponent component, int condition, JComponent target, int targetCondition, KeyStroke keyStroke) {
replaceAction(component, condition, target, targetCondition, keyStroke, new DelegateAction.PassthroughDelegateAction(), false);
}
public static void replaceAction(JComponent component, int condition, JComponent target, int targetCondition, KeyStroke keyStroke, DelegateAction delegateAction) {
replaceAction(component, condition, target, targetCondition, keyStroke, delegateAction, false);
}
public static void replaceAction(JComponent component, int condition, JComponent target, int targetCondition, KeyStroke keyStroke, DelegateAction delegateAction, boolean first) {
ActionListener action = component.getActionForKeyStroke(keyStroke);
if (action != delegateAction && action instanceof Action) {
if (!first && action instanceof DelegateAction) {
Action childAction = ((DelegateAction) action).getAction();
while (childAction != null) {
if (childAction == delegateAction) {
return;
}
if (childAction instanceof DelegateAction) {
childAction = ((DelegateAction) childAction).getAction();
}
else {
childAction = null;
}
}
delegateAction.setAction(((DelegateAction) action).getAction());
((DelegateAction) action).setAction(delegateAction);
delegateAction = (DelegateAction) action;
}
else {
delegateAction.setAction((Action) action);
}
}
if (target != component) {
delegateAction.setTarget(target);
replaceAction(component, condition, keyStroke, delegateAction);
}
else {
Object actionCommand = target.getInputMap(targetCondition).get(keyStroke);
if (actionCommand == null) {
component.registerKeyboardAction(delegateAction, keyStroke, condition);
}
else {
component.getActionMap().put(actionCommand, delegateAction);
}
}
}
public static void restoreAction(JComponent component, int condition, KeyStroke keyStroke) {
if (component == null) {
return;
}
ActionListener action = component.getActionForKeyStroke(keyStroke);
if (action instanceof DelegateAction) {
Action actualAction = ((DelegateAction) action).getAction();
if (actualAction != null) {
component.registerKeyboardAction(actualAction, keyStroke, condition);
}
else {
component.unregisterKeyboardAction(keyStroke);
}
}
}
public static void restoreAction(JComponent component, int condition, KeyStroke keyStroke, Class> actionClass) {
ActionListener action = component.getActionForKeyStroke(keyStroke);
ActionListener parent = action;
ActionListener top = action;
while (action instanceof DelegateAction) {
if (actionClass.isAssignableFrom(action.getClass())) {
if (top == action) {
Action a = ((DelegateAction) action).getAction();
if (a == null) {
component.unregisterKeyboardAction(keyStroke);
}
else {
component.registerKeyboardAction(a, keyStroke, condition);
}
}
else {
((DelegateAction) parent).setAction(((DelegateAction) action).getAction());
}
break;
}
parent = action;
action = ((DelegateAction) action).getAction();
}
}
public static void restoreAction(JComponent component, int condition, KeyStroke keyStroke, Action actionToBeRemoved) {
ActionListener action = component.getActionForKeyStroke(keyStroke);
ActionListener parent = action;
ActionListener top = action;
while (action instanceof DelegateAction) {
if (actionToBeRemoved == action) {
if (top == action) {
component.registerKeyboardAction(((DelegateAction) action).getAction(), keyStroke, condition);
}
else {
((DelegateAction) parent).setAction(((DelegateAction) action).getAction());
}
break;
}
parent = action;
action = ((DelegateAction) action).getAction();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy