Ignore:
Timestamp:
07/08/13 23:04:56 (11 years ago)
Author:
psniegowski
Message:

HIGHLIGHTS:

CHANGELOG:
Get data also on tree expansion.

Use nice framstick icon for empty nodes.

Update panel after reload if it is current.

Add shallow reload procedure.

Cut Gui prefix from several tree classes.

Bring back counter of GuiTreeNode?.

Use IdentityHashMap? were it is more appriopriate.

Remove TreeListener?.

Do not use TreeListener? in GUI.

Minor change.

Done migration to GuiTreeModel?.

BrowserTest? in that version always crashes frams.linux.

Move rendering implementation into GuiAbstractNode?.

Use hand-crafted list in GuiTreeNode?.

Generally, it would be a great place for WeakIdentityHashMap?
(but there is none in Java Collection Framework).

Remove superfluous logging.

Fix bug in GuiTreeNode?.

Use IdentityHashMap? instead of HashMap?.

Improve structure update.

Filter out invalid uids in UniqueListAccess?.

Improve TreeCellRenderer?.

Add filtering in TrackConsole?.

Improve TreeModel?.

More changes.

More improvements.

More changes.

Remove TreeNode?.

Support MetaNode? in the GuiTreeModel?.

Implement more in GuiTreeModel?.

Add CompositeParam? interface to FramsClass? and AccessInterface?.

Allow access by number to UniqueList?.

Add UidComparator?.

Use TreeMap? as a default accessee in unique list.

It keeps order of keys.

Introduce classes to use with new TreeModel?.

Another step.

Migrate from TreeNode? to Node in many places.

Remove some uses of TreeNode? as DefaultMutableTreeNode?.

Remove Path from TreeNode? interface.

Remove Path from TreeNode?.

Add Path recration from node feature.

Reworking TreeCellRenderer?.

Minor change of TreeOperations? interface.

Remove last methods from TreeNode?.

Another minor step.

Do not store reference to TreeAtFrame? in TreeNode?.

Add proxy exceptionHandler to StatusBar?.

Move panels management to TreeAtFrame?.

Store localChanges in the NodeAtFrame?.

More cleanup.

Move name computing to TreeCellRenderer?.

Move tooltip and icon computations to TreeCellRenderer?.

More dispatches removed.

Remove most dispatching from TreeNode?.

TreeNode? does not actually redispatch tasks.

Make Tree embedded in Browser use SwingDispatcher?.

Make lazy binding of Tree with Dispatcher.

Minor changes.

Organizational change in AbstractTree?.

Make AbstractTree? compose from Thread instead of inherit from it.

Make SwingDispatcher? and AtOnceDispatcher? Joinable compatible.

Add ListPanelProvider?.

Improve Controls readonly and enabled handling.

Properly pass ExceptionHandlers? in more places.

Make Tree.get accept ValueParam?.

  • This is to allow access number of list elements.

Remove not needed get redirection in ClientAtServer?.

Rename tryResolve to tryGet.

Unify tryResolveAndGet into tryResolve.

Remove resolveTop from Tree interface.

Make Tree.get accept Future<Path>.

Use get to implement resolveTop also in ObjectTree?.

Unify resolveTop and get in RemoteTree?.

Another minor step.

More minor changes in tree operations.

Minor organizational changes.

In RemoteTree? first fetch info for root.

Reworking resolving.

Minor changes.

Make ListAccess? return proxy iterators (instead of creating temporary collection).

Let AccessInterface? return Iterable<Param>.

Improve resolving.

More improvements.

First working completion in ManagedConsole?.

Rename resolve to resolveTop.

This reflects the actuall functionality.

Change semantic of tryResolve and tryResolveAndGet.

Location:
java/main/src/main/java/com/framsticks/gui
Files:
6 added
1 deleted
25 edited

Legend:

Unmodified
Added
Removed
  • java/main/src/main/java/com/framsticks/gui/Browser.java

    r97 r98  
    1414import com.framsticks.util.dispatching.ExceptionResultHandler;
    1515import com.framsticks.util.dispatching.Future;
    16 import com.framsticks.util.dispatching.FutureHandler;
    1716import com.framsticks.util.dispatching.Joinable;
    1817import com.framsticks.util.dispatching.JoinableCollection;
     
    4645
    4746        protected final List<PopupMenuEntryProvider> popupMenuEntryProviders = new LinkedList<>();
     47        // protected final SwingDispatcher
    4848
    4949        protected final MainFrame mainFrame;
     
    6363
    6464                mainFrame = new MainFrame(Browser.this);
     65
     66                // mainFrame.getStatusBar().setExceptionHandler(ThrowExceptionHandler.getInstance());
     67
    6568                addFrame(mainFrame);
    6669
     
    120123        public void addTree(Tree tree) {
    121124                log.info("adding tree: " + tree);
     125                tree.setDispatcher(new SwingDispatcher<Tree>());
    122126                trees.add(tree);
    123127        }
    124128
    125129        public void autoResolvePath(final String path, final Future<Path> future) {
    126                 final Tree i = trees.get("localhost");
    127                 i.dispatch(new RunAt<Tree>(future) {
    128                         @Override
    129                         protected void runAt() {
    130                                 TreeOperations.resolveAndGet(i, path, new FutureHandler<Path>(future) {
    131                                         @Override
    132                                         protected void result(final Path p) {
    133                                                 future.pass(p);
    134                                                 mainFrame.dispatch(new RunAt<Frame>(future) {
    135                                                         @Override
    136                                                         protected void runAt() {
    137                                                                 mainFrame.goTo(p);
    138                                                         }
    139                                                 });
    140                                         }
    141                                 });
    142                         }
    143                 });
     130                // final Tree i = trees.get("localhost");
     131                // i.dispatch(new RunAt<Tree>(future) {
     132                //      @Override
     133                //      protected void runAt() {
     134                //              TreeOperations.tryGet(i, path, new FutureHandler<Path>(future) {
     135                //                      @Override
     136                //                      protected void result(final Path p) {
     137                //                              future.pass(p);
     138                //                              mainFrame.dispatch(new RunAt<Frame>(future) {
     139                //                                      @Override
     140                //                                      protected void runAt() {
     141                //                                              mainFrame.goTo(p);
     142                //                                      }
     143                //                              });
     144                //                      }
     145                //              });
     146                //      }
     147                // });
    144148        }
    145149
     
    284288        }
    285289
    286         // @Override
    287         // public boolean isDone() {
    288         //      return frames.isDone() && trees.isDone();
     290        // final protected Map<EventParam, Subscription<?>> userSubscriptions = new HashMap<>();
     291        // public boolean hasSubscribed(EventParam param) {
     292        //      assert frame.isActive();
     293        //      return userSubscriptions.containsKey(param);
    289294        // }
     295
     296        // public void unsubscribe(EventParam eventParam) {
     297        //      assert frame.isActive();
     298        //      if (!hasSubscribed(eventParam)) {
     299        //              log.error("could not unsubscribe from " + eventParam);
     300        //              return;
     301        //      }
     302        //      userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
     303        //      userSubscriptions.remove(eventParam);
     304        // }
     305
     306
     307
     308
    290309}
  • java/main/src/main/java/com/framsticks/gui/Frame.java

    r97 r98  
    1111import java.awt.event.MouseAdapter;
    1212import java.awt.event.MouseEvent;
    13 import java.util.HashMap;
     13import java.util.IdentityHashMap;
    1414import java.util.Map;
    1515
     
    2828import javax.swing.ToolTipManager;
    2929import javax.swing.UIManager;
    30 import javax.swing.event.TreeModelEvent;
    31 import javax.swing.event.TreeModelListener;
     30import javax.swing.event.TreeExpansionEvent;
     31import javax.swing.event.TreeExpansionListener;
    3232import javax.swing.event.TreeSelectionEvent;
    3333import javax.swing.event.TreeSelectionListener;
    34 import javax.swing.tree.DefaultMutableTreeNode;
    35 import javax.swing.tree.DefaultTreeModel;
    3634import javax.swing.tree.DefaultTreeSelectionModel;
    3735import javax.swing.tree.TreePath;
     
    4038import org.apache.log4j.Logger;
    4139
     40import com.framsticks.core.Mode;
    4241import com.framsticks.core.Path;
    4342import com.framsticks.core.Tree;
     43import com.framsticks.core.TreeOperations;
    4444import com.framsticks.gui.view.TreeCellRenderer;
    45 import com.framsticks.util.FramsticksException;
     45import com.framsticks.params.AccessInterface;
    4646import com.framsticks.util.dispatching.Dispatching;
    47 import com.framsticks.util.dispatching.ExceptionResultHandler;
     47import com.framsticks.util.dispatching.FutureHandler;
    4848import com.framsticks.util.dispatching.Joinable;
    4949import com.framsticks.util.dispatching.JoinableCollection;
    5050import com.framsticks.util.dispatching.JoinableParent;
    5151import com.framsticks.util.dispatching.JoinableState;
    52 import com.framsticks.util.dispatching.RunAt;
    53 import com.framsticks.util.lang.ScopeEnd;
    5452import com.framsticks.util.swing.KeyboardModifier;
    5553import com.framsticks.util.swing.MenuConstructor;
     
    7270        protected JScrollPane treeScrollPane;
    7371        protected JTree jtree;
    74         protected DefaultTreeModel treeModel;
    75         protected javax.swing.tree.MutableTreeNode rootNode;
     72        protected TreeModel treeModel;
     73
     74        protected MetaNode rootNode;
     75
    7676        protected JPanel treePanel;
    7777        protected JPopupMenu treePopupMenu;
    7878        protected JMenuItem treePopupMenuHeader;
    7979
    80         TreeNode currentlyPoppedTreeNode;
    8180        protected JPanel mainPanel;
    8281        protected JPanel leftPanel;
     
    9190        protected JMenu helpMenu;
    9291
    93         protected final Map<Tree, TreeAtFrame> treeAtFrames = new HashMap<Tree, TreeAtFrame>();
    94         protected JoinableCollection<Tree> trees = new JoinableCollection<Tree>();
     92        protected final Map<Tree, TreeAtFrame> treeAtFrames = new IdentityHashMap<>();
     93        protected JoinableCollection<Tree> trees = new JoinableCollection<>();
    9594
    9695        public Frame(Browser browser) {
     
    106105                log.debug("creating " + this);
    107106
    108 
    109107                Container contentPane = getSwing().getContentPane();
    110108                treePopupMenu = new JPopupMenu("title");
     
    114112                treePanel.setLayout(new BorderLayout());
    115113
    116                 treeModel = new DefaultTreeModel(null);
    117                 treeModel.addTreeModelListener(new TreeModelListener() {
    118 
    119                         @Override
    120                         public void treeNodesChanged(TreeModelEvent arg0) {
    121                                 log.trace("treeNodesChanged: " + arg0);
    122                         }
    123 
    124                         @Override
    125                         public void treeNodesInserted(TreeModelEvent arg0) {
    126                                 // log.trace("treeNodesInserted: " + arg0);
    127                         }
    128 
    129                         @Override
    130                         public void treeNodesRemoved(TreeModelEvent arg0) {
    131                                 log.trace("treeNodesRemoved: " + arg0);
    132                         }
    133 
    134                         @Override
    135                         public void treeStructureChanged(TreeModelEvent arg0) {
    136                                 log.trace("treeStructureChanged: " + arg0);
    137                         }
    138                 });
     114                rootNode = new MetaNode();
     115                rootNode.setName("root");
     116                treeModel = new TreeModel(this);
    139117
    140118                jtree = new JTree(treeModel);
     
    152130                });
    153131
     132                jtree.addTreeExpansionListener(new TreeExpansionListener() {
     133
     134                        @Override
     135                        public void treeCollapsed(TreeExpansionEvent e) {
     136
     137                        }
     138
     139                        @Override
     140                        public void treeExpanded(TreeExpansionEvent e) {
     141                                loadChildren(treeModel.convertToPath(e.getPath()), false);
     142                        }
     143                });
     144
    154145                jtree.setExpandsSelectedPaths(true);
    155146                jtree.setEditable(false);
    156                 jtree.setDoubleBuffered(true);
    157147                jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    158148                jtree.setShowsRootHandles(true);
     
    173163                });
    174164
    175                 new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED).join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)).join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)).join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)).join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
     165                new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED)
     166                        .join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0))
     167                        .join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0))
     168                        .join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0))
     169                        .join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
    176170
    177171                jtree.setCellRenderer(new TreeCellRenderer());
     
    182176                treePanel.add(treeScrollPane);
    183177
    184                 rootNode = new DefaultMutableTreeNode();
    185                 rootNode.setUserObject("root");
    186                 treeModel.setRoot(rootNode);
    187178
    188179                normalWorkPanel = new JPanel();
     
    248239                });
    249240
     241                new MenuConstructor(fileMenu).add(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK), new AbstractAction("Reload current") {
     242                        @Override
     243                        public void actionPerformed(ActionEvent actionEvent) {
     244
     245                                loadPath(treeModel.convertToPath(jtree.getSelectionPath()), true);
     246                        }
     247                });
     248
    250249        }
    251250
     
    254253        }
    255254
    256         public void addRootPath(Path path) {
     255        public void addRootPath(final Path path) {
    257256                assert isActive();
     257
    258258                Tree tree = path.getTree();
     259
     260                log.info("trying mount: " + path);
     261                if (!tree.getAssignedRoot().isResolved()) {
     262                        tree.get(path, Mode.FETCH, new FutureHandler<Path>(this) {
     263
     264                                @Override
     265                                protected void result(Path result) {
     266                                        addRootPath(result);
     267                                }
     268                        });
     269                        return;
     270                }
     271
    259272                assert browser.getTrees().contains(tree);
    260273
    261274                TreeAtFrame e = new TreeAtFrame(tree, this);
    262                 tree.addListener(e);
    263275                treeAtFrames.put(tree, e);
    264                 TreeNode node = new TreeNode(e, path);
    265                 e.rootTreeNode = node;
    266                 treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
    267                 jtree.expandPath(new TreePath(rootNode));
     276
     277                rootNode.getChildren().add(new TreeNode(tree.getAssignedRoot()));
     278                e.rootNode = tree.getAssignedRoot();
     279                treeModel.nodeStructureChanged(new TreePath(rootNode));
     280                // jtree.expandPath(new TreePath(rootNode));
    268281        }
    269282
     
    275288        }
    276289
     290
    277291        private void showPopup(MouseEvent e) {
    278292                assert isActive();
     
    280294                        return;
    281295                }
    282                 currentlyPoppedTreeNode = findTreeNodeByTreePath(jtree.getPathForLocation(e.getX(), e.getY()));
    283                 if (currentlyPoppedTreeNode == null) {
    284                         return;
    285                 }
    286 
    287                 Path path = currentlyPoppedTreeNode.getTreePath();
     296                TreePath treePath = jtree.getPathForLocation(e.getX(), e.getY());
     297
     298                Path path = treeModel.convertToPath(treePath);
    288299                treePopupMenu.removeAll();
    289300
     
    291302                        provider.provide(treePopupMenu, path);
    292303                }
    293                 // treePopupMenuHeader.setText(path.getTree().getName() + path.getTextual());
    294304                treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
    295                 //currentlyPoppedPanel.getNode().getFramsClass().getName()
    296         }
    297 
    298         public TreeNode getCurrentlyPoppedTreeNode() {
    299                 assert isActive();
    300                 return currentlyPoppedTreeNode;
    301305        }
    302306
    303307        public void clear() {
    304                 treeModel.setRoot(null);
    305308                cardPanel.removeAll();
    306309                cardPanel.updateUI();
     
    308311        }
    309312
    310         public ScopeEnd startChange(final DefaultMutableTreeNode node) {
    311                 assert isActive();
    312                 final TreePath selection = jtree.getSelectionPath();
    313                 return new ScopeEnd() {
    314                         @Override
    315                         public void close() {
    316                                 assert isActive();
    317                                 treeModel.nodeChanged(node);
    318                                 jtree.setSelectionPath(selection);
    319                         }
    320                 };
    321         }
    322 
    323         public void selectTreeNode(final TreeNode treeNode) {
    324                 assert isActive();
    325                 /*              final Panel panel = treeNode.getOrCreatePanel();
    326                  if (panel == null) {
    327                  return;
    328                  }
    329                  panel.setCurrentTreeNode(treeNode);
    330                  treeNode.updateData();
    331                  showPanel(panel);*/
    332         }
    333 
    334         public TreeNode findTreeNodeByTreePath(TreePath treePath) {
     313        public void loadChildren(Path path, boolean reload) {
     314                if (path == null) {
     315                        return;
     316                }
     317                AccessInterface access = TreeOperations.bindAccess(path);
     318
     319                int count = access.getCompositeParamCount();
     320                for (int i = 0; i < count; ++i) {
     321                        Path childPath = path.appendParam(access.getCompositeParam(i)).tryFindResolution();
     322                        loadPath(childPath, reload);
     323                }
     324
     325        }
     326
     327        public void loadPath(Path path, boolean reload) {
     328                if (path == null) {
     329                        return;
     330                }
     331                if (path.isResolved() && !reload) {
     332                        return;
     333                }
     334                path.getTree().get(path, Mode.FETCH, new FutureHandler<Path>(this) {
     335                        @Override
     336                        protected void result(Path result) {
     337                                final TreePath treePath = treeModel.convertToTreePath(result);
     338
     339                                treeModel.nodeStructureChanged(treePath);
     340                                if (treePath.equals(jtree.getSelectionPath())) {
     341                                        treeAtFrames.get(result.getTree()).useOrCreatePanel(treePath);
     342                                }
     343                        }
     344                });
     345        }
     346
     347        public void chooseTreeNode(final TreePath treePath) {
    335348                assert isActive();
    336349                if (treePath == null) {
    337                         return null;
    338                 }
    339                 if (!(treePath.getLastPathComponent() instanceof TreeNode)) {
    340                         return null;
    341                 }
    342                 return (TreeNode) treePath.getLastPathComponent();
    343         }
    344 
    345         public void chooseTreeNode(TreePath treePath) {
    346                 assert isActive();
    347                 final TreeNode treeNode = findTreeNodeByTreePath(treePath);
    348                 if (treeNode == null) {
    349                         return;
    350                 }
    351                 treeNode.select();
    352         }
    353 
    354         protected final ExceptionResultHandler dialogHandler = new ExceptionResultHandler() {
    355 
    356                 @Override
    357                 public void handle(FramsticksException exception) {
    358                         //TODO TEH
    359                         throw exception;
    360 
    361                 }
    362         };
    363 
    364         public void goTo(Path path) {
    365                 assert isActive();
    366                 final TreePath treePath = treeAtFrames.get(path.getTree()).getTreePath(path, false);
    367                 log.info("go to path: " + path + "(" + treePath + ")");
    368 
    369                 this.dispatch(new RunAt<Frame>(dialogHandler) {
    370                         @Override
    371                         protected void runAt() {
    372                                 log.info("executed");
    373                                 jtree.setSelectionPath(treePath);
    374                                 jtree.makeVisible(treePath);
    375                                 assert jtree.isVisible(treePath);
    376                         }
    377                 });
    378 
    379         }
    380 
    381         public void addNode(TreeNode child, DefaultMutableTreeNode parent) {
    382                 assert isActive();
    383 
    384                 try (ScopeEnd e = startChange(parent)) {
    385                         treeModel.insertNodeInto(child, parent, parent.getChildCount());
    386                 }
    387         }
     350                        return;
     351                }
     352                if (treeModel.isChanging()) {
     353                        return;
     354                }
     355
     356                Path path = treeModel.convertToPath(treePath);
     357                if (path == null) {
     358                        return;
     359                }
     360                path = path.assureResolved();
     361                final Tree tree = path.getTree();
     362
     363                treeAtFrames.get(tree).useOrCreatePanel(treePath);
     364                loadChildren(path, false);
     365
     366        }
     367
     368
     369        // public void goTo(Path path) {
     370        //      assert isActive();
     371        //      final TreePath treePath = treeModel.convertToTreePath(path);
     372        //      log.info("go to path: " + path + "(" + treePath + ")");
     373
     374        //      this.dispatch(new RunAt<Frame>(this) {
     375        //              @Override
     376        //              protected void runAt() {
     377        //                      log.info("executed");
     378        //                      jtree.setSelectionPath(treePath);
     379        //                      jtree.makeVisible(treePath);
     380        //                      assert jtree.isVisible(treePath);
     381        //              }
     382        //      });
     383
     384        // }
    388385
    389386        @Override
     
    422419        }
    423420
     421        /**
     422         * @return the treeModel
     423         */
     424        public TreeModel getTreeModel() {
     425                return treeModel;
     426        }
     427
    424428}
  • java/main/src/main/java/com/framsticks/gui/ImageProvider.java

    r90 r98  
    77
    88import javax.swing.*;
     9
    910import java.util.HashMap;
    10 import java.util.LinkedHashMap;
     11import java.util.Map;
    1112
    1213/**
     
    2122         * HashMap stores icons. Key is icon path, Value is icon.
    2223         */
    23         private static HashMap<String, ImageIcon> icons = new LinkedHashMap<String, ImageIcon>();
     24        private static Map<String, ImageIcon> icons = new HashMap<String, ImageIcon>();
    2425
    2526        public static final String IMAGE = "image.png";
    2627        public static final String LOGO = "logo.png";
    2728
    28         //public static final String FOLDER_OPEN = "folder_open.png";
    29         //public static final String FOLDER_CLOSED = "folder_close.png";
    30         //public static final String NODE = "node.png";
     29        public static final String FOLDER_OPEN = "folder_open.png";
     30        public static final String FOLDER_CLOSED = "folder_close.png";
     31        public static final String NODE = "node.png";
    3132
    3233        public static final String SERVER = "server.png";
  • java/main/src/main/java/com/framsticks/gui/ModifiablePanel.java

    r97 r98  
    22
    33import org.apache.log4j.Logger;
     4
    45
    56import javax.swing.*;
     
    6566        }
    6667
    67         @Override
    68         public void setCurrentTreeNode(TreeNode node) {
    69                 super.setCurrentTreeNode(node);
    70         }
    71 
    7268        protected abstract void applyChanges();
    7369
  • java/main/src/main/java/com/framsticks/gui/MultiPanel.java

    r97 r98  
    44
    55import javax.swing.*;
     6import javax.swing.tree.TreePath;
     7
    68import java.awt.*;
    79import java.util.List;
     
    4648
    4749        @Override
    48         public void setCurrentTreeNode(TreeNode currentTreeNode) {
    49                 super.setCurrentTreeNode(currentTreeNode);
     50        public void setCurrentTreePath(TreePath currentTreePath) {
     51                super.setCurrentTreePath(currentTreePath);
    5052                for (Panel p : panels) {
    51                         p.setCurrentTreeNode(currentTreeNode);
     53                        p.setCurrentTreePath(currentTreePath);
    5254                }
    5355        }
  • java/main/src/main/java/com/framsticks/gui/ObjectPanel.java

    r97 r98  
    1212
    1313import javax.swing.*;
     14import javax.swing.tree.TreePath;
    1415
    1516import java.util.Collection;
    16 import java.util.HashMap;
     17import java.util.IdentityHashMap;
    1718import java.util.Map;
    1819import static com.framsticks.util.lang.Containers.filterInstanceof;
    1920
    2021import com.framsticks.util.FramsticksException;
    21 import com.framsticks.util.dispatching.RunAt;
    2222
    2323@SuppressWarnings("serial")
    2424public class ObjectPanel extends ModifiablePanel implements ControlOwner {
    2525
    26         private static final Logger log = Logger.getLogger(ObjectPanel.class.getName());
     26        private static final Logger log = Logger.getLogger(ObjectPanel.class);
    2727
    28         final protected Map<Param, Control> components = new HashMap<Param, Control>();
    29         final protected Map<ValueParam, ValueControl> valueControls = new HashMap<ValueParam, ValueControl>();
     28        final protected Map<Param, Control> components = new IdentityHashMap<Param, Control>();
     29        final protected Map<ValueParam, ValueControl> valueControls = new IdentityHashMap<ValueParam, ValueControl>();
    3030
    3131        public ObjectPanel(Panel.Parameters parameters, Collection<Param> params) {
     
    3737                for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
    3838                        valueControls.put(c.getParam(), c);
     39                        c.setUserEnabled(true);
    3940                        c.setListener(new ValueControlListener() {
    4041                                @Override
    4142                                public boolean onChange(Object newValue) {
    42                                         if (currentTreeNode == null) {
     43                                        if (currentTreePath == null) {
    4344                                                return true;
    4445                                        }
    45                                         boolean result = currentTreeNode.changeValue(c, newValue);
     46                                        boolean result = treeAtFrame.changeValue(currentTreePath, c, newValue);
    4647                                        refreshControlButtons();
    4748                                        return result;
     
    5758        protected void applyChanges() {
    5859                assert frame.isActive();
    59                 assert currentTreeNode != null;
    60                 currentTreeNode.pushLocalChanges();
     60                assert currentTreePath != null;
     61                treeAtFrame.pushLocalChanges(currentTreePath);
    6162        }
    6263
    6364        protected void refreshControlButtons() {
    6465                assert frame.isActive();
    65                 applyButton.setEnabled(currentTreeNode.localChanges != null);
     66                applyButton.setEnabled(treeAtFrame.hasLocalChanges(currentTreePath));
    6667        }
    6768
     
    7172        @Override
    7273        public void pullValuesFromLocalToUser(AccessInterface access) {
    73                 assert currentTreeNode != null;
    74                 assert currentTreeNode.path.getTree().isActive();
     74                assert currentTreePath != null;
    7575                log.debug("refreshing components");
    7676
    77                 final Map<ValueControl, Object> values = new HashMap<ValueControl, Object>();
     77                final Map<ValueControl, Object> values = new IdentityHashMap<ValueControl, Object>();
    7878                for (Map.Entry<ValueParam, ValueControl> e : valueControls.entrySet()) {
    7979                        values.put(e.getValue(), access.get(e.getKey().getId(), Object.class));
    8080                }
    8181
    82                 frame.dispatch(new RunAt<Frame>(frame) {
    83                         @Override
    84                         protected void runAt() {
    85                                 if (currentTreeNode.localChanges != null) {
    86                                         for (Map.Entry<ValueControl, Object> e : currentTreeNode.localChanges.entrySet()) {
    87                                                 values.put(e.getKey(), e.getValue());
    88                                         }
    89                                 }
    90                                 for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
    91                                         e.getKey().pushValueToUserInterface(e.getValue());
    92                                 }
    93                                 refreshControlButtons();
    94                                 ObjectPanel.this.revalidate();
     82
     83                NodeAtFrame nodeAtFrame = treeAtFrame.getLocalInfo(currentTreePath);
     84                if (nodeAtFrame != null) {
     85                        for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
     86                                values.put(e.getKey(), e.getValue());
    9587                        }
    96                 });
     88                }
     89
     90                for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
     91                        e.getKey().pushValueToUserInterface(e.getValue());
     92                }
     93                refreshControlButtons();
     94                ObjectPanel.this.revalidate();
    9795
    9896        }
     
    109107
    110108        @Override
    111         public TreeNode getCurrentTreeNode() {
    112                 return super.getCurrentTreeNode();
    113         }
    114 
    115         @Override
    116109        public void handle(FramsticksException exception) {
    117110                frame.handle(exception);
    118111        }
    119112
    120         // public void updateValue() {
    121         //      //assert panel.getFrame().isActive();
     113        @Override
     114        public TreePath getCurrentTreePath() {
     115                return super.getCurrentTreePath();
     116        }
    122117
    123         //      final Node n = panel.getCurrentNode();
    124         //      panel.getBrowser().getManager().invokeLater(new Runnable() {
    125         //              @Override
    126         //              public void run() {
    127         //                      Object v = n.getAccess().get(param, Object.class);
    128         //                      if (v == null) {
    129         //                              v = param.getDef(Object.class);
    130         //                      }
    131         //                      final Object fv = v;
    132         //                      panel.getBrowser().invokeLater(new Runnable() {
    133         //                              @Override
    134         //                              public void run() {
    135         //                                      setValueImpl(fv);
    136         //                              }
    137         //                      });
    138         //              }
    139         //      });
    140         // }
    141118
    142119}
  • java/main/src/main/java/com/framsticks/gui/Panel.java

    r97 r98  
    44import com.framsticks.params.CompositeParam;
    55import com.framsticks.params.FramsClass;
    6 // import org.apache.log4j.Logger;
    76
    87import javax.swing.*;
     8import javax.swing.tree.TreePath;
     9
     10import org.apache.log4j.Logger;
    911
    1012/**
     
    1315@SuppressWarnings("serial")
    1416public abstract class Panel extends JPanel {
     17
     18        private static final Logger log = Logger.getLogger(Panel.class);
     19
    1520
    1621        public static class Parameters {
     
    2833        // private static final Logger log = Logger.getLogger(Panel.class.getName());
    2934
    30         protected TreeNode currentTreeNode;
     35        protected TreePath currentTreePath;
    3136        protected final TreeAtFrame treeAtFrame;
    3237        protected final Frame frame;
     
    4348                this.className = parameters.param.getContainedTypeName();
    4449                this.setName(parameters.param.getFramsTypeName());
     50                log.debug("created panel: " + this);
    4551        }
    4652
    47         public void setCurrentTreeNode(TreeNode currentTreeNode) {
    48                 this.currentTreeNode = currentTreeNode;
    49         }
    5053
    51         public TreeNode getCurrentTreeNode() {
    52                 return currentTreeNode;
    53         }
    5454
    5555        public final Frame getFrame() {
    5656                return frame;
     57        }
     58
     59        /**
     60         * @return the currentTreePath
     61         */
     62        public TreePath getCurrentTreePath() {
     63                return currentTreePath;
     64        }
     65
     66        /**
     67         * @param currentTreePath the currentTreePath to set
     68         */
     69        public void setCurrentTreePath(TreePath currentTreePath) {
     70                this.currentTreePath = currentTreePath;
    5771        }
    5872
     
    7084        @Override
    7185        public String toString() {
    72                 return uniqueName;
     86                return param.toString() + "(" + uniqueName + ")";
    7387        }
    7488
  • java/main/src/main/java/com/framsticks/gui/StatusBar.java

    r97 r98  
    2222        protected JTextField statusBar;
    2323        protected JPanel swing;
     24        protected ExceptionResultHandler exceptionHandler;
    2425
    2526        /**
     
    3536                        @Override
    3637                        protected void runAt() {
    37                                 log.error("error: " + exception);
     38                                log.error("error: ", exception);
    3839                                statusBar.setText(exception.getShortMessage(new StringBuilder()).toString());
     40                                if (exceptionHandler != null) {
     41                                        exceptionHandler.handle(exception);
     42                                }
    3943                        }
    4044                });
     
    7074        }
    7175
     76        /**
     77         * @return the exceptionHandler
     78         */
     79        public ExceptionResultHandler getExceptionHandler() {
     80                return exceptionHandler;
     81        }
     82
     83        /**
     84         * @param exceptionHandler the exceptionHandler to set
     85         */
     86        public void setExceptionHandler(ExceptionResultHandler exceptionHandler) {
     87                this.exceptionHandler = exceptionHandler;
     88        }
     89
    7290}
  • java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java

    r97 r98  
    11package com.framsticks.gui;
    22
     3import java.awt.event.ActionEvent;
     4import java.awt.event.ActionListener;
     5
     6import com.framsticks.util.dispatching.AbstractJoinable;
    37import com.framsticks.util.dispatching.Dispatcher;
     8import com.framsticks.util.dispatching.JoinableDispatcher;
    49import com.framsticks.util.dispatching.Task;
    510import com.framsticks.util.dispatching.ThrowExceptionHandler;
     
    1116 * @author Piotr Sniegowski
    1217 */
    13 public class SwingDispatcher<C> implements Dispatcher<C> {
     18public class SwingDispatcher<C> extends AbstractJoinable implements JoinableDispatcher<C> {
    1419
    1520        @SuppressWarnings("rawtypes")
     
    3742        @Override
    3843        public final void dispatch(RunAt<? extends C> runnable) {
    39                 assert !(runnable instanceof Task);
     44                if (runnable instanceof Task) {
     45                        final Task<?> task = (Task<?>) runnable;
     46                        Timer timer = new Timer(0, null);
     47                        timer.addActionListener(new ActionListener() {
     48
     49                                @Override
     50                                public void actionPerformed(ActionEvent event) {
     51                                        task.run();
     52                                }
     53
     54                        });
     55                        timer.setInitialDelay((int) (task.getMoment() - System.currentTimeMillis()));
     56                        timer.setRepeats(false);
     57                        timer.start();
     58                        return;
     59                }
    4060                SwingUtilities.invokeLater(runnable);
    4161        }
    4262
     63        @Override
     64        public String getName() {
     65                return "gui";
     66        }
     67
     68        @Override
     69        protected void joinableStart() {
     70
     71        }
     72
     73        @Override
     74        protected void joinableInterrupt() {
     75                finish();
     76        }
     77
     78        @Override
     79        protected void joinableFinish() {
     80
     81        }
     82
     83        @Override
     84        protected void joinableJoin() throws InterruptedException {
     85
     86        }
     87
    4388}
  • java/main/src/main/java/com/framsticks/gui/TreeAtFrame.java

    r97 r98  
    44
    55import com.framsticks.core.Tree;
    6 import com.framsticks.core.TreeListener;
    7 import com.framsticks.core.ListChange;
    86import com.framsticks.core.Node;
    97import com.framsticks.core.Path;
     8import com.framsticks.core.TreeOperations;
     9import com.framsticks.gui.controls.ValueControl;
    1010import com.framsticks.params.CompositeParam;
    1111import com.framsticks.params.FramsClass;
     
    1414
    1515import javax.swing.tree.TreePath;
    16 import com.framsticks.util.dispatching.RunAt;
     16
     17
     18import com.framsticks.util.dispatching.FutureHandler;
     19import com.framsticks.util.lang.Casting;
    1720
    1821/**
    1922 * @author Piotr Sniegowski
    2023 */
    21 public class TreeAtFrame implements TreeListener {
     24public class TreeAtFrame {
    2225
    2326        private static final Logger log = Logger.getLogger(TreeAtFrame.class);
     
    2629        protected final Tree tree;
    2730        protected final Map<String, Panel> knownPanels = new HashMap<String, Panel>();
    28         protected TreeNode rootTreeNode;
     31        protected Node rootNode;
     32
     33        protected Map<TreeNode, NodeAtFrame> nodesStorage = new WeakHashMap<>();
    2934
    3035        public TreeAtFrame(Tree tree, Frame frame) {
     
    9095        }
    9196
    92         @Override
    93         public void onListChange(Path path, ListChange change) {
     97        public boolean hasLocalChanges(TreePath treePath) {
     98                NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
     99                if (nodeAtFrame == null) {
     100                        return false;
     101                }
     102                return !nodeAtFrame.localChanges.isEmpty();
     103        }
     104
     105        public NodeAtFrame assureLocalInfo(TreePath treePath) {
     106                assert frame.isActive();
     107                NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
     108
     109                if (nodeAtFrame == null) {
     110                        nodeAtFrame = new NodeAtFrame();
     111                        nodesStorage.put(Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()), nodeAtFrame);
     112                }
     113                return nodeAtFrame;
     114        }
     115
     116        public NodeAtFrame getLocalInfo(TreePath treePath) {
     117                return nodesStorage.get(treePath.getLastPathComponent());
     118        }
     119
     120        public boolean changeValue(TreePath treePath, ValueControl component, Object newValue) {
     121                log.debug("changing value of " + component + " to '" + newValue + "'");
     122
     123                assureLocalInfo(treePath).localChanges.put(component, newValue);
     124
     125                return true;
     126        }
     127
     128        public void pushLocalChanges(TreePath treePath) {
     129                assert frame.isActive();
     130
     131                NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
     132                if (nodeAtFrame == null) {
     133                        return;
     134                }
     135                Path path = frame.treeModel.convertToPath(treePath);
     136
     137                for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
     138                        TreeOperations.set(path, e.getKey().getParam(), e.getValue(), new FutureHandler<Integer>(frame) {
     139                                @Override
     140                                protected void result(Integer flag) {
     141                                }
     142                        });
     143                }
     144        }
     145
     146        public void fillPanelWithValues(TreePath treePath) {
     147                NodeAtFrame nodeAtFrame = assureLocalInfo(treePath);
     148                if (nodeAtFrame == null) {
     149                        return;
     150                }
     151
     152                if (nodeAtFrame.panel == null) {
     153                        return;
     154                }
     155                Node node = TreeNode.tryGetNode(treePath);
     156                if (node == null) {
     157                        return;
     158                }
     159                nodeAtFrame.panel.setCurrentTreePath(treePath);
     160                nodeAtFrame.panel.pullValuesFromLocalToUser(TreeOperations.bindAccess(node));
     161
     162                frame.showPanel(nodeAtFrame.panel);
    94163
    95164        }
    96165
    97         public TreePath getTreePath(Path path, boolean create) {
    98                 assert frame.isActive();
    99                 TreeNode t = rootTreeNode;
    100                 TreePath result = new TreePath(frame.rootNode).pathByAddingChild(rootTreeNode);
    101                 List<Node> nodes = path.getNodes();
    102                 Iterator<Node> i = nodes.iterator();
    103                 i.next();
    104                 // Node first = i.next();
     166        public void useOrCreatePanel(TreePath treePath) {
     167                // node.assureResolved();
     168                Node node = TreeNode.tryGetNode(treePath);
    105169
    106                 // if (!t.path.isResolved()) {
    107                 //      t.path = new Path(path.getInstance(), nodes, first);
    108                 // }
    109                 while (i.hasNext()) {
    110                         Node n = i.next();
    111                         TreeNode r = null;
    112                         for (TreeNode c : t.childrenIterable()) {
    113                                 if (c.param.getId().equals(n.getParam().getId())) {
    114                                         r = c;
    115                                         break;
    116                                 }
     170                NodeAtFrame nodeAtFrame = assureLocalInfo(treePath);
     171
     172                if (nodeAtFrame.panel == null) {
     173                        CompositeParam param = node.getParam();
     174                        nodeAtFrame.panel = findPanel(param.computeAccessId());
     175                        if (nodeAtFrame.panel == null) {
     176                                FramsClass framsClass = node.getTree().getInfoFromCache(param.getContainedTypeName());
     177                                nodeAtFrame.panel = preparePanel(param, framsClass);
    117178                        }
    118                         if (r == null) {
    119                                 log.debug("missing " + n.getParam().getId() + " in " + t);
    120                                 if (!create) {
    121                                         return result;
    122                                 }
    123                                 Path p = Path.build().tree(path.getTree()).buildUpTo(nodes, n).finish();
    124 
    125 
    126                                 log.debug("forced resolution: creating treenode for " + p);
    127                                 TreeNode childNode = new TreeNode(TreeAtFrame.this, p);
    128 
    129                                 frame.addNode(childNode, t);
    130                                 // frame.treeModel.reload();
    131                                 // t.add(childNode);
    132                                 // frame.treeModel.nodeStructureChanged(t);
    133 
    134                                 r = childNode;
    135                         } else {
    136                                 // if (!r.path.isResolved()) {
    137                                 //      r.path = new Path(path.getInstance(), nodes, n);
    138                                 // }
    139                         }
    140                         result = result.pathByAddingChild(r);
    141                         t = r;
    142179                }
    143                 return result;
    144         }
    145 
    146         @Override
    147         public void onFetch(final Path path) {
    148                 assert tree.isActive();
    149                 log.trace("fetched " + path);
    150 
    151                 frame.dispatch(new RunAt<Frame>(frame) {
    152                         @Override
    153                         protected void runAt() {
    154 
    155                                 TreePath treePath = getTreePath(path, true);
    156                                 assert treePath.getPathCount() == path.size() + 1;
    157 
    158                                 final TreeNode result = (TreeNode) treePath.getLastPathComponent();
    159                                 // log.trace("found " + result + " == " + path);
    160                                 tree.dispatch(new RunAt<Tree>(frame) {
    161                                         @Override
    162                                         protected void runAt() {
    163                                                 result.reactForFetchResult(path, null);
    164                                         }
    165                                 });
    166                         }
    167                 });
    168         }
    169 
    170         @Override
    171         public void onRun(Exception e) {
    172 
    173         }
    174 
    175         @Override
    176         public void onStop(Exception e) {
    177 
     180                fillPanelWithValues(treePath);
    178181        }
    179182}
  • java/main/src/main/java/com/framsticks/gui/TreeNode.java

    r97 r98  
    11package com.framsticks.gui;
    22
    3 import com.framsticks.communication.Subscription;
    4 import com.framsticks.communication.util.LoggingStateCallback;
    5 import com.framsticks.core.Mode;
     3import java.lang.ref.WeakReference;
     4import java.util.Iterator;
     5import java.util.LinkedList;
     6import java.util.List;
     7import java.util.concurrent.atomic.AtomicInteger;
     8
     9import javax.swing.tree.TreePath;
     10
     11import org.apache.log4j.Logger;
     12
     13import com.framsticks.core.Node;
    614import com.framsticks.core.Tree;
    7 import com.framsticks.core.TreeOperations;
    8 import com.framsticks.core.ListChange;
    9 import com.framsticks.core.Path;
    10 import com.framsticks.gui.controls.ValueControl;
    1115import com.framsticks.gui.view.TreeCellRenderer;
    1216import com.framsticks.params.AccessInterface;
    1317import com.framsticks.params.CompositeParam;
    14 import com.framsticks.params.FramsClass;
    15 import com.framsticks.params.types.*;
    16 import com.framsticks.remote.*;
     18import com.framsticks.params.types.StringParam;
     19import com.framsticks.util.FramsticksException;
    1720import com.framsticks.util.lang.Casting;
    18 import com.framsticks.util.lang.Holder;
     21import com.framsticks.util.lang.Pair;
    1922import com.framsticks.util.swing.TooltipConstructor;
    20 import com.framsticks.util.dispatching.ExceptionResultHandler;
    21 import com.framsticks.util.dispatching.FutureHandler;
    22 import com.framsticks.util.FramsticksException;
    23 import com.framsticks.util.Logging;
    24 import org.apache.log4j.Logger;
    25 import com.framsticks.util.dispatching.RunAt;
    26 
    27 import javax.swing.tree.DefaultMutableTreeNode;
    28 import java.util.HashMap;
    29 import java.util.LinkedList;
    30 import java.util.List;
    31 import java.util.Map;
    32 import static com.framsticks.util.lang.Containers.filterInstanceof;
    33 import com.framsticks.util.swing.TreeNodeUtils;
    34 import static com.framsticks.core.TreeOperations.*;
    35 
    36 /**
    37  * @author Piotr Sniegowski
    38  */
    39 @SuppressWarnings("serial")
    40 public class TreeNode extends DefaultMutableTreeNode implements NodeListener, ExceptionResultHandler {
    41 
    42         private static final Logger log = Logger.getLogger(TreeNode.class.getName());
    43 
    44         Panel panel;
    45 
    46         final protected Frame frame;
    47         final protected TreeAtFrame treeAtFrame;
    48 
    49         final protected Map<EventParam, Subscription<?>> userSubscriptions = new HashMap<>();
    50         protected Map<ValueControl, Object> localChanges = null;
    51         protected String tooltip;
    52         protected String name;
     23
     24public class TreeNode extends AbstractNode {
     25        private static final Logger log = Logger.getLogger(TreeNode.class);
     26
     27
     28        protected static final AtomicInteger counter = new AtomicInteger();
     29
     30        protected final WeakReference<Object> reference;
    5331        protected final CompositeParam param;
    54         protected String iconName;
    55         protected Path path;
    56 
    57         public TreeNode(TreeAtFrame treeAtFrame, final Path path) {
    58                 this.frame = treeAtFrame.getFrame();
    59                 assert frame.isActive();
    60                 this.param = path.getTop().getParam();
    61                 this.name = this.param.getId();
    62                 log.debug("creating treenode " + name + ": " + path);
    63                 this.path = path;
    64                 this.treeAtFrame = treeAtFrame;
    65 
    66                 iconName = TreeCellRenderer.findIconName(name, path.getTextual());
    67                 tooltip = "?";
    68                 path.getTree().dispatch(new RunAt<Tree>(this) {
    69                         @Override
    70                         protected void runAt() {
    71                                 updateDescriptions(path);
    72                         }
    73                 });
    74         }
    75 
    76         public void fetch(final Path p) {
    77                 assert p.getTree().isActive();
    78                 log.debug("fetching: " + p);
    79                 p.getTree().get(p, Mode.FETCH, new FutureHandler<Object>(this) {
    80                         @Override
    81                         protected void result(Object result) {
    82 
    83                         }
    84                 });
    85         }
    86 
    87         protected void reactForFetchResult(final Path p, Exception e) {
    88                 assert p.getTree().isActive();
    89                 if (Logging.log(log, "fetch", TreeNode.this, e)) {
    90                         frame.dispatch(new RunAt<Frame>(this) {
    91                                 @Override
    92                                 protected void runAt() {
    93                                         log.debug("removing node from tree: " + p);
    94                                         frame.treeModel.removeNodeFromParent(TreeNode.this);
    95                                 }
    96                         });
    97                         return;
    98                 }
    99                 updateChildren(p);
    100                 frame.dispatch(new RunAt<Frame>(this) {
    101                         @Override
    102                         protected void runAt() {
    103                                 //TODO maybe this should be called from some better place
    104                                 useOrCreatePanel();
    105                         }
    106                 });
    107         }
    108 
    109         protected void postUpdatePath(final Path newPath) {
    110                 assert !frame.isActive();
    111                 /** TODO those two actions could be merged into single closure */
    112                 frame.dispatch(new RunAt<Frame>(this) {
    113                         @Override
    114                         protected void runAt() {
    115                                 updatePath(newPath);
    116                         }
    117                 });
    118                 updateDescriptions(newPath);
    119         }
    120 
    121         protected void updatePath(Path newPath) {
    122                 assert frame.isActive();
    123                 if (!path.isResolved()) {
    124                         path = newPath;
    125                         log.debug("updated treenode's path: " + path);
    126                         return;
    127                 }
    128                 if (path.matches(newPath)) {
    129                         return;
    130                 }
    131                 log.debug("removing all children due to path update");
    132                 this.removeAllChildren();
    133                 frame.treeModel.nodeStructureChanged(this);
    134         }
    135 
    136         public Iterable<TreeNode> childrenIterable() {
    137                 return filterInstanceof(TreeNodeUtils.children(TreeNode.this, frame.treeModel), TreeNode.class);
    138         }
    139 
    140         /** Update children, by removing non existing and adding new ones.
     32        protected final Tree tree;
     33        protected final List<Pair<WeakReference<Object>, WeakReference<TreeNode>>> children = new LinkedList<>();
     34        protected final int number;
     35
     36        public TreeNode(Tree tree, CompositeParam param, Object object) {
     37                this.tree = tree;
     38                this.param = param;
     39                reference = new WeakReference<Object>(object);
     40                number = counter.getAndIncrement();
     41        }
     42
     43        public TreeNode(Node node) {
     44                this(node.getTree(), node.getParam(), node.assureResolved().getObject());
     45        }
     46
     47        public Node tryCreateNode() {
     48                Object child = lock();
     49                if (child == null) {
     50                        return null;
     51                }
     52                return new Node(tree, param, child);
     53        }
     54
     55        @Override
     56        public int getChildCount() {
     57                Object referent = lock();
     58                if (referent == null) {
     59                        return 0;
     60                }
     61                AccessInterface access = tree.prepareAccess(param).select(referent);
     62                final int count = access.getCompositeParamCount();
     63                return count;
     64        }
     65
     66        public TreeNode getTreeNodeForChild(Object child) {
     67                Iterator<Pair<WeakReference<Object>, WeakReference<TreeNode>>> i = children.iterator();
     68                while (i.hasNext()) {
     69                        Pair<WeakReference<Object>, WeakReference<TreeNode>> p = i.next();
     70                        Object object = p.first.get();
     71                        if (object == null) {
     72                                i.remove();
     73                                continue;
     74                        }
     75                        TreeNode treeNode = p.second.get();
     76                        if (treeNode == null) {
     77                                i.remove();
     78                                continue;
     79                        }
     80                        if (object == child) {
     81                                return treeNode;
     82                        }
     83                }
     84                return null;
     85
     86                // WeakReference<GuiTreeNode> resultReference = children.get(child);
     87                // if (resultReference == null) {
     88                //      return null;
     89                // }
     90                // return resultReference.get();
     91        }
     92
     93        @Override
     94        public AbstractNode getChild(int number) {
     95                Object referent = lock();
     96                if (referent == null) {
     97                        throw new FramsticksException().msg("invalid state - missing referent");
     98                }
     99                AccessInterface access = tree.prepareAccess(param).select(referent);
     100
     101                final int count = access.getCompositeParamCount();
     102                if (number >= count) {
     103                        throw new FramsticksException().msg("invalid state - no child");
     104                }
     105
     106                CompositeParam childParam = access.getCompositeParam(number);
     107                Object child = access.get(childParam, Object.class);
     108                if (child == null) {
     109                        log.debug("returing dummy node for " + childParam + " in " + referent);
     110                        return new EmptyNode(childParam);
     111                }
     112
     113                TreeNode result = getTreeNodeForChild(child);
     114                if (result != null) {
     115                        return result;
     116                }
     117                result = new TreeNode(tree, childParam, child);
     118
     119                children.add(Pair.make(new WeakReference<Object>(child), new WeakReference<TreeNode>(result)));
     120
     121                return result;
     122
     123        }
     124
     125        public Object lock() {
     126                return reference.get();
     127        }
     128
     129        @Override
     130        public int getIndexOfChild(AbstractNode child) {
     131                final TreeNode treeChild = Casting.tryCast(TreeNode.class, child);
     132                if (treeChild == null) {
     133                        return -1;
     134                }
     135                final Object childObject = treeChild.lock();
     136                final Object parentObject = lock();
     137                if (childObject == null || parentObject == null) {
     138                        return -1;
     139                }
     140                final AccessInterface access = tree.prepareAccess(param).select(parentObject);
     141
     142                final int count = access.getCompositeParamCount();
     143                for (int i = 0; i < count; ++i) {
     144                        Object c = access.get(access.getCompositeParam(i), Object.class);
     145                        if (c == childObject) {
     146                                return i;
     147                        }
     148                }
     149                log.debug(child + " not found in " + this);
     150                return -1;
     151        }
     152
     153        /**
     154         * @return the param
    141155         */
    142         protected void updateChildren(final Path p) {
    143                 assert p.getTree().isActive();
    144                 log.debug("updating children of " + this);
    145                 AccessInterface access = TreeOperations.bindAccess(p.getTree(), p.getTop());
    146                 final List<Path> childrenPaths = new LinkedList<Path>();
    147                 /**Prepare path for each child.*/
    148                 for (CompositeParam param : filterInstanceof(access.getParams(), CompositeParam.class)) {
    149                         childrenPaths.add(p.appendParam(param).tryFindResolution());
    150                 }
    151 
    152                 /**If some child were found, update in frame context.*/
    153                 if (childrenPaths.size() > 0) {
    154                         frame.dispatch(new RunAt<Frame>(this) {
    155                                 @Override
    156                                 protected void runAt() {
    157                                         // TreePath treePath = frame.startChange();
    158                                         updatePath(p);
    159                                         Map<String, TreeNode> current = new HashMap<String, TreeNode>();
    160                                         for (TreeNode n : childrenIterable()) {
    161                                                 current.put(n.path.getLastElement(), n);
    162                                         }
    163                                         assert current.size() == TreeNode.this.getChildCount();
    164                                         assert TreeNode.this.getChildCount() == frame.treeModel.getChildCount(TreeNode.this);
    165                                         log.trace("current " + TreeNode.this.getChildCount() + " children: " + current.values());
    166                                         for (Path childPath : childrenPaths) {
    167                                                 String e = childPath.getLastElement();
    168                                                 if (current.containsKey(e)) {
    169                                                         current.remove(e);
    170                                                         continue;
    171                                                 }
    172                                                 log.debug("update: treenode for " + p);
    173                                                 TreeNode childNode = new TreeNode(treeAtFrame, childPath);
    174 
    175                                                 frame.addNode(childNode, TreeNode.this);
    176                                         }
    177                                         for (TreeNode n : current.values()) {
    178                                                 frame.treeModel.removeNodeFromParent(n);
    179                                         }
    180                                         log.debug("updated children of " + TreeNode.this + ": " + TreeNode.this.getChildCount());
    181                                 }
    182                         });
     156        public CompositeParam getParam() {
     157                return param;
     158        }
     159
     160        /**
     161         * @return the tree
     162         */
     163        public Tree getTree() {
     164                return tree;
     165        }
     166
     167
     168        @Override
     169        public String toString() {
     170                return param.toString();
     171        }
     172
     173        public static Node tryGetNode(TreePath treePath) {
     174                return Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()).tryCreateNode();
     175        }
     176
     177        @Override
     178        public boolean isLeaf() {
     179                Object referent = lock();
     180                if (referent == null) {
     181                        return true;
     182                }
     183                AccessInterface access = tree.prepareAccess(param).select(referent);
     184                return access.getCompositeParamCount() == 0;
     185        }
     186
     187
     188        @Override
     189        public void render(TreeCellRenderer renderer) {
     190                String name = param.getId();
     191
     192                Object child = lock();
     193                if (child != null) {
     194                        AccessInterface access = tree.prepareAccess(param).select(child);
     195
     196                        StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
     197
     198                        if (nameParam != null) {
     199                                name = access.get(nameParam, String.class);
     200                        }
     201
     202                        renderer.setToolTipText(new TooltipConstructor()
     203                                .append("frams", access.getId())
     204                                .append("java", child.getClass().getCanonicalName())
     205                                .append("access", access.getClass().getSimpleName())
     206                                .append("name", name)
     207                                .append("id", param.getId())
     208                                .append("object", Integer.toHexString(System.identityHashCode(child)))
     209                                .append("number", number)
     210                                .build());
    183211                } else {
    184                         log.debug("no children in " + TreeNode.this);
    185                 }
    186         }
    187 
    188         public void select() {
    189                 final Path p = path;
    190 
    191                 p.getTree().dispatch(new RunAt<Tree>(this) {
    192                         @Override
    193                         protected void runAt() {
    194                                 final Path updated = (p.isResolved()) ? p : p.tryFindResolution();
    195                                 if (updated.isResolved()) {
    196                                         Logging.log(log, "update", updated, null);
    197                                         fetch(updated);
    198                                         postUpdatePath(updated);
    199                                         return;
    200                                 }
    201                                 p.getTree().resolve(updated, new FutureHandler<Path>(Logging.logger(log, "resolve and select", TreeNode.this)) {
    202                                         @Override
    203                                         protected void result(Path result) {
    204                                                 fetch(result);
    205                                                 postUpdatePath(result);
    206                                         }
    207                                 });
    208                         }
    209                 });
    210 
    211         }
    212 
    213         @Override
    214         public String toString() {
    215                 return path.toString();
    216         }
    217 
    218         public final Panel getPanel() {
    219                 assert frame.isActive();
    220                 return panel;
    221         }
    222 
    223         protected void updateDescriptions(Path p) {
    224                 assert p.getTree().isActive();
    225 
    226                 if (!p.isResolved()) {
    227                         return;
    228                 }
    229                 AccessInterface access = TreeOperations.bindAccess(p);
    230 
    231                 final String tooltip = new TooltipConstructor().append("frams", access.getId()).append("java", p.getTopObject().getClass().getCanonicalName()).append("access", access.getClass().getSimpleName()).append("name", name).append("id", param.getId()).append("object", Integer.toHexString(System.identityHashCode(this))).build();
    232 
    233                 StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
    234                 final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
    235 
    236                 frame.dispatch(new RunAt<Frame>(this) {
    237                         @Override
    238                         protected void runAt() {
    239                                 TreeNode.this.tooltip = tooltip;
    240                                 TreeNode.this.name = name;
    241 
    242                                 log.debug("updated descriptions for " + path + ": " + name);
    243                         }
    244                 });
    245         }
    246 
    247         public void showPanel() {
    248                 assert frame.isActive();
    249                 assert panel != null;
    250                 frame.showPanel(panel);
    251         }
    252 
    253         public void fillPanelWithValues() {
    254                 assert frame.isActive();
    255                 if (panel == null) {
    256                         return;
    257                 }
    258                 final Path p = path;
    259                 assert p.isResolved();
    260                 panel.setCurrentTreeNode(this);
    261                 p.getTree().dispatch(new RunAt<Tree>(this) {
    262                         @Override
    263                         protected void runAt() {
    264                                 AccessInterface access = TreeOperations.bindAccess(p);
    265                                 panel.pullValuesFromLocalToUser(access);
    266 
    267                                 frame.dispatch(new RunAt<Frame>(this) {
    268                                         @Override
    269                                         protected void runAt() {
    270                                                 showPanel();
    271                                         }
    272                                 });
    273                         }
    274                 });
    275 
    276         }
    277 
    278         public void useOrCreatePanel() {
    279                 assert frame.isActive();
    280                 if (panel != null) {
    281                         log.trace("panel is already attached: " + path);
    282                         fillPanelWithValues();
    283                         return;
    284                 }
    285                 if (!path.isResolved()) {
    286                         log.trace("path is not resolved: " + path);
    287                         return;
    288                 }
    289 
    290                 CompositeParam param = path.getTop().getParam();
    291                 panel = treeAtFrame.findPanel(param.computeAccessId());
    292                 if (panel != null) {
    293                         log.debug("found prepared panel for: " + path);
    294                         fillPanelWithValues();
    295                         return;
    296                 }
    297                 final Path p = path;
    298                 log.debug("preparing panel: " + p);
    299                 p.getTree().dispatch(new RunAt<Tree>(this) {
    300                         @Override
    301                         protected void runAt() {
    302                                 assert p.getTree().isActive();
    303                                 final CompositeParam param = p.getTop().getParam();
    304                                 final FramsClass framsClass = p.getTree().getInfoFromCache(param.getContainedTypeName());
    305                                 frame.dispatch(new RunAt<Frame>(this) {
    306                                         @Override
    307                                         protected void runAt() {
    308                                                 panel = treeAtFrame.preparePanel(param, framsClass);
    309                                                 fillPanelWithValues();
    310                                         }
    311                                 });
    312                         }
    313                 });
    314         }
    315 
    316         public String getTooltip() {
    317                 assert frame.isActive();
    318                 return tooltip;
    319         }
    320 
    321         /*public void subscribe(final EventParam eventParam) {
    322                 assert browser.isActive();
    323                 if (hasSubscribed(eventParam)) {
    324                         log.error(eventParam + " is already subscribed for " + this);
    325                         return;
    326                 }
    327                 Node node = getNode();
    328                 node.getConnection().subscribe(node.getPath() + "/" + eventParam.getId(), new SubscriptionCallback() {
    329                         @Override
    330                         public EventCallback subscribed(final Subscription subscription) {
    331                                 if (subscription == null) {
    332                                         log.error("subscription failed");
    333                                         return null;
    334                                 }
    335                                 if (hasSubscribed(eventParam)) {
    336                                         //abort subscription
    337                                         return null;
    338                                 }
    339                                 userSubscriptions.put(eventParam, subscription);
    340                                 log.debug("subscription succeeded: " + subscription);
    341                                 subscription.setDispatcher(browser);
    342                                 return new EventCallback() {
    343                                         @Override
    344                                         public void call(SourceInterface content) {
    345                                                 assert browser.isActive();
    346                                                 log.info("event " + subscription + " occurred");
    347                                         }
    348                                 };
    349                         }
    350                 });
    351 
    352         }*/
    353 
    354         public boolean hasSubscribed(EventParam param) {
    355                 assert frame.isActive();
    356                 return userSubscriptions.containsKey(param);
    357         }
    358 
    359         public void unsubscribe(EventParam eventParam) {
    360                 assert frame.isActive();
    361                 if (!hasSubscribed(eventParam)) {
    362                         log.error("could not unsubscribe from " + eventParam);
    363                         return;
    364                 }
    365                 userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
    366                 userSubscriptions.remove(eventParam);
    367         }
    368 
    369         // @Override
    370         // public void onChildChange(final Child child, ListChange.Action action) {
    371         // assert browser.manager.isActive();
    372 
    373         // switch (action) {
    374         // case Remove: {
    375         // Dispatching.invokeDispatch(browser, browser.manager, new Runnable() {
    376         // @Override
    377         // public void run() {
    378         // assert browser.manager.isActive();
    379         // final TreeNode treeNode = (TreeNode) child.getUserObject();
    380         // if (treeNode == null) {
    381         // log.error("child " + child + " had no tree node attached");
    382         // return;
    383         // }
    384         // browser.invokeLater(new Runnable() {
    385         // @Override
    386         // public void run() {
    387         // assert browser.isActive();
    388         // TreePath path = browser.startChange();
    389         // //assert treeNode.getParent() == TreeNode.this;
    390         // if (treeNode.getParent() != null) {
    391         // browser.treeModel.removeNodeFromParent(treeNode);
    392         // }
    393         // //remove(treeNode);
    394         // browser.markNodeChanged(TreeNode.this, path);
    395         // }
    396         // });
    397         // }
    398         // });
    399         // break;
    400         // }
    401         // }
    402 
    403         // }
    404 
    405         public String getName() {
    406                 return name;
    407         }
    408 
    409         public String getIconName() {
    410                 return iconName;
    411         }
    412 
    413         @Override
    414         public void onUpgrade(Path path) {
    415         }
    416 
    417         @Override
    418         public void onChange(Path path) {
    419         }
    420 
    421         @Override
    422         public void onChildChange(Path path, ListChange.Action action) {
    423         }
    424 
    425         public final Frame getFrame() {
    426                 return frame;
    427         }
    428 
    429         public boolean changeValue(ValueControl component, Object newValue) {
    430                 log.debug("changing value of " + component + " to '" + newValue + "'");
    431 
    432                 if (localChanges == null) {
    433                         localChanges = new HashMap<ValueControl, Object>();
    434                 }
    435                 localChanges.put(component, newValue);
    436 
    437                 return true;
    438         }
    439 
    440         public Path getTreePath() {
    441                 assert frame.isActive();
    442                 return path;
    443         }
    444 
    445         public void pushLocalChanges() {
    446                 assert frame.isActive();
    447                 if (localChanges == null) {
    448                         return;
    449                 }
    450                 Map<ValueControl, Object> changes = localChanges;
    451                 localChanges = null;
    452                 final Holder<Integer> counter = new Holder<>(changes.size());
    453                 final Path p = path;
    454 
    455                 for (Map.Entry<ValueControl, Object> e : changes.entrySet()) {
    456                         set(p, e.getKey().getParam(), e.getValue(), new FutureHandler<Integer>(this) {
    457                                 @Override
    458                                 protected void result(Integer flag) {
    459                                         counter.set(counter.get() - 1);
    460                                         if (counter.get() != 0) {
    461                                                 return;
    462                                         }
    463                                         log.debug("applied changes for: " + p);
    464                                         frame.dispatch(new RunAt<Frame>(this) {
    465                                                 @Override
    466                                                 protected void runAt() {
    467                                                         fillPanelWithValues();
    468                                                 }
    469                                         });
    470                                 }
    471 
    472                         });
    473                 }
    474         }
    475 
    476         @Override
    477         public void handle(FramsticksException exception) {
    478                 frame.handle(exception);
    479         }
     212                        renderer.setToolTipText("?");
     213                }
     214                renderer.setText(name);
     215                renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param)));
     216
     217        }
     218
    480219}
  • java/main/src/main/java/com/framsticks/gui/console/InteractiveConsole.java

    r97 r98  
    109109                        }
    110110                });
    111 
    112 
    113111        }
    114112
  • java/main/src/main/java/com/framsticks/gui/console/ManagedConsole.java

    r97 r98  
    33import java.util.LinkedList;
    44import java.util.List;
    5 
    65
    76import com.framsticks.communication.ClientSideManagedConnection;
     
    1110import com.framsticks.communication.Response;
    1211import com.framsticks.communication.queries.ApplicationRequest;
     12import com.framsticks.core.Mode;
    1313import com.framsticks.core.Path;
    1414import static com.framsticks.core.TreeOperations.*;
     
    1717import com.framsticks.params.annotations.AutoAppendAnnotation;
    1818import com.framsticks.params.annotations.FramsClassAnnotation;
     19import com.framsticks.params.types.ListParam;
    1920import com.framsticks.remote.RemoteTree;
    2021import com.framsticks.util.FramsticksException;
     22import com.framsticks.util.dispatching.Dispatching;
    2123import com.framsticks.util.dispatching.FutureHandler;
     24import com.framsticks.util.dispatching.RunAt;
    2225import com.framsticks.util.lang.Casting;
    2326import com.framsticks.util.lang.Containers;
     
    2730@FramsClassAnnotation
    2831public class ManagedConsole extends InteractiveConsole {
     32
    2933
    3034        protected RemoteTree tree;
     
    7074        }
    7175
     76
    7277        @Override
    7378        protected void findCompletionPropositions(final String prefix) {
    7479                Pair<CharSequence, CharSequence> command = Request.takeIdentifier(prefix);
     80                if (command == null) {
     81                        return;
     82                }
    7583
    7684                Casting.throwCast(ApplicationRequest.class, Request.createRequestByTypeString(command.first.toString()));
     
    9098                // final Iterator<String> iterator = Path.splitPath(textual);
    9199
    92                 resolve(tree, textual, new FutureHandler<Path>(this) {
     100                tryGet(tree, textual, new FutureHandler<Path>(this) {
    93101
    94102                        @Override
    95                         protected void result(Path path) {
     103                        protected void result(final Path path) {
    96104                                if (!textual.startsWith(path.getTextual())) {
    97105                                        throw new FramsticksException().msg("invalid state").arg("line", prefix).arg("path", path);
    98106                                }
     107                                assert path.getTree().isActive();
    99108
    100                                 List<String> propositions = new LinkedList<String>();
    101                                 String remaining = textual.substring(path.getTextual().length());
    102                                 remaining = Path.PathBuilder.splitPath(remaining).next();
     109                                final Runnable finalizeCompletion = new Runnable() {
     110                                        @Override
     111                                        public void run() {
     112                                                String remaining = textual.substring(path.getTextual().length());
    103113
    104                                 for (CompositeParam p : Containers.filterInstanceof(bindAccess(path).getParams(), CompositeParam.class)) {
    105                                         if (p.getId().startsWith(remaining)) {
    106                                                 propositions.add(p.getId());
     114                                                String base = prefix.substring(0, prefix.length() - (textual.length() - path.getTextual().length()));
     115                                                if (path.size() > 1) {
     116                                                        base = base + "/";
     117                                                }
     118
     119                                                if (remaining.startsWith("/")) {
     120                                                        remaining = remaining.substring(1);
     121                                                }
     122
     123                                                if (remaining.indexOf('/') != -1) {
     124                                                        /** It is to long. */
     125                                                        return;
     126                                                }
     127                                                final List<String> propositions = new LinkedList<String>();
     128                                                for (CompositeParam p : Containers.filterInstanceof(bindAccess(path).getParams(), CompositeParam.class)) {
     129                                                        if (remaining.equals("") || p.getId().startsWith(remaining)) {
     130                                                                propositions.add(base + p.getId());
     131                                                        }
     132                                                }
     133
     134                                                dispatch(new RunAt<ManagedConsole>(ManagedConsole.this) {
     135
     136                                                        @Override
     137                                                        protected void runAt() {
     138                                                                processCompletionResult(prefix, propositions);
     139                                                        }
     140                                                });
    107141                                        }
     142                                };
     143
     144                                if (path.getTop().getParam() instanceof ListParam) {
     145                                        tree.get(path, Mode.FETCH, new FutureHandler<Path>(ManagedConsole.this) {
     146                                                @Override
     147                                                protected void result(Path result) {
     148                                                        finalizeCompletion.run();
     149                                                }
     150                                        });
     151                                        return;
    108152                                }
    109                                 processCompletionResult(prefix, propositions);
     153                                finalizeCompletion.run();
     154
    110155                        }
    111156                });
     
    119164                connection = tree.getConnection();
    120165        }
     166
     167        @Override
     168        protected void joinableStart() {
     169                super.joinableStart();
     170                Dispatching.use(tree, this);
     171        }
     172
     173        @Override
     174        protected void joinableInterrupt() {
     175                Dispatching.drop(tree, this);
     176                super.joinableInterrupt();
     177        }
     178
     179        @Override
     180        protected void joinableJoin() throws InterruptedException {
     181                Dispatching.join(tree);
     182                super.joinableJoin();
     183        }
    121184}
  • java/main/src/main/java/com/framsticks/gui/console/TrackConsole.java

    r97 r98  
    11package com.framsticks.gui.console;
     2
     3import java.awt.BorderLayout;
     4import java.awt.event.ActionEvent;
     5import java.awt.event.ActionListener;
     6
     7import javax.swing.Box;
     8import javax.swing.BoxLayout;
     9import javax.swing.JCheckBox;
    210
    311import com.framsticks.communication.Connection;
     
    816@FramsClassAnnotation
    917public class TrackConsole extends Console implements ConnectionListener {
     18
     19        volatile boolean writeOut = true;
     20        volatile boolean writeIn = true;
    1021
    1122        public TrackConsole() {
     
    3041        }
    3142
    32 
    3343        @Override
    3444        public void connectionOutgoing(String line) {
    35                 dispatchWrite(line);
     45                if (writeOut) {
     46                        dispatchWrite(line);
     47                }
    3648        }
    3749
    3850        @Override
    3951        public void connectionIncomming(String line) {
    40                 dispatchWrite(line);
     52                if (writeIn) {
     53                        dispatchWrite(line);
     54                }
     55        }
     56
     57        @Override
     58        protected void initializeGui() {
     59                super.initializeGui();
     60
     61                final Box box = new Box(BoxLayout.LINE_AXIS);
     62
     63                final JCheckBox outCheckbox = new JCheckBox();
     64                outCheckbox.setText("Show out");
     65                outCheckbox.setSelected(true);
     66                outCheckbox.addActionListener(new ActionListener() {
     67                        @Override
     68                        public void actionPerformed(ActionEvent arg0) {
     69                                writeOut = outCheckbox.isSelected();
     70                        }
     71                });
     72
     73                final JCheckBox inCheckbox = new JCheckBox();
     74                inCheckbox.setText("Show in");
     75                inCheckbox.setSelected(true);
     76                inCheckbox.addActionListener(new ActionListener() {
     77                        @Override
     78                        public void actionPerformed(ActionEvent arg0) {
     79                                writeIn = inCheckbox.isSelected();
     80                        }
     81                });
     82
     83                box.add(outCheckbox);
     84                box.add(Box.createHorizontalStrut(10));
     85                box.add(inCheckbox);
     86
     87                panel.add(box, BorderLayout.PAGE_END);
    4188        }
    4289
  • java/main/src/main/java/com/framsticks/gui/controls/CheckBoxControl.java

    r84 r98  
    2121                super(booleanParam);
    2222                checkBox = new JCheckBox();
    23                 checkBox.setEnabled(!isReadOnly());
    2423                checkBox.addActionListener(new ActionListener() {
    2524
     
    5251        }
    5352
     53        @Override
     54        protected void updateEnabled(boolean enabled) {
     55                checkBox.setEnabled(enabled);
     56        }
     57
    5458}
  • java/main/src/main/java/com/framsticks/gui/controls/Control.java

    r97 r98  
    2424        protected ControlOwner owner;
    2525
     26        protected abstract void updateEnabled(boolean enabled);
     27
     28        private boolean userEnabled = true;
     29
    2630        public Control(Param param) {
    2731                this.param = param;
    2832                setName(param.getId());
    29 
    30                 this.setEnabled(!param.hasFlag(Flags.READONLY));
    31                 // TODO: take care of textField exception: setEditable
    3233        }
    3334
     
    3839        public void setOwner(ControlOwner owner) {
    3940                this.owner = owner;
     41        }
     42
     43        /**
     44         * @return the userEnabled
     45         */
     46        public final boolean isUserEnabled() {
     47                return userEnabled;
     48        }
     49
     50        /**
     51         * @param userEnabled the userEnabled to set
     52         */
     53        public final void setUserEnabled(boolean userEnabled) {
     54                this.userEnabled = userEnabled;
     55                updateEnabled(!isReadonly());
     56        }
     57
     58        public final boolean isReadonly() {
     59                return !userEnabled || param.hasFlag(Flags.READONLY);
    4060        }
    4161
  • java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java

    r97 r98  
    22
    33import javax.swing.JPanel;
     4import javax.swing.tree.TreePath;
    45
    5 import com.framsticks.gui.TreeNode;
     6import com.framsticks.gui.Frame;
    67import com.framsticks.util.dispatching.ExceptionResultHandler;
    78
     
    910
    1011        public JPanel getPanel();
    11         public TreeNode getCurrentTreeNode();
     12        public TreePath getCurrentTreePath();
     13        public Frame getFrame();
    1214
    1315}
  • java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java

    r85 r98  
    2828                }
    2929                list.setEditable(false);
    30                 list.setEnabled(!isReadOnly());
    3130                list.addItemListener(new ItemListener() {
    3231                        @Override
     
    6160        }
    6261
     62        @Override
     63        protected void updateEnabled(boolean enabled) {
     64                list.setEnabled(enabled);
     65
     66        }
     67
    6368}
  • java/main/src/main/java/com/framsticks/gui/controls/EventControl.java

    r84 r98  
    3939        }
    4040
     41        @Override
     42        protected void updateEnabled(boolean enabled) {
     43                button.setEnabled(enabled);
     44        }
     45
    4146        /*
    4247        @Override
  • java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java

    r97 r98  
    33import com.framsticks.core.Tree;
    44import com.framsticks.core.Path;
     5import com.framsticks.gui.Frame;
    56import com.framsticks.gui.Gui;
    6 import com.framsticks.gui.TreeNode;
    77import com.framsticks.params.Param;
    88import com.framsticks.params.ValueParam;
     
    1515import javax.swing.*;
    1616import javax.swing.border.BevelBorder;
     17import javax.swing.tree.TreePath;
    1718
    1819import org.apache.log4j.Logger;
     
    2021import java.awt.event.ActionEvent;
    2122import java.awt.event.ActionListener;
    22 import java.util.HashMap;
     23import java.util.IdentityHashMap;
    2324import java.util.LinkedList;
    2425import java.util.List;
     
    3233        protected final JButton procedureButton;
    3334
    34         final protected Map<ValueParam, ValueControl> components = new HashMap<>();
     35        final protected Map<ValueParam, ValueControl> components = new IdentityHashMap<>();
    3536
    3637        public ProcedureControl(ProcedureParam procedureParam) {
     
    5455                        @Override
    5556                        public void actionPerformed(ActionEvent e) {
    56                                 TreeNode treeNode = owner.getCurrentTreeNode();
    57                                 assert treeNode != null;
    5857
    59                                 log.debug("calling " + getParam() + " on " + treeNode);
    60                                 final Path path = treeNode.getTreePath();
     58                                final Path path = getFrame().getTreeModel().convertToPath(getCurrentTreePath());
    6159
    6260                                final List<Object> arguments = new LinkedList<Object>();
     
    9391
    9492        @Override
    95         public TreeNode getCurrentTreeNode() {
    96                 return owner.getCurrentTreeNode();
    97         }
    98 
    99         @Override
    10093        public ProcedureParam getParam() {
    10194                return (ProcedureParam) param;
    10295        }
    10396
     97        @Override
     98        protected void updateEnabled(boolean enabled) {
     99                procedureButton.setEnabled(enabled);
     100                for (ValueControl vc : components.values()) {
     101                        vc.setUserEnabled(enabled);
     102                }
     103        }
     104
     105        @Override
     106        public Frame getFrame() {
     107                return owner.getFrame();
     108        }
     109
     110        @Override
     111        public TreePath getCurrentTreePath() {
     112                return owner.getCurrentTreePath();
     113        }
     114
    104115}
  • java/main/src/main/java/com/framsticks/gui/controls/SliderControl.java

    r97 r98  
    1717import org.apache.log4j.Logger;
    1818
    19 import com.framsticks.params.Flags;
    2019import com.framsticks.params.types.DecimalParam;
    2120import com.framsticks.params.types.FloatParam;
     
    5554                slider = new JSlider();
    5655
    57                 slider.setEnabled(!isReadOnly());
    5856                slider.setPaintLabels(false);
    5957                if (param instanceof DecimalParam) {
     
    110108                text.setHorizontalAlignment(JSlider.CENTER);
    111109
    112                 text.setEnabled(!param.hasFlag(Flags.READONLY));
    113110
    114111                slider.addChangeListener(new ChangeListener() {
     
    206203        }
    207204
     205        @Override
     206        protected void updateEnabled(boolean enabled) {
     207                slider.setEnabled(enabled);
     208                text.setEnabled(enabled);
     209        }
     210
    208211}
  • java/main/src/main/java/com/framsticks/gui/controls/TextAreaControl.java

    r97 r98  
    1818                textArea.setLineWrap(true);
    1919                textArea.setWrapStyleWord(true);
    20                 textArea.setEditable(!isReadOnly());
    2120                addDefaultDocumentListener(textArea);
    2221
     
    4746        }
    4847
     48        @Override
     49        protected void updateEnabled(boolean enabled) {
     50                textArea.setEditable(enabled);
     51        }
     52
    4953}
  • java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java

    r90 r98  
    3131                this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Control.LINE_HEIGHT));
    3232
    33                 textField.setEditable(!isReadOnly());
    34 
    3533                addDefaultDocumentListener(textField);
    3634
     
    4846        }
    4947
     48        @Override
     49        protected void updateEnabled(boolean enabled) {
     50                textField.setEnabled(enabled);
     51        }
     52
    5053}
  • java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java

    r97 r98  
    9797        }
    9898
    99         public final boolean isReadOnly() {
    100                 return (param.getFlags() & Flags.READONLY) != 0;
    101         }
    102 
    103 
    10499
    105100}
  • java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java

    r90 r98  
    11package com.framsticks.gui.view;
    22
    3 import com.framsticks.gui.ImageProvider;
    4 import com.framsticks.gui.TreeNode;
     3import java.awt.Component;
    54
    6 import javax.swing.*;
     5import javax.swing.JTree;
    76import javax.swing.tree.DefaultTreeCellRenderer;
    87
    9 import org.apache.log4j.Logger;
    10 
    11 import java.awt.*;
     8import com.framsticks.gui.AbstractNode;
     9import com.framsticks.gui.ImageProvider;
     10import com.framsticks.params.CompositeParam;
    1211
    1312/**
     
    1615@SuppressWarnings("serial")
    1716public class TreeCellRenderer extends DefaultTreeCellRenderer {
    18         private static final Logger log =
    19                 Logger.getLogger(TreeCellRenderer.class);
    20 
    2117
    2218        public TreeCellRenderer() {
    23                 setOpenIcon(null);
    24                 setClosedIcon(null);
    25                 setLeafIcon(null);
     19
     20                // setOpenIcon(ImageProvider.loadImage(ImageProvider.FOLDER_OPEN));
     21                // setClosedIcon(ImageProvider.loadImage(ImageProvider.FOLDER_CLOSED));
     22                // setLeafIcon(ImageProvider.loadImage(ImageProvider.NODE));
    2623        }
    2724
     
    3128                        boolean hasFocus) {
    3229
    33                 //super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
    34                 //              row, hasFocus);
     30                super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
     31
    3532                if (value == null) {
     33                        setText("!null value");
    3634                        return this;
    3735                }
    38                 if (!(value instanceof TreeNode)) {
     36
     37                if (!(value instanceof AbstractNode)) {
    3938                        setIcon(ImageProvider.loadImage(ImageProvider.SERVER));
    4039                        setText("framsticks");
    4140                        return this;
    4241                }
    43                 TreeNode treeNode = (TreeNode)value;
    44                 assert treeNode.getFrame().isActive();
    45                 setToolTipText(treeNode.getTooltip());
    46                 setIcon(ImageProvider.loadImage(treeNode.getIconName()));
    47                 setText(treeNode.getName());
     42                ((AbstractNode) value).render(this);
     43
    4844                return this;
    4945        }
    5046
    51         public static String findIconName(String nodeName, String path) {
    52                 if (nodeName == null || path == null) {
    53                         log.warn("given invalid parameters: " + nodeName + " " + path);
    54                         // return null;
    55                         return ImageProvider.SERVER;
     47        public static String findIconName(CompositeParam param) {
     48                switch (param.getFramsTypeName()) {
     49                        case "o Server": return ImageProvider.SERVER;
     50                        case "o Simulator": return ImageProvider.SIMULATOR;
     51                        case "o CLI": return ImageProvider.CLI;
     52                        case "o World": return ImageProvider.WORLD;
     53                        case "o GenePools": return ImageProvider.GENEPOOLS;
     54                        case "l GenePool": return ImageProvider.SIMULATOR; //HERE
     55                        case "o GenePool": return ImageProvider.GENEPOOLS_GROUP; //HERE
     56
     57                        case "o Populations": return ImageProvider.POPULATIONS;
     58                        case "l Population": return ImageProvider.SIMULATOR; ///HERE
     59                        case "o Population": return ImageProvider.POPULATION_GROUP;
     60                        case "o ExpParams": return ImageProvider.EXPERIMENT;
     61                        case "o stats": return ImageProvider.STATISTIC;
     62                        case "l Genotype uid": return ImageProvider.GENOTYPES_GROUP;
     63                        case "o Genotype": return ImageProvider.GENOTYPES;
     64
     65                        case "o Part": return ImageProvider.PART;
     66                        case "o Joint": return ImageProvider.JOINT;
     67                        case "o NeuroDef": return ImageProvider.NEURON_DEF;
     68                        case "o NeuroConn": return ImageProvider.NEURON_DEF;
     69
     70                        case "o MechPart": return ImageProvider.MECH_PART;
     71                        case "o MechJoint": return ImageProvider.MECH_JOINT;
     72                        case "o Neuro": return ImageProvider.NEURON;
     73
     74                        case "l Part": return ImageProvider.PART_GROUP;
     75                        case "l Joint": return ImageProvider.JOINT_GROUP;
     76                        case "l NeuroDef": return ImageProvider.NEURON_DEF_GROUP;
     77                        case "l NeuroConn": return ImageProvider.NEURON_DEF_GROUP;
     78
     79                        case "l MechPart": return ImageProvider.MECH_PART_GROUP;
     80                        case "l MechJoint": return ImageProvider.MECH_JOINT_GROUP;
     81                        case "l Neuro": return ImageProvider.NEURON_GROUP;
     82
     83                        case "o Creature": return ImageProvider.CREATURE;
     84                        case "l Creature uid": return ImageProvider.CREATURES_GROUP;
     85                        case "l Event id": return ImageProvider.EVENT;
     86                        case "o Event": return ImageProvider.EVENT;
     87
    5688                }
    57                 if (path.equals("/")) {
    58                         return ImageProvider.SERVER;
    59                 }
    60                 if (path.endsWith("simulator")) {
    61                         return ImageProvider.SIMULATOR;
    62                 }
    63                 if (path.endsWith("cli")) {
    64                         return ImageProvider.CLI;
    65                 }
    66                 if (path.endsWith("world")) {
    67                         return ImageProvider.WORLD;
    68                 }
    69                 if (path.endsWith("genepools")) {
    70                         return ImageProvider.GENEPOOLS;
    71                 }
    72                 if (path.endsWith("populations")) {
    73                         return ImageProvider.POPULATIONS;
    74                 }
    75                 if (path.endsWith("experiment")) {
    76                         return ImageProvider.EXPERIMENT;
    77                 }
    78                 if (path.endsWith("stats")) {
    79                         return ImageProvider.STATISTIC;
    80                 }
    81                 if (nodeName.equals("creatures") || path.endsWith("creatures")) {
    82                         return ImageProvider.CREATURES_GROUP;
    83                 }
    84                 if (nodeName.equals("Favourite Fields")) {
    85                         return ImageProvider.FAVORITE_FIELDS;
    86                 }
    87                 if (nodeName.equals("genotypes") || path.endsWith("creatures")) {
    88                         return ImageProvider.GENOTYPES_GROUP;
    89                 }
    90                 if (nodeName.equals("parts") || path.endsWith("parts")) {
    91                         return ImageProvider.PART_GROUP;
    92                 }
    93                 if (nodeName.equals("joints") || path.endsWith("joints")) {
    94                         return ImageProvider.JOINT_GROUP;
    95                 }
    96                 if (nodeName.equals("neurodefs") || path.endsWith("neurodefs")) {
    97                         return ImageProvider.NEURON_DEF_GROUP;
    98                 }
    99                 if (nodeName.equals("neuroconns") || path.endsWith("neuroconns")) {
    100                         return ImageProvider.NEURON_DEF_GROUP;
    101                 }
    102                 if (nodeName.equals("mechparts") || path.endsWith("mechparts")) {
    103                         return ImageProvider.MECH_PART_GROUP;
    104                 }
    105                 if (nodeName.equals("mechjoints") || path.endsWith("mechjoints")) {
    106                         return ImageProvider.MECH_JOINT_GROUP;
    107                 }
    108                 if (nodeName.equals("neurons") || path.endsWith("neurons")) {
    109                         return ImageProvider.NEURON_GROUP;
    110                 }
    111                 if (path.matches("^.*parts/[0-9]+$")) {
    112                         return ImageProvider.PART;
    113                 }
    114                 if (path.matches("^.*joints/[0-9]+$")) {
    115                         return ImageProvider.JOINT;
    116                 }
    117                 if (path.matches("^.*neurodefs/[0-9]+$")) {
    118                         return ImageProvider.NEURON_DEF;
    119                 }
    120                 if (path.matches("^.*neuroconns/[0-9]+$")) {
    121                         return ImageProvider.NEURON_DEF;
    122                 }
    123                 if (path.matches("^.*mechparts/[0-9]+$")) {
    124                         return ImageProvider.MECH_PART;
    125                 }
    126                 if (path.matches("^.*mechjoints/[0-9]+$")) {
    127                         return ImageProvider.MECH_JOINT;
    128                 }
    129                 if (path.matches("^.*neurons/[0-9]+$")) {
    130                         return ImageProvider.NEURON;
    131                 }
    132                 if (path.matches("^.*creatures/c[0-9]+$")) {
    133                         return ImageProvider.CREATURE;
    134                 }
    135                 if (path.matches("^.*genotypes/g[0-9]+$")) {
    136                         return ImageProvider.GENOTYPES;
    137                 }
    138                 if (path.matches("^.*populations/groups/[0-9]+$")) {
    139                         return ImageProvider.POPULATION_GROUP;
    140                 }
    141                 if (path.matches("^.*genepools/groups/[0-9]+$")) {
    142                         return ImageProvider.GENEPOOLS_GROUP;
    143                 }
    144                 if (path.matches("^.*events/e[0-9]+$")) {
    145                         return ImageProvider.EVENT;
    146                 }
    147                 return ImageProvider.SIMULATOR;
     89
     90
     91                return ImageProvider.SERVER;
    14892        }
    14993
    15094
     95
    15196}
Note: See TracChangeset for help on using the changeset viewer.