@@ -0,0 +1,3076 @@
+package ch.raffael.util.swing.context;%0A%0Aimport java.beans.PropertyChangeListener;%0A%0Aimport com.google.common.base.Objects;%0A%0Aimport ch.raffael.util.beans.Observable;%0Aimport ch.raffael.util.beans.ObservableSupport;%0A%0A%0A/**%0A * Utility class to track the active context. The active context may be used e.g. in%0A * MDI UIs, where some actions may depend on the active/focused component somewhere down%0A * the component tree.%0A * %3Cp%3E%0A * An example for this would be the save action: In an MDI UI, this action would reside in%0A * the JMenuBar of the frame, but operate within the context of the active window in a%0A * JDesktopPane or JTabbedPane. It could, however, also reside in a toolbar within the%0A * window or tab itself and always operate in this context. This is, where this class%0A * comes to play: The save action looks up an ActiveContextTracker from its event source.%0A * The frame has a tracker associated which will be updated by the desktop. Each document%0A * within the desktop is also associated with an active context tracker, but in fixed%0A * (unchangeable) mode. This way, when invoked from the menu bar, the action will apply%0A * the the currently selected window or tab. When invoked from a tool bar from within the%0A * window, it will always apply to the context the action was invoked from.%0A * %3Cp%3E%0A * TODO: Consider integrating this into the Context API%0A *%0A * @author %3Ca href=%22mailto:herzog@raffael.ch%22%3ERaffael Herzog%3C/a%3E%0A */%0Apublic class ActiveContextTracker implements Observable %7B%0A%0A    private final ObservableSupport observableSupport = new ObservableSupport(this);%0A%0A    private boolean fixed;%0A    private Context activeContext;%0A%0A    public ActiveContextTracker() %7B%0A        this(null, false);%0A    %7D%0A%0A    public ActiveContextTracker(boolean fixed) %7B%0A        this(null, fixed);%0A    %7D%0A%0A    public ActiveContextTracker(Context activeContext) %7B%0A        this(activeContext, false);%0A    %7D%0A%0A    public ActiveContextTracker(Context activeContext, boolean fixed) %7B%0A        this.fixed = fixed;%0A        this.activeContext = activeContext;%0A    %7D%0A%0A    @Override%0A    public void addPropertyChangeListener(PropertyChangeListener listener) %7B%0A        observableSupport.addPropertyChangeListener(listener);%0A    %7D%0A%0A    @Override%0A    public void removePropertyChangeListener(PropertyChangeListener listener) %7B%0A        observableSupport.removePropertyChangeListener(listener);%0A    %7D%0A%0A    public void setActiveContext(Context activeContext) %7B%0A        if ( !Objects.equal(activeContext, this.activeContext) ) %7B%0A            if ( fixed && this.activeContext != null ) %7B%0A                throw new IllegalStateException(%22Active context cannot be changed%22);%0A            %7D%0A            Context oldContext = this.activeContext;%0A            this.activeContext = activeContext;%0A            observableSupport.firePropertyChange(%22activeContext%22, oldContext, activeContext);%0A        %7D%0A    %7D%0A%0A    public Context getActiveContext() %7B%0A        return activeContext;%0A    %7D%0A%0A    public boolean isFixed() %7B%0A        return fixed;%0A    %7D%0A%0A    public void setFixed(boolean fixed) %7B%0A        this.fixed = fixed;%0A    %7D%0A%7D%0A

Add ActiveContextTracker.