]> source.dussan.org Git - vaadin-framework.git/commitdiff
Slider component serverside almost complete.
authorJouni Koivuviita <jouni.koivuviita@itmill.com>
Sun, 29 Jul 2007 13:17:14 +0000 (13:17 +0000)
committerJouni Koivuviita <jouni.koivuviita@itmill.com>
Sun, 29 Jul 2007 13:17:14 +0000 (13:17 +0000)
ISlider implementation started (minimal support for horizontal sliding).

svn changeset:1918/svn branch:trunk

src/com/itmill/toolkit/terminal/PaintTarget.java
src/com/itmill/toolkit/terminal/gwt/client/DefaultWidgetFactory.java
src/com/itmill/toolkit/terminal/gwt/client/UIDL.java
src/com/itmill/toolkit/terminal/gwt/client/ui/ISlider.java
src/com/itmill/toolkit/terminal/gwt/public/component-themes/collection.css
src/com/itmill/toolkit/terminal/gwt/public/component-themes/slider/css/slider.css [new file with mode: 0644]
src/com/itmill/toolkit/terminal/gwt/server/JsonPaintTarget.java
src/com/itmill/toolkit/ui/Slider.java

index 9b42ef893224ad0a1a39301947607351453bfa82..750fc42282cefda1d9f8f2554bf23100a12d3ed8 100644 (file)
@@ -162,6 +162,20 @@ public interface PaintTarget {
         *             if the paint operation failed.
         */
        public void addAttribute(String name, long value) throws PaintException;
+       
+       /**
+        * Adds a float attribute to component. Atributes must be added before any
+        * content is written.
+        * 
+        * @param name
+        *            the Attribute name.
+        * @param value
+        *            the Attribute value.
+        * 
+        * @throws PaintException
+        *             if the paint operation failed.
+        */
+       public void addAttribute(String name, float value) throws PaintException;
 
        /**
         * Adds a string attribute to component. Atributes must be added before any
@@ -208,6 +222,38 @@ public interface PaintTarget {
         */
        public void addVariable(VariableOwner owner, String name, int value)
                        throws PaintException;
+       
+       /**
+        * Adds a long type variable.
+        * 
+        * @param owner
+        *            the Listener for variable changes.
+        * @param name
+        *            the Variable name.
+        * @param value
+        *            the Variable initial value.
+        * 
+        * @throws PaintException
+        *             if the paint operation failed.
+        */
+       public void addVariable(VariableOwner owner, String name, long value)
+                       throws PaintException;
+       
+       /**
+        * Adds a float type variable.
+        * 
+        * @param owner
+        *            the Listener for variable changes.
+        * @param name
+        *            the Variable name.
+        * @param value
+        *            the Variable initial value.
+        * 
+        * @throws PaintException
+        *             if the paint operation failed.
+        */
+       public void addVariable(VariableOwner owner, String name, float value)
+                       throws PaintException;
 
        /**
         * Adds a boolean type variable.
index ba124ef6b82907786c2c4102994b4b7db1d6c91c..623af04875e5466a213a01f4f7dc3312a20cbe37 100644 (file)
@@ -17,6 +17,7 @@ import com.itmill.toolkit.terminal.gwt.client.ui.IPasswordField;
 import com.itmill.toolkit.terminal.gwt.client.ui.IPopupCalendar;
 import com.itmill.toolkit.terminal.gwt.client.ui.IScrollTable;
 import com.itmill.toolkit.terminal.gwt.client.ui.ISelect;
+import com.itmill.toolkit.terminal.gwt.client.ui.ISlider;
 import com.itmill.toolkit.terminal.gwt.client.ui.ITablePaging;
 import com.itmill.toolkit.terminal.gwt.client.ui.ITabsheet;
 import com.itmill.toolkit.terminal.gwt.client.ui.ITextArea;
@@ -39,52 +40,52 @@ public class DefaultWidgetFactory implements WidgetFactory {
                                return new ICheckBox();
                        return new IButton();
                }
-               if ("window".equals(tag))
+               else if ("window".equals(tag))
                        return new IWindow();
-               if ("orderedlayout".equals(tag)) {
+               else if ("orderedlayout".equals(tag)) {
                        if ("horizontal".equals(uidl.getStringAttribute("orientation")))
                                return new IHorizontalLayout();
                        else
                                return new IVerticalLayout();
                }
-               if ("label".equals(tag))
+               else if ("label".equals(tag))
                        return new ILabel();
-               if ("gridlayout".equals(tag))
+               else if ("gridlayout".equals(tag))
                        return new IGridLayout();
-               if ("tree".equals(tag))
+               else if ("tree".equals(tag))
                        return new ITree();
-               if ("select".equals(tag)) {
+               else if ("select".equals(tag)) {
                        if("optiongroup".equals(uidl.getStringAttribute("style")))
                                return new IOptionGroup();
                        else if("twincol".equals(uidl.getStringAttribute("style")))
                                return new ITwinColSelect();
                        return new ISelect();
                }
-               if ("panel".equals(tag))
+               else if ("panel".equals(tag))
                        return new IPanel();
-               if ("component".equals(tag))
+               else if ("component".equals(tag))
                        return new IComponent();
-               if ("tabsheet".equals(tag))
+               else if ("tabsheet".equals(tag))
                        return new ITabsheet();
-               if ("embedded".equals(tag))
+               else if ("embedded".equals(tag))
                        return new IEmbedded();
-               if ("customlayout".equals(tag))
+               else if ("customlayout".equals(tag))
                        return new ICustomLayout();
-               if ("textfield".equals(tag)) {
+               else if ("textfield".equals(tag)) {
                        if(uidl.hasAttribute("multiline"))
                                return new ITextArea();
                        else if(uidl.getBooleanAttribute("secret"))
                                return new IPasswordField();
                        return new ITextField();
                }
-               if ("table".equals(tag)) {
+               else if ("table".equals(tag)) {
                        if(uidl.hasAttribute("style")) {
                                if("paging".equals(uidl.getStringAttribute("style")))
                                                return new ITablePaging();
                        }
                        return new IScrollTable();
                }
-               if("datefield".equals(tag)) {
+               else if("datefield".equals(tag)) {
                        if(uidl.hasAttribute("style"))
                                if("calendar".equals(uidl.getStringAttribute("style")))
                                        return new ICalendar();
@@ -92,6 +93,8 @@ public class DefaultWidgetFactory implements WidgetFactory {
                                        return new ITextualDate();
                        return new IPopupCalendar();
                }
+               else if("slider".equals(tag))
+                       return new ISlider();
 
                return new IUnknownComponent();
        }
index ed8ca237a024e479bdc9058994c997d85a35d352..910deb0b57b3e74c44cbd5241111a8037f2883a0 100644 (file)
@@ -77,6 +77,14 @@ public class UIDL {
                return s;
        }
 
+       public HashSet getStringArrayAttributeAsSet(String string) {
+               JSONArray a = getArrayVariable(string);
+               HashSet s = new HashSet();
+               for (int i = 0; i < a.size(); i++)
+                       s.add(((JSONString) a.get(i)).stringValue());
+               return s;
+       }
+
        /**
         * Get attributes value as string whateever the type is
         * 
@@ -296,6 +304,20 @@ public class UIDL {
                return (int) t.getValue();
        }
 
+       public long getLongVariable(String name) {
+               JSONNumber t = (JSONNumber) getVariableHash().get(name);
+               if (t == null)
+                       throw new IllegalArgumentException("No such variable: " + name);
+               return (long) t.getValue();
+       }
+       
+       public float getFloatVariable(String name) {
+               JSONNumber t = (JSONNumber) getVariableHash().get(name);
+               if (t == null)
+                       throw new IllegalArgumentException("No such variable: " + name);
+               return (float) t.getValue();
+       }
+
        public boolean getBooleanVariable(String name) {
                JSONBoolean t = (JSONBoolean) getVariableHash().get(name);
                if (t == null)
index 32275b2d4f0f62e0fe4b4051ba60b4c1a0dbb6aa..866c3a5c72503d21c3d30dd90e94c0d2c5fd4ce2 100644 (file)
@@ -1,7 +1,13 @@
 package com.itmill.toolkit.terminal.gwt.client.ui;\r
 \r
+import java.util.HashSet;\r
+\r
 import com.google.gwt.user.client.DOM;\r
 import com.google.gwt.user.client.Element;\r
+import com.google.gwt.user.client.Event;\r
+import com.google.gwt.user.client.Timer;\r
+import com.google.gwt.user.client.ui.MouseListener;\r
+import com.google.gwt.user.client.ui.SourcesMouseEvents;\r
 import com.google.gwt.user.client.ui.Widget;\r
 import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection;\r
 import com.itmill.toolkit.terminal.gwt.client.Paintable;\r
@@ -9,26 +15,204 @@ import com.itmill.toolkit.terminal.gwt.client.UIDL;
 \r
 public class ISlider extends Widget implements Paintable {\r
        \r
+       public static final String CLASSNAME = "i-slider";\r
+       \r
+       ApplicationConnection client;\r
+       \r
+       String id;\r
+       \r
+       private boolean immediate;\r
+       private boolean disabled;\r
+       private boolean readonly;\r
+       \r
+       private int handleSize;\r
+       private float min;\r
+       private float max;\r
+       private int resolution;\r
+       private Object value;\r
+       private HashSet values;\r
+       private boolean vertical;\r
+       private int size = -1;\r
+       \r
        /* DOM element for slider's base */\r
        private Element base;\r
        \r
        /* DOM element for slider's handle */\r
        private Element handle;\r
        \r
+       private boolean dragging;\r
+       \r
        public ISlider() {\r
                super();\r
+               setElement(DOM.createElement("div"));\r
                base = DOM.createElement("div");\r
+               DOM.appendChild(getElement(), base);\r
                handle = DOM.createElement("div");\r
                DOM.appendChild(base, handle);\r
-               setElement(base);\r
+               setStyleName(CLASSNAME);\r
+               DOM.setAttribute(base, "className", CLASSNAME+"-base");\r
+               DOM.setAttribute(handle, "className", CLASSNAME+"-handle");\r
+               \r
+               DOM.sinkEvents(base, Event.MOUSEEVENTS);\r
+               DOM.sinkEvents(handle, Event.MOUSEEVENTS);\r
        }\r
 \r
        public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
                \r
+               this.client = client;\r
+               \r
                // Ensure correct implementation (handle own caption)\r
                if (client.updateComponent(this, uidl, false))\r
                        return;\r
                \r
+               immediate = uidl.getBooleanAttribute("immediate");\r
+               disabled = uidl.getBooleanAttribute("disabled");\r
+               readonly = uidl.getBooleanAttribute("readonly");\r
+               \r
+               vertical = uidl.hasAttribute("vertical");\r
+               \r
+               if(vertical)\r
+                       addStyleName(CLASSNAME+"-vertical");\r
+               else\r
+                       removeStyleName(CLASSNAME+"-vertical");\r
+               \r
+               if(uidl.hasAttribute("values")) {\r
+                       values = uidl.getStringArrayAttributeAsSet("values");\r
+                       value = uidl.getStringVariable("value");\r
+               } else {\r
+                       min = uidl.getLongAttribute("min");\r
+                       max = uidl.getLongAttribute("max");\r
+                       resolution = uidl.getIntAttribute("resolution");\r
+                       value = new Float(uidl.getFloatVariable("value"));\r
+                       values = null;\r
+               }\r
+               \r
+               handleSize = uidl.getIntAttribute("hsize");\r
+               \r
+               if(uidl.hasAttribute("size"))\r
+                       size = uidl.getIntAttribute("size");\r
+               \r
+               buildBase();\r
+               \r
+               if(!vertical) {\r
+                       // Draw handle with a delay to allow base to gain maximum width\r
+                       Timer delay = new Timer() {\r
+                               public void run() {\r
+                                       buildHandle();\r
+                                       setHandlePosition(value);\r
+                               }\r
+                       };\r
+                       delay.schedule(100);\r
+               } else {\r
+                       buildHandle();\r
+                       setHandlePosition(value);\r
+               }\r
+       }\r
+\r
+       private void buildBase() {\r
+               if(vertical) {\r
+                       if(size > -1)\r
+                               DOM.setStyleAttribute(base, "height", size + "px");\r
+                       else DOM.setStyleAttribute(base, "height", "120px");\r
+               } else {\r
+                       if(size > -1)\r
+                               DOM.setStyleAttribute(base, "width", size + "px");\r
+                       else DOM.setStyleAttribute(base, "width", "100%");\r
+               }\r
+               // Allow absolute positioning of handle\r
+               DOM.setStyleAttribute(base, "position", "relative");\r
+               \r
+               // TODO attach listeners for clicking on base, focusing and arrow keys\r
+       }\r
+       \r
+       private void buildHandle() {\r
+               // Allow absolute positioning\r
+               DOM.setStyleAttribute(handle, "position", "absolute");\r
+               \r
+               if(vertical) {\r
+                       // TODO\r
+               } else {\r
+                       int t = Integer.parseInt(DOM.getAttribute(base, "offsetHeight")) - Integer.parseInt(DOM.getAttribute(handle, "offsetHeight"));\r
+                       DOM.setStyleAttribute(handle, "top", (t/2)+"px");\r
+                       DOM.setStyleAttribute(handle, "left", "0px");\r
+                       int w = (int) (Float.parseFloat(DOM.getAttribute(base, "offsetWidth")) / 100 * handleSize);\r
+                       DOM.setStyleAttribute(handle, "width", w+"px");\r
+               }\r
+               \r
+       }\r
+       \r
+       private void setHandlePosition(Object value) {\r
+               if(vertical) {\r
+                       // TODO\r
+               } else {\r
+                       if(values == null) {\r
+                               int handleWidth = Integer.parseInt(DOM.getAttribute(handle, "offsetWidth"));\r
+                               int baseWidth = Integer.parseInt(DOM.getAttribute(base, "offsetWidth"));\r
+                               int range = baseWidth - handleWidth;\r
+                               float v = ((Float)value).floatValue();\r
+                               float valueRange = max - min;\r
+                               float pos = range * ((v - min) / valueRange);\r
+                               DOM.setStyleAttribute(handle, "left", pos+"px");\r
+                               DOM.setAttribute(handle, "title", ""+v);\r
+                       }\r
+               }\r
+               this.value = value;\r
+       }\r
+\r
+       public void onBrowserEvent(Event event) {\r
+               if(DOM.compare(DOM.eventGetTarget(event), handle))\r
+                       processHandleEvent(event);\r
+               else\r
+                       processBaseEvent(event);\r
+               \r
+               super.onBrowserEvent(event);\r
+       }\r
+       \r
+       private void processHandleEvent(Event event) {\r
+               switch (DOM.eventGetType(event)) {\r
+               case Event.ONMOUSEDOWN:\r
+                       client.console.log("Slider handle: mousedown");\r
+                       if(!disabled && !readonly) {\r
+                               dragging = true;\r
+                               DOM.setCapture(handle);\r
+                               DOM.eventPreventDefault(event); // prevent selecting text\r
+                       }\r
+                       break;\r
+               case Event.ONMOUSEMOVE:\r
+                       if (dragging) {\r
+                               client.console.log("Slider handle: dragging...");\r
+                               int x = DOM.eventGetClientX(event);\r
+                               int y = DOM.eventGetClientY(event);\r
+                               if(vertical) {\r
+                                       // TODO\r
+                               } else {\r
+                                       if(values == null) {\r
+                                               float handleW = Integer.parseInt(DOM.getAttribute(handle, "offsetWidth"));\r
+                                               float baseX = DOM.getAbsoluteLeft(base);\r
+                                               float baseW = Integer.parseInt(DOM.getAttribute(base, "offsetWidth"));\r
+                                               float v = ((x-baseX)/(baseW-baseX)) * (max-min) + min;\r
+                                               if(resolution > 0) {\r
+                                                       setHandlePosition(new Float(v));\r
+                                               } else\r
+                                                       setHandlePosition(new Float((int)v));\r
+                                       } else {\r
+                                               // TODO\r
+                                       }\r
+                               }\r
+                       }\r
+                       break;\r
+               case Event.ONMOUSEUP:\r
+                       dragging = false;\r
+                       DOM.releaseCapture(handle);\r
+                       break;\r
+               default:\r
+                       break;\r
+               }\r
+       }\r
+               \r
+       private void processBaseEvent(Event event) {\r
+               // TODO\r
+               super.onBrowserEvent(event);\r
        }\r
 \r
 }\r
