/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 Neil C Smith.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 3 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 3 for more details.
*
* You should have received a copy of the GNU General Public License version 3
* along with this work; if not, see http://www.gnu.org/licenses/
*
*
* Please visit http://neilcsmith.net if you need additional information or
* have any questions.
*/
package net.neilcsmith.praxis.live.core;
import java.awt.EventQueue;
import java.lang.reflect.InvocationTargetException;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Map;
import net.neilcsmith.praxis.core.Component;
import net.neilcsmith.praxis.core.ControlAddress;
import net.neilcsmith.praxis.core.Lookup;
import net.neilcsmith.praxis.core.VetoException;
import net.neilcsmith.praxis.gui.BindingContext;
import net.neilcsmith.praxis.gui.ControlBinding;
import net.neilcsmith.praxis.gui.ControlBinding.Adaptor;
import net.neilcsmith.praxis.gui.impl.DefaultBindingControl;
import net.neilcsmith.praxis.impl.AbstractRoot.Caps;
import net.neilcsmith.praxis.impl.AbstractSwingRoot;
import net.neilcsmith.praxis.impl.InstanceLookup;
import org.openide.util.Exceptions;
/**
*
* @author Neil C Smith (http://neilcsmith.net)
*/
class ExtensionContainer extends AbstractSwingRoot {
private static final String EXT_PREFIX = "_ext_";
private Component[] extensions;
private Map<ControlAddress, DefaultBindingControl> bindingCache;
private Lookup lookup;
// private Bindings bindings;
ExtensionContainer(Component[] extensions) {
super(EnumSet.noneOf(Caps.class));
this.extensions = extensions.clone();
bindingCache = new HashMap<ControlAddress, DefaultBindingControl>();
}
@Override
protected void setup() {
super.setup();
installExtensionsImpl();
}
@Override
protected void dispose() {
super.dispose();
uninstallExtensionsImpl();
// clearBindings();
}
@Override
public Lookup getLookup() {
if (lookup == null) {
lookup = InstanceLookup.create(super.getLookup(), new Bindings());
}
return lookup;
}
@Override
public void hierarchyChanged() {
super.hierarchyChanged();
lookup = null;
}
void uninstallExtensions() {
if (EventQueue.isDispatchThread()) {
uninstallExtensionsImpl();
} else {
try {
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
uninstallExtensionsImpl();
}
});
} catch (InterruptedException ex) {
Exceptions.printStackTrace(ex);
} catch (InvocationTargetException ex) {
Exceptions.printStackTrace(ex);
}
}
}
private void installExtensionsImpl() {
for (Component ext : extensions) {
String id = EXT_PREFIX + Integer.toHexString(System.identityHashCode(ext));
try {
addChild(id, ext);
} catch (VetoException ex) {
Exceptions.printStackTrace(ex);
}
}
}
private void uninstallExtensionsImpl() {
String[] ids = getChildIDs();
for (String id : ids) {
removeChild(id);
}
clearBindings();
}
private void clearBindings() {
for (DefaultBindingControl binding : bindingCache.values()) {
binding.unbindAll();
}
}
private class Bindings extends BindingContext {
@Override
public void bind(ControlAddress address, Adaptor adaptor) {
DefaultBindingControl binding = bindingCache.get(address);
if (binding == null) {
binding = new DefaultBindingControl(address);
registerControl("_binding_" + Integer.toHexString(binding.hashCode()),
binding);
bindingCache.put(address, binding);
}
binding.bind(adaptor);
}
@Override
public void unbind(Adaptor adaptor) {
ControlBinding cBinding = adaptor.getBinding();
if (cBinding == null) {
return;
}
DefaultBindingControl binding = bindingCache.get(cBinding.getAddress());
if (binding != null) {
binding.unbind(adaptor);
}
}
}
}