package com.framsticks.gui; import org.apache.log4j.Logger; import com.framsticks.core.Tree; import com.framsticks.core.Node; import com.framsticks.core.Path; import com.framsticks.core.TreeOperations; import com.framsticks.gui.controls.ValueControl; import com.framsticks.params.CompositeParam; import com.framsticks.params.FramsClass; import java.util.*; import javax.swing.tree.TreePath; import com.framsticks.util.dispatching.FutureHandler; import com.framsticks.util.lang.Casting; /** * @author Piotr Sniegowski */ public class TreeAtFrame { private static final Logger log = Logger.getLogger(TreeAtFrame.class); protected final Frame frame; protected final Tree tree; protected final Map knownPanels = new HashMap(); protected Node rootNode; protected Map nodesStorage = new WeakHashMap<>(); public TreeAtFrame(Tree tree, Frame frame) { this.frame = frame; this.tree = tree; } public Frame getFrame() { return frame; } /** * @return the tree */ public Tree getTree() { return tree; } public void registerPanel(Panel panel) { } public Panel findPanel(String accessId) { assert frame.isActive(); return (knownPanels.containsKey(accessId) ? knownPanels.get(accessId) : null); } public final String getName() { return tree.getName(); } public Panel preparePanel(CompositeParam param, FramsClass framsClass) { assert frame.isActive(); Panel panel = preparePanelImpl(param, framsClass); assert panel != null; String accessId = param.computeAccessId(); panel.uniqueName = accessId + "@" + tree.getName(); knownPanels.put(accessId, panel); frame.cardPanel.add(panel, panel.uniqueName); log.debug("prepared panel for " + panel); return panel; } protected Panel preparePanelImpl(CompositeParam param, FramsClass framsClass) { assert frame.isActive(); List panels = new ArrayList(); Panel.Parameters parameters = new Panel.Parameters(this, param, framsClass); for (PanelProvider pp : frame.browser.panelProviders) { Panel p = pp.providePanel(parameters); if (p != null) { panels.add(p); } } if (panels.isEmpty()) { return new EmptyPanel(parameters); } if (panels.size() == 1) { return panels.get(0); } return new MultiPanel(parameters, panels); } public boolean hasLocalChanges(TreePath treePath) { NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent()); if (nodeAtFrame == null) { return false; } return !nodeAtFrame.localChanges.isEmpty(); } public NodeAtFrame assureLocalInfo(TreePath treePath) { assert frame.isActive(); NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent()); if (nodeAtFrame == null) { nodeAtFrame = new NodeAtFrame(); nodesStorage.put(Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()), nodeAtFrame); } return nodeAtFrame; } public NodeAtFrame getLocalInfo(TreePath treePath) { return nodesStorage.get(treePath.getLastPathComponent()); } public boolean changeValue(TreePath treePath, ValueControl component, Object newValue) { log.debug("changing value of " + component + " to '" + newValue + "'"); assureLocalInfo(treePath).localChanges.put(component, newValue); return true; } public void pushLocalChanges(TreePath treePath) { assert frame.isActive(); NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent()); if (nodeAtFrame == null) { return; } Path path = frame.treeModel.convertToPath(treePath); for (Map.Entry e : nodeAtFrame.localChanges.entrySet()) { TreeOperations.set(path, e.getKey().getParam(), e.getValue(), new FutureHandler(frame) { @Override protected void result(Integer flag) { } }); } } public void fillPanelWithValues(TreePath treePath) { NodeAtFrame nodeAtFrame = assureLocalInfo(treePath); if (nodeAtFrame == null) { return; } if (nodeAtFrame.panel == null) { return; } Node node = TreeNode.tryGetNode(treePath); if (node == null) { return; } nodeAtFrame.panel.setCurrentTreePath(treePath); nodeAtFrame.panel.pullValuesFromLocalToUser(TreeOperations.bindAccess(node)); frame.showPanel(nodeAtFrame.panel); } public void useOrCreatePanel(TreePath treePath) { // node.assureResolved(); Node node = TreeNode.tryGetNode(treePath); NodeAtFrame nodeAtFrame = assureLocalInfo(treePath); if (nodeAtFrame.panel == null) { CompositeParam param = node.getParam(); nodeAtFrame.panel = findPanel(param.computeAccessId()); if (nodeAtFrame.panel == null) { FramsClass framsClass = node.getTree().getInfoFromCache(param.getContainedTypeName()); nodeAtFrame.panel = preparePanel(param, framsClass); } } fillPanelWithValues(treePath); } }