index cad477b824824986259ce93b149995360aeb0cef..04bf7396d2788a0b2e3b4fb0c3acac84b6438153 100644 (file)
@@ -4,4 +4,5 @@
 @import "panel/css/panel.css";\r
 @import "tabsheet/css/tabsheet.css";\r
 @import "datefield/css/datefield.css";\r
-@import "table/css/table.css";
\ No newline at end of file
+@import "table/css/table.css";\r
+@import "slider/css/slider.css";
\ No newline at end of file
diff --git a/src/com/itmill/toolkit/terminal/gwt/public/component-themes/slider/css/slider.css b/src/com/itmill/toolkit/terminal/gwt/public/component-themes/slider/css/slider.css
new file mode 100644 (file)
index 0000000..73a4bcb
--- /dev/null
@@ -0,0 +1,11 @@
+.i-slider {\r
+\r
+}\r
+\r
+.i-slider-base {\r
+       background: #eee;\r
+}\r
+\r
+.i-slider-handle {\r
+       background: #ccc;\r
+}
\ No newline at end of file
index 8095141895e4604e49040b4707fc926cc9b9a36c..90d74184cf00091124be467bb464482cfca38e04 100644 (file)
 
 package com.itmill.toolkit.terminal.gwt.server;
 
+import java.io.PrintWriter;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.Stack;
+import java.util.Vector;
+
 import com.itmill.toolkit.Application;
 import com.itmill.toolkit.terminal.ApplicationResource;
 import com.itmill.toolkit.terminal.ExternalResource;
