org.drombler.commons.docking.context.impl.DockableDataModifiedManager Maven / Gradle / Ivy
/*
* COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Notice
*
* The contents of this file are subject to the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL)
* Version 1.0 (the "License"); you may not use this file except in
* compliance with the License. A copy of the License is available at
* http://www.opensource.org/licenses/cddl1.txt
*
* The Original Code is Drombler.org. The Initial Developer of the
* Original Code is Florian Brunner (GitHub user: puce77).
* Copyright 2015 Drombler.org. All Rights Reserved.
*
* Contributor(s): .
*/
package org.drombler.commons.docking.context.impl;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.drombler.commons.action.command.Savable;
import org.drombler.commons.context.Context;
import org.drombler.commons.context.ContextEvent;
import org.drombler.commons.context.ContextListener;
import org.drombler.commons.context.Contexts;
import org.drombler.commons.context.LocalContextProvider;
import org.drombler.commons.docking.DockableData;
import org.drombler.commons.docking.DockableEntry;
import org.drombler.commons.docking.context.DockingAreaContainer;
import org.softsmithy.lib.util.SetChangeEvent;
import org.softsmithy.lib.util.SetChangeListener;
/**
* This manager listens for {@link Savable} in the local contexts of the Dockables and synchronizes the {@link FXDockableData#modifiedProperty()} accordingly.
*
* @author puce
* @param
* @param
* @param
*/
public class DockableDataModifiedManager> implements AutoCloseable {
private final Map savableListeners = new HashMap<>();
private final SetChangeListener dockablesListener = new SetChangeListener() {
@Override
public void elementAdded(SetChangeEvent event) {
final E dockableEntry = event.getElement();
final D dockable = dockableEntry.getDockable();
if (dockable instanceof LocalContextProvider) {
Context localContext = Contexts.getLocalContext(dockable);
final ContextListener savableListener = (ContextEvent contextEvent)
-> updateDockableDataModified(dockableEntry.getDockableData(), localContext);
savableListeners.put(dockable, savableListener);
localContext.addContextListener(Savable.class, savableListener);
updateDockableDataModified(dockableEntry.getDockableData(), localContext);
}
}
@Override
public void elementRemoved(SetChangeEvent event) {
final E dockableEntry = event.getElement();
final D dockable = dockableEntry.getDockable();
if (dockable instanceof LocalContextProvider) {
ContextListener savableListener = savableListeners.remove(dockable);
removeContextListener(dockable, savableListener);
}
}
};
private final DockingAreaContainer dockingAreaContainer;
public DockableDataModifiedManager(DockingAreaContainer dockingAreaContainer) {
this.dockingAreaContainer = dockingAreaContainer;
this.dockingAreaContainer.addDockableSetChangeListener(dockablesListener);
}
private void removeContextListener(D dockable, ContextListener savableListener) {
Context localContext = Contexts.getLocalContext(dockable);
localContext.removeContextListener(Savable.class, savableListener);
}
private void updateDockableDataModified(DATA dockableData, Context localContext) {
dockableData.setModified(localContext.find(Savable.class) != null);
}
@Override
public void close() {
// TODO: handle vizualized/ unhandled Dockables?
dockingAreaContainer.removeDockableSetChangeListener(dockablesListener);
for (Iterator> iterator = savableListeners.entrySet().iterator();
iterator.hasNext();) {
Map.Entry entry = iterator.next();
removeContextListener(entry.getKey(), entry.getValue());
iterator.remove();
}
}
}