Index: java/main/src/main/java/com/framsticks/gui/ObjectPanel.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 77)
+++ java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 84)
@@ -1,85 +1,45 @@
 package com.framsticks.gui;
 
-import com.framsticks.gui.components.Control;
-import com.framsticks.gui.components.ValueControl;
-import com.framsticks.gui.components.ValueControlListener;
+import com.framsticks.gui.controls.Control;
+import com.framsticks.gui.controls.ValueControl;
+import com.framsticks.gui.controls.ValueControlListener;
 import com.framsticks.params.AccessInterface;
-import com.framsticks.params.types.CompositeParam;
 import com.framsticks.params.Param;
-import com.framsticks.util.Strings;
+import com.framsticks.params.ValueParam;
+
 import org.apache.log4j.Logger;
 
 import javax.swing.*;
-import java.awt.*;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.List;
+import static com.framsticks.util.lang.Containers.filterInstanceof;
 
 @SuppressWarnings("serial")
-public class ObjectPanel extends com.framsticks.gui.Panel {
+public class ObjectPanel extends ModifiablePanel {
 
-	private static final Logger LOGGER = Logger.getLogger(ObjectPanel.class.getName());
+	private static final Logger log = Logger.getLogger(ObjectPanel.class.getName());
 
 	final protected Map<Param, Control> components = new HashMap<Param, Control>();
-	final protected Map<Param, ValueControl> valueComponents = new HashMap<Param, ValueControl>();
+	final protected Map<ValueParam, ValueControl> valueControls = new HashMap<ValueParam, ValueControl>();
 
-	public static void fillWithComponents(JPanel panel, Collection<Param> params, Map<Param, Control> components) {
-		for (Param param : params) {
-			if (param.isUserHidden()) {
-				continue;
-			}
-			assert !(param instanceof CompositeParam);
-			Control control = Control.createSuitable(param);
-			if (control != null) {
-				LOGGER.debug("add component for " + param);
-				JPanel line = new JPanel();
-				line.setLayout(new BoxLayout(line, BoxLayout.LINE_AXIS));
-				line.setAlignmentX(LEFT_ALIGNMENT);
-				JLabel label = new JLabel(Strings.notEmpty(param.getName()) ? param.getName() : "? (" + param.getId() + ")");
-				label.setToolTipText(label.getText());
-				label.setHorizontalAlignment(JLabel.RIGHT);
-				Dimension labelSize = new Dimension(150, 30);
-				label.setMaximumSize(labelSize);
-				label.setMinimumSize(labelSize);
-				label.setPreferredSize(labelSize);
-				line.add(label);
-				line.add(Box.createRigidArea(new Dimension(8, 0)));
-				line.add(control);
-				line.revalidate();
-				panel.add(line);
-				panel.add(Box.createRigidArea(new Dimension(0, 8)));
-				//component.setAlignmentX(LEFT_ALIGNMENT);
-				components.put(param, control);
-				continue;
-			}
-			LOGGER.error("component for param " + param + " of type " + param.getClass().getSimpleName() + " was not added");
-		}
+	public ObjectPanel(Panel.Parameters parameters, Collection<Param> params) {
+		super(parameters);
 
-	}
+		Gui.fillWithControls(contentPanel, params, components);
 
-	public ObjectPanel(EndpointAtFrame endpoint, String className, List<Param> params) {
-		super(endpoint, className);
-
-		fillWithComponents(contentPanel, params, components);
-
-		for (Map.Entry<Param, Control> e : components.entrySet()) {
-			Control control = e.getValue();
-			Param param = e.getKey();
-			if (control instanceof ValueControl) {
-				final ValueControl valueComponent = (ValueControl) control;
-				valueComponents.put(param, valueComponent);
-				valueComponent.setListener(new ValueControlListener() {
-					@Override
-					public boolean onChange(Object newValue) {
-						if (currentTreeNode == null) {
-							return true;
-						}
-						boolean result = currentTreeNode.changeValue(valueComponent, newValue);
-						refreshControlButtons();
-						return result;
+		for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
+			valueControls.put(c.getParam(), c);
+			c.setListener(new ValueControlListener() {
+				@Override
+				public boolean onChange(Object newValue) {
+					if (currentTreeNode == null) {
+						return true;
 					}
-				});
-			}
+					boolean result = currentTreeNode.changeValue(c, newValue);
+					refreshControlButtons();
+					return result;
+				}
+			});
 		}
 		contentPanel.add(Box.createVerticalGlue());
@@ -91,65 +51,71 @@
 		assert frame.isActive();
 		assert currentTreeNode != null;
-		currentTreeNode.applyChanges();
+		currentTreeNode.pushLocalChanges();
 	}
 
 	protected void refreshControlButtons() {
 		assert frame.isActive();
-		applyButton.setEnabled(currentTreeNode.changedValues != null);
+		applyButton.setEnabled(currentTreeNode.localChanges != null);
+	}
+
+	protected static void fillControlsWithValues(Map<ValueControl, Object> map) {
 	}
 
 	@Override
-	public void refreshComponents(AccessInterface access) {
-        assert currentTreeNode.path.getInstance().isActive();
-        assert currentTreeNode != null;
-        LOGGER.debug("refreshing components");
+	public void pullValuesFromLocalToUser(AccessInterface access) {
+		assert currentTreeNode != null;
+		assert currentTreeNode.path.getInstance().isActive();
+		log.debug("refreshing components");
 
-        final Map<ValueControl, Object> values = new HashMap<ValueControl, Object>();
-        for (ValueControl vc : valueComponents.values()) {
-            Object value = access.get(vc.getParam().getId(), Object.class);
-            values.put(vc, value);
-        }
+		final Map<ValueControl, Object> values = new HashMap<ValueControl, Object>();
+		for (Map.Entry<ValueParam, ValueControl> e : valueControls.entrySet()) {
+			values.put(e.getValue(), access.get(e.getKey().getId(), Object.class));
+		}
 
-        frame.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
-                    e.getKey().setValue(e.getValue());
-                }
-				if (currentTreeNode.changedValues != null) {
-					for (Map.Entry<ValueControl, Object> e : currentTreeNode.changedValues.entrySet()) {
-						e.getKey().setValue(e.getValue());
+		frame.invokeLater(new Runnable() {
+			@Override
+			public void run() {
+				if (currentTreeNode.localChanges != null) {
+					for (Map.Entry<ValueControl, Object> e : currentTreeNode.localChanges.entrySet()) {
+						values.put(e.getKey(), e.getValue());
 					}
 				}
+				for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
+					e.getKey().pushValueToUserInterface(e.getValue());
+				}
 				refreshControlButtons();
-                ObjectPanel.this.revalidate();
-            }
-        });
+				ObjectPanel.this.revalidate();
+			}
+		});
 
 	}
 
+	@Override
+	public String getTitle() {
+		return "Properties";
+	}
 
 
-/*	public void updateValue() {
-		//assert panel.getFrame().isActive();
+	// public void updateValue() {
+	// 	//assert panel.getFrame().isActive();
 
-        final Node n = panel.getCurrentNode();
-        panel.getBrowser().getManager().invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                Object v = n.getAccess().get(param, Object.class);
-                if (v == null) {
-                    v = param.getDef(Object.class);
-                }
-                final Object fv = v;
-                panel.getBrowser().invokeLater(new Runnable() {
-                    @Override
-                    public void run() {
-                        setValueImpl(fv);
-                    }
-                });
-            }
-        });
-	}*/
+	// 	final Node n = panel.getCurrentNode();
+	// 	panel.getBrowser().getManager().invokeLater(new Runnable() {
+	// 		@Override
+	// 		public void run() {
+	// 			Object v = n.getAccess().get(param, Object.class);
+	// 			if (v == null) {
+	// 				v = param.getDef(Object.class);
+	// 			}
+	// 			final Object fv = v;
+	// 			panel.getBrowser().invokeLater(new Runnable() {
+	// 				@Override
+	// 				public void run() {
+	// 					setValueImpl(fv);
+	// 				}
+	// 			});
+	// 		}
+	// 	});
+	// }
 
 }