@@ -36,22 +43,8 @@ import com.itmill.toolkit.terminal.PaintTarget;
 import com.itmill.toolkit.terminal.Paintable;
 import com.itmill.toolkit.terminal.Resource;
 import com.itmill.toolkit.terminal.ThemeResource;
-import com.itmill.toolkit.terminal.UploadStream;
 import com.itmill.toolkit.terminal.VariableOwner;
 
-import java.io.BufferedWriter;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.io.UnsupportedEncodingException;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.Set;
-import java.util.Stack;
-import java.util.Vector;
-
 /**
  * User Interface Description Language Target.
  * 
@@ -423,6 +416,22 @@ public class JsonPaintTarget implements PaintTarget {
        public void addAttribute(String name, long value) throws PaintException {
                tag.addAttribute("\"" + name + "\":" + String.valueOf(value));
        }
+       
+       /**
+        * Adds a float attribute to component. Atributes must be added before any
+        * content is written.
+        * 
+        * @param name
+        *            the Attribute name.
+        * @param value
+        *            the Attribute value.
+        * 
+        * @throws PaintException
+        *             if the paint operation failed.
+        */
+       public void addAttribute(String name, float value) throws PaintException {
+               tag.addAttribute("\"" + name + "\":" + String.valueOf(value));
+       }
 
        /**
         * Adds a string attribute to component. Atributes must be added before any
@@ -505,6 +514,40 @@ public class JsonPaintTarget implements PaintTarget {
                        throws PaintException {
                tag.addVariable(new IntVariable(owner, name, value));
        }
+       
+       /**
+        * Adds a long type variable.
+        * 
+        * @param owner
+        *            the Listener for variable changes.
+        * @param name
+        *            the Variable name.
+        * @param value
+        *            the Variable initial value.
+        * 
+        * @throws PaintException
+        *             if the paint operation failed.
+        */
+       public void addVariable(VariableOwner owner, String name, long value) throws PaintException {
+               tag.addVariable(new LongVariable(owner, name, value));
+       }
+       
+       /**
+        * Adds a float type variable.
+        * 
+        * @param owner
+        *            the Listener for variable changes.
+        * @param name
+        *            the Variable name.
+        * @param value
+        *            the Variable initial value.
+        * 
+        * @throws PaintException
+        *             if the paint operation failed.
+        */
+       public void addVariable(VariableOwner owner, String name, float value) throws PaintException {
+               tag.addVariable(new FloatVariable(owner, name, value));
+       }
 
        /**
         * Adds a boolean type variable.
@@ -928,6 +971,32 @@ public class JsonPaintTarget implements PaintTarget {
                        return "\"" + name + "\":" + value;
                }
        }
+       
+       class LongVariable extends Variable {
+               long value;
+
+               public LongVariable(VariableOwner owner, String name, long v) {
+                       value = v;
+                       this.name = name;
+               }
+
+               public String getJsonPresentation() {
+                       return "\"" + name + "\":" + value;
+               }
+       }
+       
+       class FloatVariable extends Variable {
+               float value;
+
+               public FloatVariable(VariableOwner owner, String name, float v) {
+                       value = v;
+                       this.name = name;
+               }
+
+               public String getJsonPresentation() {
+                       return "\"" + name + "\":" + value;
+               }
+       }
 
        class ArrayVariable extends Variable {
                String[] value;
index 8f4350193bfaa252f8059518f2fe30c6c6e4dd4c..2d7e253821efbf9f0f422b0fb1138febbfa87039 100644 (file)
@@ -1,74 +1,95 @@
 package com.itmill.toolkit.ui;\r
 \r
-import java.io.IOException;\r
-import java.lang.reflect.Method;\r
-import java.util.Iterator;\r
-import java.util.LinkedHashSet;\r
-import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
-import java.util.StringTokenizer;\r
 \r
-import com.itmill.toolkit.event.Action;\r
-import com.itmill.toolkit.event.ShortcutAction;\r
 import com.itmill.toolkit.terminal.PaintException;\r
 import com.itmill.toolkit.terminal.PaintTarget;\r
-import com.itmill.toolkit.ui.Button.ClickEvent;\r
 \r
-public class Slider extends AbstractComponent {\r
+public class Slider extends AbstractField {\r
        \r
        public static final int ORIENTATION_HORIZONTAL = 0;\r
        public static final int ORIENTATION_VERTICAL = 1;\r
        \r
-       /* Minimum value of slider */\r
-       private int min = 0;\r
-       /* Maximum value of slider */\r
-       private int max = 100;\r
+       /** Minimum value of slider */\r
+       private float min = 0;\r
+       /** Maximum value of slider */\r
+       private float max = 100;\r
        \r
