AbstractCommand.java
/*
* @(#)AbstractCommand.java
*
* Project: JHotdraw - a GUI framework for technical drawings
* http://www.jhotdraw.org
* http://jhotdraw.sourceforge.net
* Copyright: © by the original author(s) and all contributors
* License: Lesser GNU Public License (LGPL)
* http://www.opensource.org/licenses/lgpl-license.html
*/
package CH.ifa.draw.standard;
import CH.ifa.draw.framework.*;
import CH.ifa.draw.util.Command;
import CH.ifa.draw.util.CommandListener;
import CH.ifa.draw.util.Undoable;
import java.util.*;
/**
* @author: Helge Horch, Wolfram Kaiser
* @version <$CURRENT_VERSION$>
*/
public abstract class AbstractCommand implements Command, FigureSelectionListener, ViewChangeListener {
private String myName;
private Undoable myUndoableActivity;
private boolean myIsViewRequired;
private AbstractCommand.EventDispatcher myEventDispatcher;
/**
* the DrawingEditor this command applies to
*/
private DrawingEditor myDrawingEditor;
/**
* Constructs a command with the given name that applies to the given view.
* @param name java.lang.String
* @param newDrawingEditor the DrawingEditor which manages the views
*/
public AbstractCommand(String newName, DrawingEditor newDrawingEditor) {
this(newName, newDrawingEditor, true);
}
public AbstractCommand(String newName, DrawingEditor newDrawingEditor, boolean newIsViewRequired) {
setName(newName);
setDrawingEditor(newDrawingEditor);
getDrawingEditor().addViewChangeListener(this);
myIsViewRequired = newIsViewRequired;
setEventDispatcher(createEventDispatcher());
}
public void viewSelectionChanged(DrawingView oldView, DrawingView newView) {
if (oldView != null) {
oldView.removeFigureSelectionListener(this);
}
if (newView != null) {
newView.addFigureSelectionListener(this);
}
if (isViewRequired()) {
boolean isOldViewInteractive = (oldView != null) && oldView.isInteractive();
boolean isNewViewInteractive = (newView != null) && newView.isInteractive();
// old view was not interactive aware while new view is now interactive aware
if (!isOldViewInteractive && isNewViewInteractive) {
getEventDispatcher().fireCommandExecutableEvent();
}
// old view was interactive aware while new view is not
else if (isOldViewInteractive && !isNewViewInteractive) {
getEventDispatcher().fireCommandNotExecutableEvent();
}
}
}
/**
* Sent when a new view is created
*/
public void viewCreated(DrawingView view) {
}
/**
* Send when an existing view is about to be destroyed.
*/
public void viewDestroying(DrawingView view) {
}
/**
* @param view a DrawingView
*/
public void figureSelectionChanged(DrawingView view) {
}
/**
* @return DrawingEditor associated with this command
*/
public DrawingEditor getDrawingEditor() {
return myDrawingEditor;
}
private void setDrawingEditor(DrawingEditor newDrawingEditor) {
myDrawingEditor = newDrawingEditor;
}
/**
* Convenience method
*
* @return DrawingView currently active in the editor
*/
public DrawingView view() {
return getDrawingEditor().view();
}
/**
* Gets the command name.
*/
public String name() {
return myName;
}
public void setName(String newName) {
myName = newName;
}
/**
* Releases resources associated with this command
*/
public void dispose() {
if (view() != null) {
view().removeFigureSelectionListener(this);
}
}
/**
* Executes the command.
*/
public void execute() {
if (view() == null) {
throw new JHotDrawRuntimeException("execute should NOT be getting called when view() == null");
};
}
/**
* Tests if the command can be executed. The view must be valid when this is
* called. Per default, a command is executable if at
* least one figure is selected in the current activated
* view.
*/
public boolean isExecutable() {
// test whether there is a view required and whether an existing view
// accepts user input
if (isViewRequired()) {
if ((view() == null) || !view().isInteractive()) {
return false;
}
}
return isExecutableWithView();
}
protected boolean isViewRequired() {
return myIsViewRequired;
}
protected boolean isExecutableWithView() {
return true;
}
public Undoable getUndoActivity() {
return myUndoableActivity;
}
public void setUndoActivity(Undoable newUndoableActivity) {
myUndoableActivity = newUndoableActivity;
}
public void addCommandListener(CommandListener newCommandListener) {
getEventDispatcher().addCommandListener(newCommandListener);
}
public void removeCommandListener(CommandListener oldCommandListener) {
getEventDispatcher().removeCommandListener(oldCommandListener);
}
private void setEventDispatcher(AbstractCommand.EventDispatcher newEventDispatcher) {
myEventDispatcher = newEventDispatcher;
}
protected AbstractCommand.EventDispatcher getEventDispatcher() {
return myEventDispatcher;
}
public AbstractCommand.EventDispatcher createEventDispatcher() {
return new AbstractCommand.EventDispatcher(this);
}
public static class EventDispatcher {
private Vector myRegisteredListeners;
private Command myObservedCommand;
public EventDispatcher(Command newObservedCommand) {
myRegisteredListeners = new Vector();
myObservedCommand = newObservedCommand;
}
public void fireCommandExecutedEvent() {
Enumeration le = myRegisteredListeners.elements();
while (le.hasMoreElements()) {
((CommandListener)le.nextElement()).commandExecuted(new EventObject(myObservedCommand));
}
}
public void fireCommandExecutableEvent() {
Enumeration le = myRegisteredListeners.elements();
while (le.hasMoreElements()) {
((CommandListener)le.nextElement()).commandExecutable(new EventObject(myObservedCommand));
}
}
public void fireCommandNotExecutableEvent() {
Enumeration le = myRegisteredListeners.elements();
while (le.hasMoreElements()) {
((CommandListener)le.nextElement()).commandNotExecutable(new EventObject(myObservedCommand));
}
}
public void addCommandListener(CommandListener newCommandListener) {
if (!myRegisteredListeners.contains(newCommandListener)) {
myRegisteredListeners.add(newCommandListener);
}
}
public void removeCommandListener(CommandListener oldCommandListener) {
if (myRegisteredListeners.contains(oldCommandListener)) {
myRegisteredListeners.remove(oldCommandListener);
}
}
}
}