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

HIGHLIGHTS:

  • improve tree side notes
  • improve GUI layout
  • add foldable list of occured events to EventControl?
  • improve automatic type conversion in proxy listeners
  • implement several Access functionalities as algorithms independent of Access type
  • introduce draft base classes for distributed experiments
  • automatically register dependant Java classes to FramsClass? registry
  • add testing prime experiment and configuration
  • simplify and improve task dispatching

CHANGELOG:
Improve task dispatching in RemoteTree?.

GUI no longer hangs on connection problems.

Make all dispatchers joinables.

Refactorize Thread dispatcher.

Remove Task and PeriodicTask?.

Use Java utilities in those situations.

Reworking tasks dispatching.

Fix bug in EventControl? listener dispatching.

Minor improvements.

Add testing configuration for ExternalProcess? in GUI.

More improvement to prime.

Support for USERREADONLY in GUI.

Add that flag to various params in Java classes.

Remove redundant register clauses from several FramsClassAnnotations?.

Automatically gather and register dependant classes.

Add configuration for prime.

Improve Simulator class.

Add prime.xml configuration.

Introduce draft Experiment and Simulator classes.

Add prime experiment tests.

Enclose typical map with listeners into SimpleUniqueList?.

Needfile works in GUI.

Improve needfile handling in Browser.

More improvement with NeedFile?.

Implementing needfile.

Update test.

Rename ChangeEvent? to TestChangeEvent?.

Automatic argument type search in RemoteTree? listeners.

MultiParamLoader? uses AccessProvider?. By default old implementation
enclosed in AccessStash? or Registry.

Minor changes.

Rename SourceInterface? to Source.

Also improve toString of File and ListSource?.

Remove unused SimpleSource? class.

Add clearing in HistoryControl?.

Show entries in table at EventControl?.

Improve EventControl?.

Add listeners registration to EventControl?.

Add foldable table to HistoryControl?.

Add control row to Procedure and Event controls.

Improve layout of controls.

Another minor change to gui layout.

Minor improvement in the SliderControl?.

Minor changes.

Move ReflectionAccess?.Backend to separate file.

It was to cluttered.

Cleanup in ReflectionAccess?.

Move setMin, setMax, setDef to AccessOperations?.

Extract loading operation into AccessOperations?.

Append Framsticks to name of UnsupportedOperationException?.

The java.lang.UnsupportedOperationException? was shadowing this class.

Rename params.Util to params.ParamsUtil?.

Several improvements.

Minor changes.

Implement revert functionality.

Improve local changes management.

Minor improvement.

Remove methods rendered superfluous after SideNoteKey? improvement.

Improve SideNoteKey?.

It is now generic type, so explicit type specification at
call site is no more needed.

Introduce SideNoteKey? interface.

Only Objects implementing that key may be used as side note keys.

Minor improvements.

Use strings instead of ValueControls? in several gui mappings.

Location:
java/main/src/main/java/com/framsticks/gui
Files:
3 added
2 deleted
26 edited