-       /* Resolution, how many digits are considered relevant after desimal point */\r
-       private int resolution = 2;\r
-       \r
-       /* Current value */\r
-       private Object value;\r
+       /**\r
+        * Resolution, how many digits are considered relevant after desimal point.\r
+        * Must be a non-negative value \r
+        */\r
+       private int resolution = 0;\r
        \r
-       /* Object values for slider in stead of numeric.\r
+       /** \r
+        * Object values for slider in stead of numeric (usually strings).\r
         * If this is set, min, max and resolution values are ignored.\r
         */\r
-       private Object[] values;\r
+       private Set values;\r
        \r
+       /**\r
+        * Slider orientation (horizontal==default/vertical).\r
+        */\r
        private int orientation = ORIENTATION_HORIZONTAL;\r
        \r
-       private List listeners;\r
+       /**\r
+        * Slider size in pixels.\r
+        * In horizontal mode if set to -1, allow 100% with container.\r
+        * In vertical mode if set to -1, default height 120 pixels.\r
+        */\r
+       private int size = -1;\r
        \r
-       private int width;\r
-       private int height;\r
+       /**\r
+        * Handle size in percents related to base size.\r
+        * Must be a value between 1-100.\r
+        */\r
+       private int handleSize = 20;\r
        \r
-       public Object getValue() {\r
-               return value;\r
-       }\r
        \r
