/*
* @(#)DesktopEventService.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 org.jhotdraw.contrib;
import org.jhotdraw.framework.DrawingView;
import org.jhotdraw.standard.NullDrawingView;
import org.jhotdraw.util.CollectionsFactory;
import java.util.List;
import java.util.ListIterator;
import java.awt.event.ContainerAdapter;
import java.awt.event.ContainerListener;
import java.awt.event.ContainerEvent;
import java.awt.*;
/**
* @author Wolfram Kaiser <mrfloppy@users.sourceforge.net>
* @version <$CURRENT_VERSION$>
*/
public class DesktopEventService {
/**
* Current usage of this List is not thread safe, nor should it need to be.
* If it ever does we can synchronize on the List itself to provide safety.
*/
private java.util.List listeners;
private DrawingView mySelectedView;
private Container myContainer;
private Desktop myDesktop;
public DesktopEventService(Desktop newDesktop, Container newContainer) {
listeners = CollectionsFactory.current().createList();
setDesktop(newDesktop);
setContainer(newContainer);
getContainer().addContainerListener(createComponentListener());
}
private void setDesktop(Desktop newDesktop) {
myDesktop = newDesktop;
}
protected Desktop getDesktop() {
return myDesktop;
}
private void setContainer(Container newContainer) {
myContainer = newContainer;
}
protected Container getContainer() {
return myContainer;
}
public void addComponent(Component newComponent) {
getContainer().add(newComponent);
}
public void removeComponent(DrawingView dv) {
Component[] comps = getContainer().getComponents();
for (int x = 0; x < comps.length; x++) {
if (dv == Helper.getDrawingView(comps[x])) {
getContainer().remove(comps[x]);
break;
}
}
}
public void removeAllComponents() {
getContainer().removeAll();
}
public void addDesktopListener(DesktopListener dpl) {
listeners.add(dpl);
}
public void removeDesktopListener(DesktopListener dpl) {
listeners.remove(dpl);
}
protected void fireDrawingViewAddedEvent(final DrawingView dv) {
ListIterator li= listeners.listIterator(listeners.size());
DesktopEvent dpe = createDesktopEvent(getActiveDrawingView(), dv);
while (li.hasPrevious()) {
DesktopListener dpl = (DesktopListener)li.previous();
dpl.drawingViewAdded(dpe);
}
}
protected void fireDrawingViewRemovedEvent(final DrawingView dv) {
ListIterator li= listeners.listIterator(listeners.size());
DesktopEvent dpe = createDesktopEvent(getActiveDrawingView(), dv);
while (li.hasPrevious()) {
DesktopListener dpl = (DesktopListener)li.previous();
dpl.drawingViewRemoved(dpe);
}
}
/**
* This method is only called if the selected drawingView has actually changed
*/
protected void fireDrawingViewSelectedEvent(final DrawingView oldView, final DrawingView newView) {
ListIterator li= listeners.listIterator(listeners.size());
DesktopEvent dpe = createDesktopEvent(oldView, newView);
while (li.hasPrevious()) {
DesktopListener dpl = (DesktopListener)li.previous();
dpl.drawingViewSelected(dpe);
}
}
/**
* @param oldView previous active drawing view (may be null because not all events require this information)
*/
protected DesktopEvent createDesktopEvent(DrawingView oldView, DrawingView newView) {
return new DesktopEvent(getDesktop(), newView, oldView);
}
public DrawingView[] getDrawingViews(Component[] comps) {
List al = CollectionsFactory.current().createList();
for (int x = 0; x < comps.length; x++) {
DrawingView dv = Helper.getDrawingView(comps[x]);
if (dv != null) {
al.add(dv);
}
}
DrawingView[] dvs = new DrawingView[al.size()];
al.toArray(dvs);
return dvs;
}
public DrawingView getActiveDrawingView() {
return mySelectedView;
}
protected void setActiveDrawingView(DrawingView newActiveDrawingView) {
mySelectedView = newActiveDrawingView;
}
protected ContainerListener createComponentListener() {
return new ContainerAdapter() {
/**
* If the dv is null assert
* @todo does adding a component always make it the selected view?
* Yes so far because this is only being used on single view Desktops.
* If it is to work on multipleView desktops, the we need to think further.
*/
public void componentAdded(ContainerEvent e) {
DrawingView dv = Helper.getDrawingView((java.awt.Container)e.getChild());
DrawingView oldView = getActiveDrawingView();
if (dv != null) {
fireDrawingViewAddedEvent(dv);
setActiveDrawingView(dv);
fireDrawingViewSelectedEvent(oldView, getActiveDrawingView());
}
}
/**
* If dv is null assert
* dv will only be null if something thats not a drawingView was
* added to the desktop. it would be simpler if we forbade that.
*/
public void componentRemoved(ContainerEvent e) {
DrawingView dv = Helper.getDrawingView((java.awt.Container)e.getChild());
if (dv != null) {
DrawingView oldView = getActiveDrawingView();
setActiveDrawingView(NullDrawingView.getManagedDrawingView(oldView.editor()));
fireDrawingViewSelectedEvent(oldView, getActiveDrawingView());
fireDrawingViewRemovedEvent(dv);
}
}
};
}
}