Legend:

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

    r100 r101  
    11package com.framsticks.gui;
    22
     3import com.framsticks.communication.File;
     4import com.framsticks.communication.queries.NeedFile;
     5import com.framsticks.communication.queries.NeedFileAcceptor;
    36import com.framsticks.core.*;
    47import com.framsticks.gui.console.Console;
     
    912import com.framsticks.params.annotations.FramsClassAnnotation;
    1013import com.framsticks.params.annotations.ParamAnnotation;
     14import com.framsticks.parsers.FileSource;
    1115import com.framsticks.remote.RemoteTree;
    1216import com.framsticks.util.FramsticksException;
     
    2226
    2327import javax.swing.*;
     28import javax.swing.filechooser.FileNameExtensionFilter;
    2429
    2530import org.apache.logging.log4j.Logger;
     
    3035import java.awt.datatransfer.StringSelection;
    3136import java.awt.event.ActionEvent;
     37import java.awt.event.ActionListener;
     38import java.awt.event.WindowAdapter;
     39import java.awt.event.WindowEvent;
     40import java.io.IOException;
    3241import java.util.ArrayList;
    3342import java.util.LinkedList;
    3443import java.util.List;
     44import java.util.regex.Matcher;
     45import java.util.regex.Pattern;
     46
    3547import com.framsticks.util.dispatching.RunAt;
     48import com.framsticks.util.lang.Strings;
    3649
    3750/**
     
    132145        }
    133146
     147        protected static final Pattern extensionFilterPattern = Pattern.compile("\\*\\.(\\S+)");
     148
    134149        @AutoAppendAnnotation
    135         public void addTree(Tree tree) {
     150        public void addTree(final Tree tree) {
    136151                log.debug("adding tree: {}", tree);
    137152                tree.setDispatcher(new SwingDispatcher<Tree>());
    138153                tree.setExceptionHandler(this);
    139154                trees.add(tree);
     155
     156                final NeedFileAcceptor acceptor = new NeedFileAcceptor() {
     157
     158                        protected boolean done = false;
     159
     160                        @Override
     161                        public boolean acceptNeed(final NeedFile needFile) {
     162                                final JFileChooser chooser = new JFileChooser();
     163                                final JFrame frame = new JFrame();
     164
     165                                frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
     166
     167                                frame.addWindowListener(new WindowAdapter() {
     168                                        @Override
     169                                        public void windowClosing(WindowEvent e) {
     170                                                if (!done) {
     171                                                        needFile.getFuture().handle(new FramsticksException().msg("user closed the window"));
     172                                                }
     173                                                frame.setVisible(false);
     174                                                frame.dispose();
     175                                        }
     176                                });
     177
     178                                frame.setTitle(Strings.toStringEmptyProof(needFile.getDescription(), "Choose file"));
     179                                chooser.setMultiSelectionEnabled(false);
     180                                Matcher matcher = extensionFilterPattern.matcher(needFile.getSuggestedName());
     181                                if (matcher.matches()) {
     182                                        chooser.setFileFilter(new FileNameExtensionFilter(Strings.toStringEmptyProof(needFile.getDescription(), "file"), Strings.takeGroup(needFile.getSuggestedName(), matcher, 1).toString()));
     183                                }
     184
     185                                frame.getContentPane().add(chooser);
     186
     187                                chooser.addActionListener(new ActionListener() {
     188
     189                                        @Override
     190                                        public void actionPerformed(ActionEvent event) {
     191                                                if (event.getActionCommand().equals("CancelSelection")) {
     192                                                        needFile.getFuture().handle(new FramsticksException().msg("user cancelled choose"));
     193                                                        frame.setVisible(false);
     194                                                        frame.dispose();
     195                                                }
     196                                                if (event.getActionCommand().equals("ApproveSelection")) {
     197                                                        File file = null;
     198                                                        String filename = chooser.getSelectedFile().getAbsolutePath();
     199                                                        try {
     200                                                                file = new File("", new FileSource(filename));
     201                                                        } catch (IOException e) {
     202                                                                needFile.getFuture().handle(new FramsticksException().msg("failed to open choosed file").arg("filename", filename).cause(e));
     203                                                        }
     204                                                        if (file != null) {
     205                                                                done = true;
     206                                                                needFile.getFuture().pass(file);
     207                                                        }
     208                                                        frame.setVisible(false);
     209                                                        frame.dispose();
     210                                                }
     211                                        }
     212                                });
     213                                frame.setVisible(true);
     214                                return true;
     215                        }
     216                };
     217
     218                tree.dispatch(new RunAt<Tree>(this) {
     219                        @Override
     220                        protected void runAt() {
     221                                log.debug("adding need file acceptor: {}", acceptor);
     222                                tree.addNeedFileAcceptor(Integer.MAX_VALUE, acceptor);
     223                        }
     224                });
     225
    140226        }
    141227
     
    143229                // final Tree i = trees.get("localhost");
    144230                // i.dispatch(new RunAt<Tree>(future) {
    145                 //      @Override
    146                 //      protected void runAt() {
    147                 //              TreeOperations.tryGet(i, path, new FutureHandler<Path>(future) {
    148                 //                      @Override
    149                 //                      protected void result(final Path p) {
    150                 //                              future.pass(p);
    151                 //                              mainFrame.dispatch(new RunAt<Frame>(future) {
    152                 //                                      @Override
    153                 //                                      protected void runAt() {
    154                 //                                              mainFrame.goTo(p);
    155                 //                                      }
    156                 //                              });
    157                 //                      }
    158                 //              });
    159                 //      }
     231                //      @Override
     232                //      protected void runAt() {
     233                //              TreeOperations.tryGet(i, path, new FutureHandler<Path>(future) {
     234                //                      @Override
     235                //                      protected void result(final Path p) {
     236                //                              future.pass(p);
     237                //                              mainFrame.dispatch(new RunAt<Frame>(future) {
     238                //                                      @Override
     239                //                                      protected void runAt() {
     240                //                                              mainFrame.goTo(p);
     241                //                                      }
     242                //                              });
     243                //                      }
     244                //              });
     245                //      }
    160246                // });
    161247        }
     
    183269                                                protected void runAt() {
    184270                                                        final Path p = Path.to(i, "/");
     271                                                        log.debug("adding path: {}", p);
    185272                                                        dispatch(new RunAt<Browser>(this) {
    186273                                                                @Override
  • java/main/src/main/java/com/framsticks/gui/Frame.java

    r100 r101  
    243243                        @Override
    244244                        public void actionPerformed(ActionEvent actionEvent) {
    245                                 interrupt();
     245                                interruptJoinable();
    246246                        }
    247247                });
     
    268268                log.debug("trying mount: {}", path);
    269269                if (!tree.getAssignedRoot().isResolved()) {
     270                        log.debug("root not yet assigned, geting root");
    270271                        tree.get(path, new FutureHandler<Path>(this) {
    271272
  • java/main/src/main/java/com/framsticks/gui/FrameJoinable.java

    r100 r101  
    3131         */
    3232        public FrameJoinable() {
    33                 statusBar = new StatusBar();
     33                statusBar = new StatusBar(this);
    3434        }
    3535
     
    101101                        @Override
    102102                        protected void runAt() {
    103                                 finish();
     103                                finishJoinable();
    104104                        }
    105105                });
     
    135135                        public void windowClosing(WindowEvent e) {
    136136                                log.info("received closing");
    137                                 interrupt();
     137                                interruptJoinable();
    138138                        }
    139139                });
  • java/main/src/main/java/com/framsticks/gui/Gui.java

    r100 r101  
    77import javax.swing.Box;
    88import javax.swing.BoxLayout;
     9import javax.swing.JComponent;
    910import javax.swing.JLabel;
    1011import javax.swing.JPanel;
     12import javax.swing.border.TitledBorder;
    1113
    1214import org.apache.logging.log4j.Logger;
     
    2426import com.framsticks.params.CompositeParam;
    2527import com.framsticks.params.Param;
     28import com.framsticks.params.ParamFlags;
    2629import com.framsticks.params.PrimitiveParam;
    2730import com.framsticks.params.types.BinaryParam;
     
    101104        }
    102105
    103         public static <P extends Param, C extends Control> void fillWithControls(ControlOwner owner, Collection<P> params, Map<P, C> components, Class<C> controlType) {
    104                 JPanel panel = owner.getPanelForControls();
     106        public static <P extends Param, C extends Control> void fillWithControls(ControlOwner owner, JPanel panel, Collection<P> params, Map<String, C> components, Class<C> controlType) {
     107                panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
    105108                for (P param : params) {
    106                         if (param.isUserHidden()) {
     109                        if (param.hasFlag(ParamFlags.USERHIDDEN)) {
    107110                                continue;
    108111                        }
     
    122125                        line.setLayout(new BoxLayout(line, BoxLayout.LINE_AXIS));
    123126                        line.setAlignmentX(JPanel.LEFT_ALIGNMENT);
    124                         JLabel label = new JLabel(Strings.notEmpty(param.getName()) ? param.getName() : (Strings.notEmpty(param.getId()) ? param.getId() : "?"));
    125                         label.setToolTipText(control.getToolTipText());
    126                         label.setHorizontalAlignment(JLabel.RIGHT);
    127                         Dimension labelSize = new Dimension(150, 30);
    128                         label.setMaximumSize(labelSize);
    129                         label.setMinimumSize(labelSize);
    130                         label.setPreferredSize(labelSize);
    131                         line.add(label);
    132                         line.add(Box.createRigidArea(new Dimension(8, 0)));
     127
    133128                        line.add(control);
    134129                        line.revalidate();
    135130                        panel.add(line);
    136131                        panel.add(Box.createRigidArea(new Dimension(0, 8)));
     132                        components.put(param.getId(), control);
    137133                        //component.setAlignmentX(LEFT_ALIGNMENT);
    138                         components.put(param, control);
     134                        // components.put(param.getId(), control);
    139135                }
    140136
    141137        }
     138
     139        public static String getBestName(Param param) {
     140                if (Strings.notEmpty(param.getName())) {
     141                        return param.getName();
     142                }
     143                if (Strings.notEmpty(param.getId())) {
     144                        return param.getId();
     145                }
     146                return "?";
     147        }
     148
     149        public static void setupTitledControl(Control control, JComponent... components) {
     150
     151                control.setLayout(new BoxLayout(control, BoxLayout.PAGE_AXIS));
     152                control.setBorder(new TitledBorder(Gui.getBestName(control.getParam())));
     153                for (JComponent c : components) {
     154                        // control.add(Box.createRigidArea(new Dimension(0, 4)));
     155                        control.add(c);
     156                }
     157        }
     158
     159        public static void layoutInRow(JPanel panel, JComponent first, JComponent... components) {
     160                panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
     161                panel.setAlignmentX(JPanel.LEFT_ALIGNMENT);
     162
     163                panel.add(first);
     164                for (JComponent c : components) {
     165                        panel.add(Box.createRigidArea(new Dimension(8, 0)));
     166                        panel.add(c);
     167                }
     168        }
     169
     170        public static void addLeftToLabel(Control control, JComponent... components) {
     171
     172                JLabel label = new JLabel(getBestName(control.getParam()));
     173                label.setToolTipText(control.getToolTipText());
     174                label.setHorizontalAlignment(JLabel.LEFT);
     175                Dimension labelSize = new Dimension(150, 30);
     176                label.setMaximumSize(labelSize);
     177                label.setMinimumSize(labelSize);
     178                label.setPreferredSize(labelSize);
     179
     180                layoutInRow(control, label, components);
     181
     182        }
    142183}
  • java/main/src/main/java/com/framsticks/gui/MainFrame.java

    r100 r101  
    7373        }
    7474
    75         // private void onConnectionEstablished() {
    76                 // assert isActive();
    77 
    78                 // addNodeActionToTreePopupMenu("Open in console", new NodeAction() {
    79                         // @Override
    80                         // public void actionPerformed(TreeNode treeNode) {
    81                                 // assert isActive();
    82                         // }
    83                 // });
    84 
    85 
    86 
    87 
    88         //      // browser.addNodeActionToTreePopupMenu("Resolve recursively", new NodeAction() {
    89         //      //      @Override
    90         //      //      public void actionPerformed(TreeNode treeNode) {
    91         //      //              final Child child = treeNode.getChild();
    92         //      //              //server.invokeLater(new Runnable() {
    93         //              //              @Override
    94         //              //              public void run() {
    95         //              //                      resolveRecursively(child);
    96         //              //              }
    97         //              //      });
    98         //      // }
    99         //      // });
    100 
    101 
    102                 // // addNodeActionToTreePopupMenu("Store in file", new NodeAction() {
    103                 // //     @Override
    104                 // //     public void actionPerformed(final TreeNode treeNode) {
    105                 // //         // final Node node = treeNode.getNode();
    106                 // //         // server.invokeLater(new Runnable() {
    107                 // //         //     @Override
    108                 // //         //     public void run() {
    109                 // //         //         try {
    110                 // //         //             log.info("storing");
    111                 // //         //             //File file = new File();
    112                 // //         //             StoreStream stream = new StoreStream(file, server.getManager());
    113                 // //         //             stream.store(node);
    114                 // //         //         } catch (FileNotFoundException e) {
    115                 // //         //             e.printStackTrace();
    116                 // //         //         }
    117                 // //         //     }
    118                 // //         // });
    119                 // //     }
    120                 // // });
    121 
    122 
    123         //      // arguments.forEach("resolve", new UnaryFunctor<Boolean, String>() {
    124         //      //      @Override
    125         //      //      public Boolean call(final String s) {
    126         //      //              server.getManager().resolvePath(s, new StateFunctor() {
    127         //      //                      @Override
    128         //      //                      public void call(Exception e) {
    129         //      //                              if (e != null) {
    130         //      //                                      log.error("failed to resolve: {}", s);
    131         //      //                                      return;
    132         //      //                              }
    133         //      //                              log.info("succeeded to resolve: {}", s);
    134         //      //                      }
    135         //      //              });
    136         //      //              return true;
    137         //      //      }
    138         //      // });
    139 
    140 
    141         //      // arguments.forEach("console", new UnaryFunctor<Boolean, String>() {
    142         //      //      @Override
    143         //      //      public Boolean call(String s) {
    144         //      //              showConsoleFrame().setCommandLine(s);
    145         //      //              return true;
    146         //      //      }
    147         //      // });
    148         // }
    149 
    150 
    151         // /**
    152         //  * Creates panel with start, step, stop buttons.
    153         //  */
    154         // @Override
    155         // protected JPanel createLeftTopPanel() {
    156         //      assert isActive();
    157         //      Dimension buttonDimension = new Dimension(45, 45);
    158 
    159         //      JPanel panel = new JPanel();
    160 
    161         //      stop = new JButton(ImageProvider.loadImage(ImageProvider.SIM_STOP));
    162         //      stop.addActionListener(new ActionListener() {
    163 
    164         //              public void actionPerformed(ActionEvent e) {
    165         //                      setSimulationRunning(false);
    166         //              }
    167 
    168         //      });
    169 
    170         //      stop.setPreferredSize(buttonDimension);
    171         //      stop.setToolTipText("Simulation Stop");
    172         //      stop.setEnabled(false);
    173 
    174         //      step = new JButton(ImageProvider.loadImage(ImageProvider.SIM_STEP));
    175         //      /*
    176         //      step.addActionListener(new ActionListener() {
    177 
    178         //              public void actionPerformed(ActionEvent e) {
    179         //                      connection.send(new CallQuery().setMethod("step").setPath("/simulator"));
    180         //              }
    181 
    182         //      });
    183         //      */
    184 
    185         //      step.setPreferredSize(buttonDimension);
    186         //      step.setToolTipText("Simulation Step");
    187 
    188         //      start = new JButton(ImageProvider.loadImage(ImageProvider.SIM_START));
    189         //      start.addActionListener(new ActionListener() {
    190 
    191         //              public void actionPerformed(ActionEvent e) {
    192         //                      setSimulationRunning(true);
    193         //              }
    194 
    195         //      });
    196 
    197         //      start.setPreferredSize(buttonDimension);
    198         //      start.setToolTipText("Start Simulation");
    199 
    200         //      JPanel buttonPanel = new JPanel();
    201         //      buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
    202         //      buttonPanel.add(Box.createHorizontalStrut(5));
    203         //      buttonPanel.add(stop);
    204         //      buttonPanel.add(Box.createHorizontalStrut(10));
    205         //      buttonPanel.add(step);
    206         //      buttonPanel.add(Box.createHorizontalStrut(10));
    207         //      buttonPanel.add(start);
    208         //      buttonPanel.add(Box.createHorizontalStrut(5));
    209 
    210         //      buttonPanel.setBorder(BorderFactory.createTitledBorder(BorderFactory
    211         //                      .createRaisedBevelBorder(), "Simulation Control",
    212         //                      TitledBorder.CENTER, TitledBorder.DEFAULT_POSITION
    213         //                      ));
    214 
    215         //      panel.setLayout(new BoxLayout(panel, BoxLayout.LINE_AXIS));
    216         //      panel.add(Box.createHorizontalGlue());
    217         //      panel.add(buttonPanel);
    218         //      panel.add(Box.createHorizontalGlue());
    219         //      return panel;
    220         // }
    22175
    22276        /**
     
    248102        }
    249103
    250         // public ConsoleFrame showConsoleFrame() {
    251         //      assert isActive();
    252         //      /*
    253         //      ConsoleFrame consoleFrame = new ConsoleFrame(connection);
    254         //      consoleFrame.show(MainFrame.this);
    255         //      return consoleFrame;
    256         //      */
    257         //      return null;
    258         // }
    259 
    260104        /**
    261105         * Closes connection with manager.
  • java/main/src/main/java/com/framsticks/gui/ModifiablePanel.java

    r100 r101  
    99import java.awt.event.ActionEvent;
    1010import java.awt.event.ActionListener;
     11import static com.framsticks.core.TreeOperations.*;
    1112
    1213/**
     
    2425        protected final JLabel label;
    2526        protected final JButton applyButton;
     27        protected final JButton revertButton;
    2628        protected final JPanel centerPanel;
    2729
     
    3234                log.debug("create panel for type: {}", className);
    3335
    34 
    35 
    3636                JPanel pageEndPanel = new JPanel();
    3737                pageEndPanel.setLayout(new BoxLayout(pageEndPanel, BoxLayout.X_AXIS));
     
    4141                applyButton.setName("apply");
    4242
     43                revertButton = new JButton("Revert");
     44                revertButton.setName("revert");
     45
     46                pageEndPanel.add(applyButton);
     47                pageEndPanel.add(Box.createHorizontalStrut(10));
     48
     49                pageEndPanel.add(revertButton);
     50                pageEndPanel.add(Box.createHorizontalStrut(10));
     51
     52                pageEndPanel.setPreferredSize(new Dimension(0, 30));
     53
    4354                applyButton.addActionListener(new ActionListener() {
    4455                        public void actionPerformed(ActionEvent e) {
     
    4657                        }
    4758                });
    48                 pageEndPanel.add(applyButton);
    4959
    50                 pageEndPanel.add(Box.createHorizontalStrut(10));
    51                 pageEndPanel.setPreferredSize(new Dimension(0, 30));
     60                revertButton.addActionListener(new ActionListener() {
     61                        public void actionPerformed(ActionEvent e) {
     62                                revertChanges();
     63                        }
     64                });
    5265
    5366                label = new JLabel();
     
    6780
    6881        protected abstract void applyChanges();
     82        protected abstract void revertChanges();
    6983
    7084        protected void setupContentComponent(Component contentComponent) {
     
    7387        }
    7488
     89        protected void refreshControlButtons() {
     90                assert frame.isActive();
     91                boolean hasChanges = hasSideNotes(getTree(), getCurrentObject(), treeAtFrame.getUserChangesKey());
     92                applyButton.setEnabled(hasChanges);
     93                revertButton.setEnabled(hasChanges);
     94        }
     95
    7596}
  • java/main/src/main/java/com/framsticks/gui/ObjectPanel.java

    r100 r101  
    55import com.framsticks.gui.controls.ControlOwner;
    66import com.framsticks.gui.controls.ValueControl;
    7 import com.framsticks.gui.controls.ValueControlListener;
    87import com.framsticks.params.Access;
    98import com.framsticks.params.Param;
    10 import com.framsticks.params.ValueParam;
    119
    1210import org.apache.logging.log4j.Logger;
     
    1614
    1715import java.util.Collection;
    18 import java.util.IdentityHashMap;
     16import java.util.HashMap;
    1917import java.util.Map;
    2018import static com.framsticks.util.lang.Containers.filterInstanceof;
    2119
    2220import com.framsticks.util.FramsticksException;
     21
     22import static com.framsticks.core.TreeOperations.*;
    2323
    2424@SuppressWarnings("serial")
     
    2727        private static final Logger log = LogManager.getLogger(ObjectPanel.class);
    2828
    29         final protected Map<Param, Control> components = new IdentityHashMap<Param, Control>();
    30         final protected Map<ValueParam, ValueControl> valueControls = new IdentityHashMap<ValueParam, ValueControl>();
     29        final protected Map<String, Control> controls = new HashMap<String, Control>();
     30        final protected Map<String, ValueControl> valueControls = new HashMap<String, ValueControl>();
    3131
    3232        protected final JPanel contentPanel;
     
    3838                contentPanel = new JPanel();
    3939                scrollPane = new JScrollPane(contentPanel);
    40                 contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.PAGE_AXIS));
     40
    4141                setupContentComponent(scrollPane);
    4242
    43                 Gui.fillWithControls(this, params, components, Control.class);
     43                Gui.fillWithControls(this, contentPanel, params, controls, Control.class);
    4444                setName(framsClass.getId());
    4545
    46                 for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
    47                         valueControls.put(c.getParam(), c);
     46                for (final ValueControl c : filterInstanceof(controls.values(), ValueControl.class)) {
     47                        valueControls.put(c.getParam().getId(), c);
    4848                        c.setUserEnabled(true);
    49                         c.setListener(new ValueControlListener() {
    50                                 @Override
    51                                 public boolean onChange(Object newValue) {
    52                                         if (currentPath == null) {
    53                                                 return true;
    54                                         }
    55                                         boolean result = treeAtFrame.changeValue(currentPath.assureResolved().getTopObject(), c, newValue);
    56                                         refreshControlButtons();
    57                                         return result;
    58                                 }
    59                         });
    6049                }
    6150
     
    6857                assert frame.isActive();
    6958                assert currentPath != null;
    70                 treeAtFrame.pushLocalChanges(currentPath);
     59                treeAtFrame.pushUserChangesToTree(currentPath);
     60                refreshControlButtons();
    7161        }
    7262
    73         protected void refreshControlButtons() {
    74                 assert frame.isActive();
    75                 applyButton.setEnabled(treeAtFrame.hasLocalChanges(currentPath.getTopObject()));
     63
     64        @Override
     65        protected void revertChanges() {
     66                assert currentPath != null;
     67                removeSideNote(currentPath, treeAtFrame.getUserChangesKey());
     68                pullValuesFromLocalToUser(bindAccess(currentPath));
    7669        }
    7770
     
    8174                log.debug("refreshing components");
    8275
    83                 final Map<ValueControl, Object> values = new IdentityHashMap<ValueControl, Object>();
    84                 for (Map.Entry<ValueParam, ValueControl> e : valueControls.entrySet()) {
    85                         values.put(e.getValue(), access.get(e.getKey().getId(), Object.class));
     76                UserChanges userChanges = getSideNote(currentPath, treeAtFrame.getUserChangesKey());
     77
     78
     79                for (Map.Entry<String, ValueControl> e : valueControls.entrySet()) {
     80                        String id = e.getKey();
     81                        Object value;
     82                        if (userChanges != null && userChanges.changes.containsKey(id)) {
     83                                value = userChanges.changes.get(id);
     84                        } else {
     85                                value = access.get(id, Object.class);
     86                        }
     87
     88                        e.getValue().pushValueToUserInterface(value);
    8689                }
    8790
    88 
    89                 NodeAtFrame nodeAtFrame = treeAtFrame.getLocalInfo(currentPath.getTopObject());
    90                 if (nodeAtFrame != null) {
    91                         for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
    92                                 values.put(e.getKey(), e.getValue());
    93                         }
     91                for (Map.Entry<String, Control> e : controls.entrySet()) {
     92                        e.getValue().refreshState();
    9493                }
    9594
    96                 for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
    97                         e.getKey().pushValueToUserInterface(e.getValue());
    98                 }
    9995                refreshControlButtons();
    100                 ObjectPanel.this.revalidate();
    101 
     96                // ObjectPanel.this.revalidate();
    10297        }
    10398
     
    105100        public String getTitle() {
    106101                return "Properties";
    107         }
    108 
    109         @Override
    110         public JPanel getPanelForControls() {
    111                 return contentPanel;
    112102        }
    113103
     
    122112        }
    123113
     114        @Override
     115        public boolean onValueChange(ValueControl control, Object newValue) {
     116                if (currentPath == null) {
     117                        return true;
     118                }
     119                boolean result = treeAtFrame.changeValue(currentPath.assureResolved().getTopObject(), control, newValue);
     120                refreshControlButtons();
     121                return result;
     122        }
     123
    124124}
  • java/main/src/main/java/com/framsticks/gui/StatusBar.java

    r100 r101  
    1515import com.framsticks.util.FramsticksException;
    1616import com.framsticks.util.dispatching.Dispatcher;
     17import com.framsticks.util.dispatching.Dispatching;
    1718import com.framsticks.util.dispatching.ExceptionResultHandler;
    1819import com.framsticks.util.dispatching.RunAt;
    1920
    20 public class StatusBar implements ExceptionResultHandler, Dispatcher<StatusBar> {
     21public class StatusBar implements ExceptionResultHandler {
    2122        private static final Logger log = LogManager.getLogger(StatusBar.class);
    2223
     
    2425        protected JPanel swing;
    2526        protected ExceptionResultHandler exceptionHandler;
     27        protected final Dispatcher<?> dispatcher;
    2628
    2729        /**
    2830         *
    2931         */
    30         public StatusBar() {
     32        public StatusBar(Dispatcher<?> dispatcher) {
     33                this.dispatcher = dispatcher;
     34        }
     35
     36        @SuppressWarnings({"rawtypes", "unchecked"})
     37        public void showInfo(final Object value) {
     38                Dispatching.dispatchIfNotActive(dispatcher, new RunAt(this) {
     39
     40                        @Override
     41                        protected void runAt() {
     42                                String text = value.toString();
     43                                log.info("info: {}", text);
     44                                statusBar.setText(text);
     45
     46                        }
     47                });
    3148        }
    3249
    3350        @Override
     51        @SuppressWarnings({"rawtypes", "unchecked"})
    3452        public void handle(final FramsticksException exception) {
    35                 dispatch(new RunAt<StatusBar>(this) {
     53                dispatcher.dispatch(new RunAt(this) {
    3654
    3755                        @Override
     
    5876        }
    5977
    60         @Override
    61         public boolean isActive() {
    62                 return SwingDispatcher.getInstance().isActive();
    63         }
    64 
    65         @Override
    66         public void dispatch(RunAt<? extends StatusBar> runnable) {
    67                 SwingDispatcher.getInstance().dispatch(runnable);
    68         }
    69 
    7078        /**
    7179         * @return the swing
  • java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java

    r98 r101  
    11package com.framsticks.gui;
    22
    3 import java.awt.event.ActionEvent;
    4 import java.awt.event.ActionListener;
    53
    64import com.framsticks.util.dispatching.AbstractJoinable;
    75import com.framsticks.util.dispatching.Dispatcher;
    8 import com.framsticks.util.dispatching.JoinableDispatcher;
    9 import com.framsticks.util.dispatching.Task;
    106import com.framsticks.util.dispatching.ThrowExceptionHandler;
    117
     
    1612 * @author Piotr Sniegowski
    1713 */
    18 public class SwingDispatcher<C> extends AbstractJoinable implements JoinableDispatcher<C> {
     14public class SwingDispatcher<C> extends AbstractJoinable implements Dispatcher<C> {
    1915
    2016        @SuppressWarnings("rawtypes")
     
    4238        @Override
    4339        public final void dispatch(RunAt<? extends C> runnable) {
    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                 }
    6040                SwingUtilities.invokeLater(runnable);
    6141        }
     
    7353        @Override
    7454        protected void joinableInterrupt() {
    75                 finish();
     55                finishJoinable();
    7656        }
    7757
  • java/main/src/main/java/com/framsticks/gui/TreeAtFrame.java

    r100 r101  
    44import org.apache.logging.log4j.LogManager;
    55
     6import com.framsticks.core.SideNoteKey;
    67import com.framsticks.core.Tree;
    78import com.framsticks.core.Node;
    89import com.framsticks.core.Path;
    9 import com.framsticks.core.TreeOperations;
     10import static com.framsticks.core.TreeOperations.*;
    1011import com.framsticks.gui.controls.ValueControl;
    1112import com.framsticks.params.CompositeParam;
    1213import com.framsticks.params.FramsClass;
     14import com.framsticks.params.PrimitiveParam;
    1315
    1416import java.util.*;
     
    3032        protected Node rootNode;
    3133
     34        protected final SideNoteKey<UserChanges> userChangesKey = SideNoteKey.make(UserChanges.class);
     35
    3236        public TreeAtFrame(Tree tree, Frame frame) {
    3337                this.frame = frame;
     
    4448        public Tree getTree() {
    4549                return tree;
     50        }
     51
     52        /**
     53         * @return the userChangesKey
     54         */
     55        public SideNoteKey<UserChanges> getUserChangesKey() {
     56                return userChangesKey;
    4657        }
    4758
     
    7182                if (panels.isEmpty()) {
    7283                        panel = new EmptyTreePanel(parameters);
    73                 } else  if (panels.size() == 1) {
     84                } else  if (panels.size() == 1) {
    7485                        panel = panels.get(0);
    7586                } else {
     
    8394        }
    8495
    85 
    86         public boolean hasLocalChanges(Object object) {
    87                 NodeAtFrame nodeAtFrame = tree.getSideNote(object, this, NodeAtFrame.class);
    88                 if (nodeAtFrame == null) {
    89                         return false;
    90                 }
    91                 return !nodeAtFrame.localChanges.isEmpty();
    92         }
    93 
    94         public NodeAtFrame assureLocalInfo(Object object) {
    95                 assert frame.isActive();
    96                 NodeAtFrame nodeAtFrame = tree.getSideNote(object, this, NodeAtFrame.class);
    97 
    98                 if (nodeAtFrame == null) {
    99                         nodeAtFrame = new NodeAtFrame();
    100                         // log.debug();
    101                         tree.putSideNote(object, this, nodeAtFrame);
    102                 }
    103                 return nodeAtFrame;
    104         }
    105 
    106         public NodeAtFrame getLocalInfo(Object object) {
    107                 return tree.getSideNote(object, this, NodeAtFrame.class);
    108         }
    109 
    11096        public boolean changeValue(Object object, ValueControl component, Object newValue) {
    11197                log.debug("changing value of {} to '{}'", component, newValue);
    11298
    113                 assureLocalInfo(object).localChanges.put(component, newValue);
     99                getOrCreateSideNote(tree, object, userChangesKey).changes.put(component.getParam().getId(), newValue);
    114100
    115101                return true;
    116102        }
    117103
    118         public void pushLocalChanges(Path path) {
     104
     105        public void pushUserChangesToTree(final Path path) {
    119106                assert frame.isActive();
    120107                path.assureResolved();
    121108
    122                 NodeAtFrame nodeAtFrame = getLocalInfo(path.getTopObject());
    123                 if (nodeAtFrame == null) {
     109                final UserChanges userChanges = getSideNote(path, userChangesKey);
     110                if (userChanges == null) {
    124111                        return;
    125112                }
    126                 for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
    127                         TreeOperations.set(path, e.getKey().getParam(), e.getValue(), new FutureHandler<Integer>(frame) {
     113                removeSideNote(path, userChangesKey);
     114
     115                for (final Map.Entry<String, Object> e : userChanges.changes.entrySet()) {
     116                        set(path, getParam(path, e.getKey(), PrimitiveParam.class), e.getValue(), new FutureHandler<Integer>(frame) {
    128117                                @Override
    129118                                protected void result(Integer flag) {
     119                                        assert frame.isActive();
     120                                        userChanges.changes.remove(e.getKey());
    130121                                }
    131122                        });
  • java/main/src/main/java/com/framsticks/gui/TreePanel.java

    r100 r101  
    22
    33import com.framsticks.core.Path;
    4 import com.framsticks.core.TreeOperations;
     4import com.framsticks.core.Tree;
     5import static com.framsticks.core.TreeOperations.*;
    56import com.framsticks.gui.tree.AbstractNode;
    67import com.framsticks.gui.tree.TreeNode;
     
    2829                }
    2930                setCurrentPath(path);
    30                 pullValuesFromLocalToUser(TreeOperations.bindAccess(path));
     31                pullValuesFromLocalToUser(bindAccess(path));
    3132        }
    3233
     
    7980                return treeAtFrame;
    8081        }
    81 
     82        public final Object getCurrentObject() {
     83                assert currentPath != null;
     84                return currentPath.getTopObject();
     85        }
     86        public final Tree getTree() {
     87                assert currentPath != null;
     88                return currentPath.getTree();
     89        }
    8290
    8391        public final String getClassName() {
  • java/main/src/main/java/com/framsticks/gui/controls/CheckBoxControl.java

    r100 r101  
    1010import org.apache.logging.log4j.LogManager;
    1111
     12import com.framsticks.gui.Gui;
    1213import com.framsticks.params.types.BooleanParam;
    1314
     
    3132                });
    3233                this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Control.LINE_HEIGHT));
    33                 addAsOnlyChild(checkBox);
     34                Gui.addLeftToLabel(this, checkBox);
    3435        }
    3536
  • java/main/src/main/java/com/framsticks/gui/controls/Control.java

    r100 r101  
    11package com.framsticks.gui.controls;
    22
    3 import java.awt.BorderLayout;
     3// import java.awt.BorderLayout;
    44
    5 import javax.swing.JComponent;
     5
    66import javax.swing.JPanel;
    77
     8import com.framsticks.core.Path;
    89import com.framsticks.params.ParamFlags;
    910import com.framsticks.params.Param;
    1011import com.framsticks.util.FramsticksException;
     12import com.framsticks.util.Misc;
    1113import com.framsticks.util.dispatching.ExceptionResultHandler;
    1214
     
    5759
    5860        public final boolean isReadonly() {
    59                 return !userEnabled || param.hasFlag(ParamFlags.READONLY);
     61                return !userEnabled || param.hasFlag(ParamFlags.READONLY) || param.hasFlag(ParamFlags.USERREADONLY);
    6062        }
    6163
    62         protected void addAsOnlyChild(JComponent component) {
    63                 this.setLayout(new BorderLayout());
    64                 this.add(component, BorderLayout.CENTER);
    65         }
    6664
    6765        @Override
     
    7472                owner.handle(exception);
    7573        }
     74
     75        public Path getCurrentPath() {
     76                return owner.getCurrentPath();
     77        }
     78
     79        public Path assureCurrentPath() {
     80                return Misc.throwIfNull(owner.getCurrentPath());
     81        }
     82
     83        public void refreshState() {
     84        }
    7685}
  • java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java

    r100 r101  
    11package com.framsticks.gui.controls;
    22
    3 import javax.swing.JPanel;
    43
    54import com.framsticks.core.Path;
     
    98public interface ControlOwner extends ExceptionResultHandler {
    109
    11         public JPanel getPanelForControls();
    1210        public Path getCurrentPath();
    1311        public Frame getFrame();
     12        public boolean onValueChange(ValueControl control, Object newValue);
    1413
    1514}
  • java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java

    r100 r101  
    11package com.framsticks.gui.controls;
    22
     3import com.framsticks.gui.Gui;
    34import com.framsticks.params.types.EnumParam;
    45import com.framsticks.util.lang.Numbers;
     
    3536                        }
    3637                });
    37                 addAsOnlyChild(list);
     38                Gui.addLeftToLabel(this, list);
    3839        }
    3940
  • java/main/src/main/java/com/framsticks/gui/controls/EventControl.java

    r100 r101  
    11package com.framsticks.gui.controls;
    22
    3 import java.awt.Dimension;
    43import java.awt.event.ActionEvent;
    54import java.awt.event.ActionListener;
    6 
    7 import javax.swing.JButton;
    8 
     5import java.text.SimpleDateFormat;
     6import java.util.ArrayList;
     7import java.util.Date;
     8import java.util.List;
     9
     10
     11
     12import com.framsticks.core.Path;
     13import com.framsticks.core.SideNoteKey;
     14import com.framsticks.gui.Frame;
     15import com.framsticks.gui.Gui;
     16import com.framsticks.gui.table.AbstractTableModel;
     17import com.framsticks.params.EventListener;
    918import com.framsticks.params.types.EventParam;
     19import com.framsticks.util.FramsticksUnsupportedOperationException;
     20import com.framsticks.util.dispatching.Dispatching;
     21import com.framsticks.util.dispatching.FutureHandler;
     22import com.framsticks.util.dispatching.RunAt;
     23import com.framsticks.util.lang.Pair;
     24
     25import static com.framsticks.core.TreeOperations.*;
    1026
    1127/**
     
    1329 */
    1430@SuppressWarnings("serial")
    15 public class EventControl extends Control {
     31public class EventControl extends HistoryControl {
    1632        // private static final Logger log = LogManager.getLogger(EventControl.class.getName());
    1733
    18         protected final JButton button;
    19         boolean subscribed = true;
     34        @SuppressWarnings("rawtypes")
     35        protected final SideNoteKey<EventListener> listenerKey = SideNoteKey.make(EventListener.class);
     36
     37        public static class History {
     38                protected final List<Pair<Date, Object>> entries = new ArrayList<>();
     39        };
     40
     41        protected final SideNoteKey<History> historyKey = SideNoteKey.make(History.class);
     42        protected TableModel tableModel;
    2043
    2144        public EventControl(final EventParam eventParam) {
    2245                super(eventParam);
    2346
    24                 button = new JButton("subscribe");
    25                 this.add(button);
    26                 this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Control.LINE_HEIGHT));
    27 
    28                 button.addActionListener(new ActionListener() {
     47                mainButton.setText("Subscribe");
     48                mainButton.setName("subscription");
     49
     50                tableModel = new TableModel();
     51                resultsTable.setModel(tableModel);
     52
     53                mainButton.addActionListener(new ActionListener() {
    2954                        @Override
    3055                        public void actionPerformed(ActionEvent e) {
    31                                 if (subscribed) {
    32                                         //panel.getCurrentTreeNode().unsubscribe(eventParam);
    33                                 } else {
    34                                         //panel.getCurrentTreeNode().subscribe(eventParam);
     56                                final Path path = assureCurrentPath();
     57                                EventListener<?> listener = getSideNote(path, listenerKey);
     58                                if (listener != null) {
     59                                        removeSideNote(path, listenerKey);
     60                                        refreshState();
     61                                        path.getTree().removeListener(path, getParam(), listener, FutureHandler.doNothing(Void.class, owner.getFrame()));
     62                                        return;
    3563                                }
     64
     65                                final EventListener<Object> newListener = new EventListener<Object>() {
     66                                        @Override
     67                                        public void action(final Object argument) {
     68                                                /** actions can be invoked from anywhere */
     69                                                Dispatching.dispatchIfNotActive(owner.getFrame(), new RunAt<Frame>(owner.getFrame()) {
     70
     71                                                        @Override
     72                                                        protected void runAt() {
     73                                                                getOrCreateSideNote(path.getTree(), path.getTopObject(), historyKey).entries.add(Pair.make(new Date(), argument));
     74                                                                refreshTable();
     75                                                        }
     76                                                });
     77                                                // owner.getFrame().getStatusBar().showInfo("event " + param + " happened: " + argument);
     78                                        }
     79                                };
     80
     81                                path.getTree().addListener(path, getParam(), newListener, Object.class, new FutureHandler<Void>(owner.getFrame()) {
     82
     83                                        @Override
     84                                        protected void result(Void result) {
     85                                                putSideNote(path, listenerKey, newListener);
     86                                                refreshState();
     87                                        }
     88                                });
     89
    3690                        }
    3791                });
    3892
     93                updateFoldState();
     94                Gui.setupTitledControl(this, controlRow, resultsScrollPane);
    3995        }
    4096
    4197        @Override
    4298        protected void updateEnabled(boolean enabled) {
    43                 button.setEnabled(enabled);
    44         }
    45 
    46         /*
    47         @Override
    48         public void refresh() {
    49                 subscribed = panel.getCurrentTreeNode().hasSubscribed((EventParam)param);
    50                 button.setText(subscribed ? "unsubscribe" : "subscribe");
    51                 this.revalidate();
    52         }
    53         */
     99                mainButton.setEnabled(enabled);
     100        }
     101
     102        public boolean isListening() {
     103                return hasSideNote(getCurrentPath(), listenerKey);
     104        }
     105
     106        protected void refreshButtonState() {
     107                mainButton.setText(isListening() ? "Don't listen" : "Listen");
     108        }
     109
     110        @Override
     111        protected void refreshTable() {
     112                History history = getSideNote(assureCurrentPath(), historyKey);
     113                tableModel.entries = history != null ? history.entries : null;
     114                tableModel.refreshAll();
     115        }
     116
     117        @Override
     118        protected void clearTable() {
     119                History history = getSideNote(assureCurrentPath(), historyKey);
     120                if (history != null) {
     121                        history.entries.clear();
     122                }
     123                refreshTable();
     124        }
     125
     126        public void refreshState() {
     127                refreshButtonState();
     128                refreshTable();
     129        }
     130
     131        @Override
     132        public EventParam getParam() {
     133                return (EventParam) param;
     134        }
     135
     136
     137        public class TableModel extends AbstractTableModel {
     138
     139                List<Pair<Date, Object>> entries;
     140                SimpleDateFormat format = new SimpleDateFormat("HH:mm:ss:SSS");
     141
     142                @Override
     143                public Class<?> getColumnClass(int columnIndex) {
     144                        return String.class;
     145                }
     146
     147                @Override
     148                public int getColumnCount() {
     149                        return 2;
     150                }
     151
     152                @Override
     153                public String getColumnName(int columnIndex) {
     154                        return columnIndex == 0 ? "Occured at" : "Argument";
     155                }
     156
     157                @Override
     158                public int getRowCount() {
     159                        if (entries == null) {
     160                                return 0;
     161                        }
     162                        if (isFolded()) {
     163                                return entries.isEmpty() ? 0 : 1;
     164                        }
     165                        return entries.size();
     166                }
     167
     168                @Override
     169                public Object getValueAt(int rowIndex, int columnIndex) {
     170                        if (entries == null) {
     171                                return null;
     172                        }
     173                        Pair<Date, Object> entry;
     174                        if (isFolded()) {
     175                                if (rowIndex > 0) {
     176                                        return null;
     177                                }
     178                                if (entries.isEmpty()) {
     179                                        return null;
     180                                }
     181                                entry = entries.get(entries.size() - 1);
     182                        } else {
     183                                entry = entries.get(rowIndex);
     184                        }
     185                        return columnIndex == 0 ? format.format(entry.first) : entry.second;
     186                }
     187
     188                @Override
     189                public boolean isCellEditable(int rowIndex, int columnIndex) {
     190                        return false;
     191                }
     192
     193                @Override
     194                public void setValueAt(Object value, int rowIndex, int columnIndex) {
     195                        throw new FramsticksUnsupportedOperationException().msg("setting value in event history");
     196                }
     197
     198
     199        }
    54200}
  • java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java

    r100 r101  
    55import com.framsticks.gui.Gui;
    66import com.framsticks.params.Param;
    7 import com.framsticks.params.ValueParam;
    87import com.framsticks.params.types.ProcedureParam;
    98import com.framsticks.util.dispatching.ExceptionResultHandler;
    109import com.framsticks.util.dispatching.FutureHandler;
    1110import com.framsticks.util.dispatching.ThrowExceptionHandler;
    12 import com.framsticks.util.swing.TooltipConstructor;
    1311
    1412import javax.swing.*;
    15 import javax.swing.border.BevelBorder;
    1613
    1714import org.apache.logging.log4j.Logger;
     
    2017import java.awt.event.ActionEvent;
    2118import java.awt.event.ActionListener;
    22 import java.util.IdentityHashMap;
     19import java.util.HashMap;
    2320import java.util.LinkedList;
    2421import java.util.List;
     
    2623
    2724@SuppressWarnings("serial")
    28 public class ProcedureControl extends Control implements ControlOwner {
     25public class ProcedureControl extends HistoryControl implements ControlOwner {
    2926
    3027        private static final Logger log = LogManager.getLogger(ProcedureControl.class);
    3128
    32         protected final JButton procedureButton;
     29        protected final JPanel argumentsPanel;
    3330
    34         final protected Map<ValueParam, ValueControl> components = new IdentityHashMap<>();
     31        final protected Map<String, ValueControl> components = new HashMap<>();
    3532
    3633        public ProcedureControl(ProcedureParam procedureParam) {
    3734                super(procedureParam);
    3835
    39                 this.setToolTipText(new TooltipConstructor()
    40                         .append("name", procedureParam.getName())
    41                         .append("id", procedureParam.getId())
    42                         .append("help", procedureParam.getHelp())
    43                         .build());
    4436
    45                 procedureButton = new JButton("Call");
    46                 procedureButton.setName("call");
     37                mainButton.setText("Call");
     38                mainButton.setName("call");
    4739
    48                 this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
    4940
    50                 Gui.fillWithControls(this, procedureParam.getArgumentsType(), components, ValueControl.class);
     41                argumentsPanel = new JPanel();
     42                argumentsPanel.setName("arguments");
     43
     44                Gui.fillWithControls(this, argumentsPanel, procedureParam.getArgumentsType(), components, ValueControl.class);
    5145
    5246                if (components.size() != procedureParam.getArgumentsType().size()) {
    53                         procedureButton.setEnabled(false);
    54                 }
    55                 if (!components.isEmpty()) {
    56                         this.setBorder(new BevelBorder(BevelBorder.RAISED));
     47                        mainButton.setEnabled(false);
    5748                }
    5849
    59                 procedureButton.addActionListener(new ActionListener() {
     50                mainButton.addActionListener(new ActionListener() {
    6051                        @Override
    6152                        public void actionPerformed(ActionEvent e) {
     
    6556                                final List<Object> arguments = new LinkedList<Object>();
    6657                                for (Param arg : getParam().getArgumentsType()) {
    67                                         Object value = components.get(arg).getCurrentValue();
     58                                        Object value = components.get(arg.getId()).getCurrentValue();
    6859                                        arguments.add(value);
    6960                                        log.debug("argument {}: {}", arg, value);
     
    7465                        }
    7566                });
    76                 this.add(procedureButton);
     67
     68                updateFoldState();
     69                Gui.setupTitledControl(this, argumentsPanel, controlRow, resultsScrollPane);
    7770
    7871        }
     72
    7973
    8074        public static void callProcedure(final Path path, final ProcedureParam param, Object[] arguments) {
     
    9387
    9488        @Override
    95         public JPanel getPanelForControls() {
    96                 return this;
    97         }
    98 
    99         @Override
    10089        public ProcedureParam getParam() {
    10190                return (ProcedureParam) param;
     
    10493        @Override
    10594        protected void updateEnabled(boolean enabled) {
    106                 procedureButton.setEnabled(enabled);
     95                mainButton.setEnabled(enabled);
    10796                for (ValueControl vc : components.values()) {
    10897                        vc.setUserEnabled(enabled);
     
    120109        }
    121110
     111        @Override
     112        public boolean onValueChange(ValueControl control, Object newValue) {
     113                return true;
     114        }
     115
     116        @Override
     117        protected void refreshTable() {
     118                // TODO Auto-generated method stub
     119
     120        }
     121
     122        @Override
     123        protected void clearTable() {
     124                // TODO Auto-generated method stub
     125
     126        }
     127
    122128}
  • java/main/src/main/java/com/framsticks/gui/controls/SliderControl.java

    r100 r101  
    1818import org.apache.logging.log4j.LogManager;
    1919
     20import com.framsticks.gui.Gui;
    2021import com.framsticks.params.types.DecimalParam;
    2122import com.framsticks.params.types.FloatParam;
     
    9899                slider.setPaintTicks(true);
    99100
    100                 this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
    101                 this.setAlignmentX(Box.CENTER_ALIGNMENT);
    102                 this.setAlignmentY(Box.CENTER_ALIGNMENT);
    103 
    104                 JPanel sliderPanel = new JPanel();
    105                 // sliderPanel.setLayout(new BoxLayout(sliderPanel, BoxLayout.LINE_AXIS));
     101
    106102
    107103
     
    140136                }));
    141137
    142                 JPanel sVPanel = new JPanel();
    143                 sVPanel.setLayout(new BoxLayout(sVPanel, BoxLayout.LINE_AXIS));
    144                 sVPanel.add(text);
    145                 Layout.copyComponentDimensions(sVPanel, text);
    146 
    147                 JPanel sPanel = new JPanel();
    148                 sPanel.setLayout(new BoxLayout(sPanel, BoxLayout.LINE_AXIS));
    149 
     138                JPanel valuePanel = new JPanel();
     139                valuePanel.setLayout(new BoxLayout(valuePanel, BoxLayout.LINE_AXIS));
     140                valuePanel.add(text);
     141                Layout.copyComponentDimensions(valuePanel, text);
     142
     143
     144                JPanel sliderPanel = new JPanel();
    150145                sliderPanel.setLayout(new BorderLayout());
    151146                sliderPanel.add(slider, BorderLayout.CENTER);
     
    153148                sliderPanel.setMinimumSize(new Dimension(0, 60));
    154149
    155                 sPanel.add(sVPanel);
    156                 sPanel.add(sliderPanel);
    157 
    158                 this.add(sPanel);
     150
     151                this.setLayout(new BoxLayout(this, BoxLayout.LINE_AXIS));
     152                this.setAlignmentX(Box.CENTER_ALIGNMENT);
     153                this.setAlignmentY(Box.CENTER_ALIGNMENT);
     154
     155                Gui.addLeftToLabel(this, valuePanel, sliderPanel);
    159156        }
    160157
  • java/main/src/main/java/com/framsticks/gui/controls/TextAreaControl.java

    r100 r101  
    11package com.framsticks.gui.controls;
    22
     3import com.framsticks.gui.Gui;
    34import com.framsticks.params.PrimitiveParam;
    45
     
    2728                textArea.setMaximumSize(new Dimension(Integer.MAX_VALUE, maxSize));
    2829
    29                 this.revalidate();
     30                Gui.setupTitledControl(this, textScrollPane);
     31                // this.revalidate();
    3032        }
    3133
  • java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java

    r98 r101  
    11package com.framsticks.gui.controls;
    22
     3import com.framsticks.gui.Gui;
    34import com.framsticks.params.PrimitiveParam;
    45import com.framsticks.util.lang.Strings;
     
    3334                addDefaultDocumentListener(textField);
    3435
    35                 addAsOnlyChild(textField);
     36                Gui.addLeftToLabel(this, textField);
    3637        }
    3738
  • java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java

    r100 r101  
    1212import com.framsticks.util.lang.FlagsUtil;
    1313import com.framsticks.util.swing.TooltipConstructor;
     14// import static com.framsticks.core.TreeOperations.*;
    1415
    1516/**
     
    2021        private static final Logger log =
    2122                LogManager.getLogger(ValueControl.class);
    22 
    23         /**
    24          *
    25          */
    26         protected ValueControlListener listener;
    2723
    2824        public ValueControl(PrimitiveParam<?> primitiveParam) {
     
    6460        public abstract Object pullValueFromUserInterface();
    6561
    66         public void setListener(ValueControlListener listener) {
    67                 this.listener = listener;
    68         }
    69 
    7062        protected Object filterValueThroughConstraints(Object candidate) {
    71                 Object oldValue = pullValueFromUserInterface();
     63                Object oldValue = pullValueFromUserInterface();//bindAccess(owner.getCurrentPath()).get(getParam(), Object.class);
    7264                try {
    7365                        ReassignResult<?> res = getParam().reassign(candidate, oldValue);
     
    9284        protected boolean notifyOfChange() {
    9385                if (!programmaticChange) {
    94                         if (listener == null) {
    95                                 return true;
    96                         }
    97                         return listener.onChange(getCurrentValue());
     86                        return owner.onValueChange(this, getCurrentValue());
    9887                }
    9988                return true;
  • java/main/src/main/java/com/framsticks/gui/table/ListPanel.java

    r100 r101  
    5454                table = new JTable(tableModel);
    5555                tableModel.setupTable();
     56                table.setShowGrid(false);
    5657
    5758                scrollPane = new JScrollPane(table);
     
    7273
    7374        @Override
     75        protected void revertChanges() {
     76        }
     77
     78        @Override
    7479        public void pullValuesFromLocalToUser(Access access) {
    7580                tableModel.attachSource(Casting.throwCast(ListAccess.class, access));
     81                refreshControlButtons();
    7682        }
    7783
     
    8793                return table;
    8894        }
     95
    8996}
  • java/main/src/main/java/com/framsticks/gui/table/PrimitiveColumn.java

    r100 r101  
    22
    33import com.framsticks.params.PrimitiveParam;
    4 import com.framsticks.util.UnsupportedOperationException;
     4import com.framsticks.util.FramsticksUnsupportedOperationException;
    55
    66public class PrimitiveColumn extends Column {
     
    3131        @Override
    3232        public int setValueAt(int rowIndex, Object value) {
    33                 throw new UnsupportedOperationException().msg("setting value in table");
     33                throw new FramsticksUnsupportedOperationException().msg("setting value in table");
    3434        }
    3535
  • java/main/src/main/java/com/framsticks/gui/table/TableModel.java

    r100 r101  
    33import java.util.ArrayList;
    44import java.util.Collections;
    5 import java.util.LinkedList;
    65import java.util.List;
    76
     
    109import javax.swing.JTable;
    1110import javax.swing.UIManager;
    12 import javax.swing.event.TableModelEvent;
    13 import javax.swing.event.TableModelListener;
    1411
    1512import org.apache.logging.log4j.Logger;
     
    2320import com.framsticks.util.lang.Casting;
    2421
    25 public class TableModel implements javax.swing.table.TableModel {
     22public class TableModel extends AbstractTableModel {
    2623
    2724        private static final Logger log = LogManager.getLogger(TableModel.class);
    2825
    29         protected List<TableModelListener> listeners = new LinkedList<>();
    3026        protected ListAccess access;
    3127        protected Access elementAccess;
     
    5248        }
    5349
    54         protected void refreshAll() {
    55                 for (TableModelListener l : listeners) {
    56                         l.tableChanged(new TableModelEvent(this));
    57                 }
    58         }
    5950
    6051        /**
     
    7465        }
    7566
    76         @Override
    77         public void addTableModelListener(TableModelListener listener) {
    78                 listeners.add(listener);
    79         }
    8067
    8168        @Override
     
    114101        }
    115102
    116         @Override
    117         public void removeTableModelListener(TableModelListener listener) {
    118                 listeners.remove(listener);
    119         }
    120103
    121104
  • java/main/src/main/java/com/framsticks/gui/tree/TreeModel.java

    r100 r101  
    1717import com.framsticks.core.Node;
    1818import com.framsticks.core.Path;
     19import com.framsticks.core.SideNoteKey;
    1920import com.framsticks.core.TreeOperations;
    2021import com.framsticks.gui.Frame;
     
    2425import com.framsticks.params.ListAccess;
    2526import com.framsticks.params.PrimitiveParam;
    26 import com.framsticks.params.Util;
     27import com.framsticks.params.ParamsUtil;
    2728import com.framsticks.params.ValueParam;
    2829import com.framsticks.params.types.EventParam;
    2930import com.framsticks.util.FramsticksException;
    3031import com.framsticks.util.Misc;
    31 import com.framsticks.util.UnsupportedOperationException;
     32import com.framsticks.util.FramsticksUnsupportedOperationException;
    3233import com.framsticks.util.dispatching.FutureHandler;
    3334import com.framsticks.util.lang.Casting;
     
    9192        @Override
    9293        public void valueForPathChanged(TreePath path, Object value) {
    93                 throw new UnsupportedOperationException().msg("changing value of tree node");
     94                throw new FramsticksUnsupportedOperationException().msg("changing value of tree node");
    9495        }
    9596
     
    133134        public TreeModelEvent prepareModelEventRegarding(Access access, String id, TreePath treeListPath) {
    134135
    135                 int number = Util.getNumberOfCompositeParamChild(access, access.get(id, Object.class));
     136                int number = ParamsUtil.getNumberOfCompositeParamChild(access, access.get(id, Object.class));
    136137                if (number == -1) {
    137138                        log.debug("encountered minor tree inconsistency in {}", treeListPath);
     
    438439
    439440
    440         protected final Object createdTag = new Object();
     441        protected final SideNoteKey<Boolean> createdTag = SideNoteKey.make(Boolean.class);
    441442
    442443
  • java/main/src/main/java/com/framsticks/gui/tree/TreeNode.java

    r100 r101  
    44import java.util.Iterator;
    55import java.util.LinkedList;
    6 import java.util.List;
    76
    87import org.apache.logging.log4j.LogManager;
     
    1110import com.framsticks.core.Node;
    1211import com.framsticks.core.Path;
     12import com.framsticks.core.SideNoteKey;
    1313import com.framsticks.core.Tree;
    1414import com.framsticks.gui.Frame;
     
    5959                hashCode = System.identityHashCode(path.getTopObject());
    6060
    61                 if (getTree().getSideNote(path.getTopObject(), getTreeModel().createdTag, Object.class) == getTreeModel().createdTag) {
     61                if (isMarked(path.getTree(), path.getTopObject(), getTreeModel().createdTag, false)) {
    6262                        return;
    6363                }
    6464
    6565                // path.getTree().putSideNote(path.getTopObject(), Textual.class, path.getTextual());
    66                 path.getTree().putSideNote(path.getTopObject(), getTreeModel().createdTag, getTreeModel().createdTag);
     66                mark(path.getTree(), path.getTopObject(), getTreeModel().createdTag, true);
    6767
    6868                /** Iterate over all EventParams and for matching ValueParams register listeners. */
     
    239239                }
    240240                Access access = bindAccessForTreeObject(child);
    241                 CompositeParam param = getTree().getSideNote(child, CompositeParam.class, CompositeParam.class);
     241                CompositeParam param = getTree().getSideNote(child, Path.OBJECT_PARAM_KEY);
    242242                String name = param.getId();
    243243
     
    262262        }
    263263
    264         // public static class Textual {
    265         // }
    266264
    267265        public String getTextual() {
    268266                return textual;
    269                 // return getTree().getSideNote(lock(), Textual.class, String.class);
    270         }
    271 
    272         protected final Object listenersTag = new Object();
    273 
    274         public List<EventListener<?>> getListeners() {
    275                 @SuppressWarnings("unchecked")
    276                 List<EventListener<?>> result = getTree().getSideNote(lock(), listenersTag, List.class);
    277                 if (result == null) {
    278                         result = new LinkedList<>();
    279                         getTree().putSideNote(lock(), listenersTag, result);
    280                 }
    281 
    282                 return result;
    283         }
     267        }
     268
     269        @SuppressWarnings("rawtypes")
     270        protected final SideNoteKey<LinkedList> listenersTag = SideNoteKey.make(LinkedList.class);
    284271
    285272        protected <A> void tryAddListener(final Path path, final EventParam eventParam, Class<A> argumentType, final EventListener<A> listener) {
    286273                getTree().addListener(path, eventParam, listener, argumentType, new FutureHandler<Void>(getFrame()) {
     274                        @SuppressWarnings("unchecked")
    287275                        @Override
    288276                        protected void result(Void result) {
    289277                                assert getFrame().isActive();
    290278                                log.debug("registered gui listener for {} at {}", eventParam, path);
    291                                 getListeners().add(listener);
     279                                getOrCreateSideNote(getTree(), lock(), listenersTag).add(listener);
    292280                        }
    293281                });
Note: See TracChangeset for help on using the changeset viewer.