-       public int getHeight() {\r
-               return height;\r
-       }\r
-\r
-       public void setHeight(int height) {\r
-               this.height = height;\r
+       public Slider() {\r
+               super();\r
+               super.setValue(new Float(min));\r
        }\r
 \r
-       public int getMax() {\r
+       public float getMax() {\r
                return max;\r
        }\r
 \r
-       public void setMax(int max) {\r
+       /**\r
+        * Set the maximum value of the Slider. As a side-effect nullifies the "values" Set.\r
+        * @param max\r
+        */\r
+       public void setMax(float max) {\r
                this.max = max;\r
+               this.values = null;\r
+               try {\r
+                       if((new Float(getValue().toString())).floatValue() > max)\r
+                               super.setValue(new Float(min));\r
+               } catch(ClassCastException e) {\r
+                       super.setValue(new Float(max));\r
+               }\r
+               requestRepaint();\r
        }\r
 \r
-       public int getMin() {\r
+       public float getMin() {\r
                return min;\r
        }\r
-\r
-       public void setMin(int min) {\r
+       \r
+       /**\r
+        * Set the minimum value of the Slider. As a side-effect nullifies the "values" Set.\r
+        * @param max\r
+        */\r
+       public void setMin(float min) {\r
                this.min = min;\r
+               this.values = null;\r
+               try {\r
+                       if((new Float(getValue().toString())).floatValue() < min)\r
+                               super.setValue(new Float(min));\r
+               } catch(ClassCastException e) {\r
+                       super.setValue(new Float(min));\r
+               }\r
+               requestRepaint();\r
        }\r
 \r
        public int getOrientation() {\r
@@ -77,6 +98,7 @@ public class Slider extends AbstractComponent {
 \r
        public void setOrientation(int orientation) {\r
                this.orientation = orientation;\r
+               requestRepaint();\r
        }\r
 \r
        public int getResolution() {\r
@@ -84,48 +106,107 @@ public class Slider extends AbstractComponent {
        }\r
 \r
        public void setResolution(int resolution) {\r
+               if(resolution < 0)\r
+                       return;\r
                this.resolution = resolution;\r
+               requestRepaint();\r
        }\r
 \r
-       public Object[] getValues() {\r
+       public Set getValues() {\r
                return values;\r
        }\r
 \r
-       public void setValues(Object[] values) {\r
+       public void setValues(Set values) {\r
                this.values = values;\r
+               requestRepaint();\r
        }\r
 \r
-       public int getWidth() {\r
-               return width;\r
+       public void setValue(Float value, boolean repaintIsNotNeeded) throws ValueOutOfBoundsException {\r
+               float v = new Float(value.toString()).floatValue();\r
+               Object newValue;\r
+               if(resolution>0) {\r
+                       // Round up to resolution\r
+                       newValue = new Float(v * (resolution*10) / (resolution*10));\r
+                       if(min > ((Float)newValue).floatValue() || max < ((Float)newValue).floatValue())\r
+                               throw new ValueOutOfBoundsException(value);\r
+               } else {\r
+                       newValue = new Float((int) v);\r
+                       if(min > ((Float)newValue).intValue() || max < ((Float)newValue).intValue())\r
+                               throw new ValueOutOfBoundsException(value);\r
+               }\r
+               super.setValue(newValue, repaintIsNotNeeded);\r
+       }\r
+       \r
+       public void setValue(Float value)throws ValueOutOfBoundsException {\r
+               setValue(value, false);\r
+       }\r
+       \r
+       public void setValue(String value, boolean repaintIsNotNeeded) throws ValueOutOfBoundsException {\r
+               if(this.values != null) {\r
+                       String v = new String(value.toString());\r
+                       if(this.values.contains(v))\r
+                               super.setValue(v, repaintIsNotNeeded);\r
+                       else throw new ValueOutOfBoundsException(value);\r
+               } else {\r
+                       // TODO\r
+               }\r
+       }\r
+       \r
+       public void setValue(String value) throws ValueOutOfBoundsException {\r
+               setValue(value, false);\r
        }\r
 \r
-       public void setWidth(int width) {\r
-               this.width = width;\r
+       public int getSize() {\r
+               return size;\r
        }\r
 \r
-       public List getListeners() {\r
-               return listeners;\r
+       public void setSize(int size) {\r
+               this.size = size;\r
+               requestRepaint();\r
        }\r
-       \r
-       public void addListener(SlideListener l) {\r
-               addListener(SlideEvent.class, l, SLIDER_SLIDE_METHOD);\r
+\r
+       public int getHandleSize() {\r
+               return handleSize;\r
        }\r
-       \r
-       public void removeListener(SlideListener l) {\r
-               removeListener(SlideEvent.class, l, SLIDER_SLIDE_METHOD);\r
+\r
+       public void setHandleSize(int handleSize) {\r
+               if(handleSize > 100 || handleSize < 1)\r
+                       return;\r
+               this.handleSize = handleSize;\r
+               requestRepaint();\r
        }\r
 \r
        public String getTag() {\r
                return "slider";\r
        }\r
        \r
-       public interface SlideListener {\r
-               public void slide(SlideEvent s);\r
-       }\r
-       \r
        public void paintContent(PaintTarget target) throws PaintException {\r
                super.paintContent(target);\r
-               // TODO\r
+\r
+               if(values == null) {\r
+                       \r
+                       target.addAttribute("min", (long) min);\r
+                       target.addAttribute("max", (long) max);\r
+                       target.addAttribute("resolution", resolution);\r
+                       \r
+                       if(resolution > 0)\r
+                               target.addVariable(this, "value", ((Float)getValue()).floatValue());\r
+                       else\r
+                               target.addVariable(this, "value", ((Float)getValue()).intValue());\r
+               \r
+               } else {\r
+                       target.addVariable(this, "value", getValue().toString());\r
+                       target.addAttribute("values", values.toArray(new String[values.size()]));\r
+               }\r
+               \r
+               if(orientation == ORIENTATION_VERTICAL)\r
+                       target.addAttribute("vertical", true);\r
+               \r
+               if(size > -1)\r
+                       target.addAttribute("size", size);\r
+               \r
+               target.addAttribute("hsize", handleSize);\r
+               \r
        }\r
 \r
        /**\r
@@ -137,48 +218,50 @@ public class Slider extends AbstractComponent {
         */\r
        public void changeVariables(Object source, Map variables) {\r
                if (variables.containsKey("value")) {\r
-                       // TODO update value\r
-                       fireSlide();\r
+                       Object newValue = variables.get("value");\r
+                       if(values == null) {\r
+                               if(resolution >0)\r
+                                       newValue = new Long(newValue.toString());\r
+                               else \r
+                                       newValue = new Integer(newValue.toString());\r
+                               if(newValue != null && newValue != getValue() && !newValue.equals(getValue())) {\r
+                                       setValue(newValue);\r
+                               }\r
+                       } else {\r
+                               // TODO\r
+                       }\r
                }\r
        }\r
        \r
-       \r
-       /* **************************************************\r
-        * Event handling classes and methods\r
-        */\r
-       \r
-       public class SlideEvent extends Component.Event {\r
-\r
-               public SlideEvent(Component source) {\r
-                       super(source);\r
-               }\r
-               \r
-               public Slider getSlider() {\r
-                       return (Slider) getSource();\r
-               }\r
+       public class ValueOutOfBoundsException extends Exception {\r
 \r
                /**\r
                 * Serial generated by Eclipse.\r
                 */\r
-               private static final long serialVersionUID = -2092497444591455077L;\r
+               private static final long serialVersionUID = -6451298598644446340L;\r
+               \r
+               private Object value;\r
+               \r
+               /**\r
+                * Constructs an <code>ValueOutOfBoundsException</code> with the specified\r
+                * detail message.\r
+                * \r
+                * @param valueOutOfBounds\r
+                */\r
+               public ValueOutOfBoundsException(Object valueOutOfBounds) {\r
+                       this.value = valueOutOfBounds;\r
+               }\r
+               \r
+               public Object getValue() {\r
+                       return this.value;\r
+               }\r
                \r
        }\r
-       \r
-       protected void fireSlide() {\r
-               fireEvent(new Slider.SlideEvent(this));\r
-       }\r
-       \r
-       /* Slide event ************************************************ */\r
 \r
-       private static final Method SLIDER_SLIDE_METHOD;\r
-       static {\r
-               try {\r
-                       SLIDER_SLIDE_METHOD = SlideListener.class.getDeclaredMethod(\r
-                                       "slide", new Class[] { ClickEvent.class });\r
-               } catch (java.lang.NoSuchMethodException e) {\r
-                       // This should never happen\r
-                       throw new java.lang.RuntimeException();\r
-               }\r
+       public Class getType() {\r
+               if(values == null)\r
+                       return Float.class;\r
+               return String.class;\r
        }\r
 \r
 }\r