IDateField now supports null value.
svn changeset:1906/svn branch:trunk
}\r
\r
private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) {\r
+ // Can't draw a calendar without a date :)\r
+ if(datefield.date == null)\r
+ datefield.date = new Date();\r
+ \r
if(forceRedraw) {\r
if(prevMonth == null) { // Only do once\r
prevYear = new IEventButton(); prevYear.setHTML("«");\r
\r
private void buildCalendarBody() {\r
Date date = datefield.date;\r
+ if(date == null)\r
+ date = new Date();\r
int startWeekDay = datefield.dts.getStartWeekDay(date);\r
int numDays = DateTimeService.getNumberOfDaysInMonth(date);\r
int dayCount = 0;\r
public void updateCalendar() {\r
// Locale and resolution changes force a complete redraw\r
buildCalendar(locale != datefield.currentLocale || resolution != datefield.currentResolution);\r
+ if(datefield instanceof ITextualDate)\r
+ ((ITextualDate) datefield).buildDate();\r
locale = datefield.currentLocale;\r
resolution = datefield.currentResolution;\r
}\r
cal.datefield.date.setDate(day.intValue());\r
cal.datefield.client.updateVariable(cal.datefield.id, "day", cal.datefield.date.getDate(), cal.datefield.immediate);\r
\r
- // No need to update calendar header\r
- cal.clearCalendarBody(false);\r
- cal.buildCalendarBody();\r
+ updateCalendar();\r
}\r
\r
}\r
\r
protected boolean enabled;\r
\r
- protected Date date;\r
- \r
- /* For easy access, because java.util.Date doesn't have getMilliseconds method */\r
- private int milliseconds = 0;\r
+ protected Date date = null;\r
\r
protected DateTimeService dts;\r
\r
public IDateField() {\r
setStyleName(CLASSNAME);\r
- date = new Date();\r
dts = new DateTimeService();\r
}\r
\r
int sec = (currentResolution >= RESOLUTION_SEC)? uidl.getIntVariable("sec") : -1;\r
int msec = (currentResolution >= RESOLUTION_MSEC)? uidl.getIntVariable("msec") : -1;\r
\r
- // Construct new date for this datefield\r
- date = new Date((long) buildTime(year, month, day, hour, min, sec, msec));\r
- milliseconds = msec<0? 0 : msec;\r
+ // Construct new date for this datefield (only if not null)\r
+ if(year > -1)\r
+ date = new Date((long) getTime(year, month, day, hour, min, sec, msec));\r
\r
}\r
\r
* We need this redundant native function because \r
* Java's Date object doesn't have a setMilliseconds method.\r
*/\r
- private static native double buildTime(int y, int m, int d, int h, int mi, int s, int ms) /*-{\r
+ private static native double getTime(int y, int m, int d, int h, int mi, int s, int ms) /*-{\r
try {\r
var date = new Date();\r
if(y && y >= 0) date.setFullYear(y);\r
}-*/;\r
\r
public int getMilliseconds() {\r
- return milliseconds;\r
+ return (int) (date.getTime() - date.getTime() / 1000 * 1000);\r
}\r
\r
public void setMilliseconds(int ms) {\r
- long time = (long) buildTime(date.getYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), ms);\r
- date = new Date(time);\r
- milliseconds = ms;\r
+ date.setTime(date.getTime() / 1000 * 1000 + ms);\r
}\r
\r
}\r
\r
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
super.updateFromUIDL(uidl, client);\r
- calendar.updateCalendar();\r
+ if(date != null)\r
+ calendar.updateCalendar();\r
calendarToggle.setEnabled(enabled);\r
}\r
\r
\r
public void onPopupClosed(PopupPanel sender, boolean autoClosed) {\r
if(sender == popup)\r
- buildTime();\r
+ buildDate();\r
}\r
\r
}\r
--- /dev/null
+package com.itmill.toolkit.terminal.gwt.client.ui;\r
+\r
+import com.google.gwt.user.client.DOM;\r
+import com.google.gwt.user.client.Element;\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
+import com.itmill.toolkit.terminal.gwt.client.UIDL;\r
+\r
+public class ISlider extends Widget implements Paintable {\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
+ public ISlider() {\r
+ super();\r
+ base = DOM.createElement("div");\r
+ handle = DOM.createElement("div");\r
+ DOM.appendChild(base, handle);\r
+ setElement(base);\r
+ }\r
+\r
+ public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
+ \r
+ // Ensure correct implementation (handle own caption)\r
+ if (client.updateComponent(this, uidl, false))\r
+ return;\r
+ \r
+ }\r
+\r
+}\r
\r
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) {\r
super.updateFromUIDL(uidl, client);\r
- buildTime();\r
+ buildDate();\r
}\r
\r
- protected void buildTime() {\r
+ protected void buildDate() {\r
dl = new DateLocale();\r
DateLocale.setLocale(currentLocale);\r
\r
format = new SimpleDateFormat(verifyFormat(dts.getDateFormat()));\r
format.setLocale(dl);\r
\r
- String dateText = format.format(date);\r
+ String dateText = "";\r
+ if(date != null) {\r
+ dateText = format.format(date);\r
\r
- if(currentResolution >= IDateField.RESOLUTION_HOUR) {\r
- DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL;\r
- int h = date.getHours();\r
- if(h > 11 && dts.isTwelveHourClock())\r
- h -= 12;\r
- int m = currentResolution > IDateField.RESOLUTION_HOUR? date.getMinutes() : 0;\r
- dateText += " " + (h<10?"0"+h:""+h) + dts.getClockDelimeter() + (m<10?"0"+m:""+m);\r
- }\r
- if(currentResolution >= IDateField.RESOLUTION_SEC) {\r
- int s = date.getSeconds();\r
- dateText += dts.getClockDelimeter() + (s<10?"0"+s:""+s);\r
- }\r
- if(currentResolution == IDateField.RESOLUTION_MSEC) {\r
- int ms = getMilliseconds();\r
- String text = ""+ms;\r
- if(ms<10) text = "00"+text;\r
- else if(ms<100) text = "0"+text;\r
- dateText += "." + text;\r
+ if(currentResolution >= IDateField.RESOLUTION_HOUR) {\r
+ DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL;\r
+ int h = date.getHours();\r
+ if(h > 11 && dts.isTwelveHourClock())\r
+ h -= 12;\r
+ int m = currentResolution > IDateField.RESOLUTION_HOUR? date.getMinutes() : 0;\r
+ dateText += " " + (h<10?"0"+h:""+h) + dts.getClockDelimeter() + (m<10?"0"+m:""+m);\r
+ }\r
+ if(currentResolution >= IDateField.RESOLUTION_SEC) {\r
+ int s = date.getSeconds();\r
+ dateText += dts.getClockDelimeter() + (s<10?"0"+s:""+s);\r
+ }\r
+ if(currentResolution == IDateField.RESOLUTION_MSEC) {\r
+ int ms = getMilliseconds();\r
+ String text = ""+ms;\r
+ if(ms<10) text = "00"+text;\r
+ else if(ms<100) text = "0"+text;\r
+ dateText += "." + text;\r
+ }\r
+ if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock())\r
+ dateText += " " + (date.getHours()<12? dts.getAmPmStrings()[0] : dts.getAmPmStrings()[1]);\r
}\r
- if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock())\r
- dateText += " " + (date.getHours()<12? dts.getAmPmStrings()[0] : dts.getAmPmStrings()[1]);\r
\r
text.setText(dateText);\r
text.setEnabled(enabled&&!readonly);\r
\r
public void onChange(Widget sender) {\r
if(sender == text) {\r
- DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL;\r
- if(currentResolution == IDateField.RESOLUTION_YEAR)\r
- DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_YEAR;\r
- else if(currentResolution == IDateField.RESOLUTION_MONTH)\r
- DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_MONTH;\r
- else if(currentResolution == IDateField.RESOLUTION_DAY)\r
- DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_DAY;\r
- \r
- String f = verifyFormat(dts.getDateFormat());\r
+ if(!text.getText().equals("")) {\r
+ DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL;\r
+ if(currentResolution == IDateField.RESOLUTION_YEAR)\r
+ DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_YEAR;\r
+ else if(currentResolution == IDateField.RESOLUTION_MONTH)\r
+ DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_MONTH;\r
+ else if(currentResolution == IDateField.RESOLUTION_DAY)\r
+ DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_DAY;\r
+ \r
+ String f = verifyFormat(dts.getDateFormat());\r
+ \r
+ if(currentResolution >= IDateField.RESOLUTION_HOUR)\r
+ f += " " + (dts.isTwelveHourClock()?\r
+ DateLocale.TOKEN_HOUR_12 + DateLocale.TOKEN_HOUR_12\r
+ : DateLocale.TOKEN_HOUR_24 + DateLocale.TOKEN_HOUR_24)\r
+ + dts.getClockDelimeter() + DateLocale.TOKEN_MINUTE + DateLocale.TOKEN_MINUTE;\r
+ if(currentResolution >= IDateField.RESOLUTION_SEC)\r
+ f += dts.getClockDelimeter() + DateLocale.TOKEN_SECOND + DateLocale.TOKEN_SECOND;\r
+ if(currentResolution == IDateField.RESOLUTION_MSEC)\r
+ f += "." + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND;\r
+ if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock())\r
+ f += " " + DateLocale.TOKEN_AM_PM;\r
+ \r
+ format = new SimpleDateFormat(f);\r
+ DateLocale.setLocale(currentLocale);\r
+ format.setLocale(dl);\r
+ \r
+ try {\r
+ date = format.parse(text.getText());\r
+ } catch (Exception e) {\r
+ client.console.log(e.getMessage());\r
+ text.addStyleName(ITextField.CLASSNAME+"-error");\r
+ Timer t = new Timer() {\r
+ public void run() {\r
+ text.removeStyleName(ITextField.CLASSNAME+"-error");\r
+ }\r
+ };\r
+ t.schedule(2000);\r
+ return;\r
+ }\r
\r
- if(currentResolution >= IDateField.RESOLUTION_HOUR)\r
- f += " " + (dts.isTwelveHourClock()?\r
- DateLocale.TOKEN_HOUR_12 + DateLocale.TOKEN_HOUR_12\r
- : DateLocale.TOKEN_HOUR_24 + DateLocale.TOKEN_HOUR_24)\r
- + dts.getClockDelimeter() + DateLocale.TOKEN_MINUTE + DateLocale.TOKEN_MINUTE;\r
- if(currentResolution >= IDateField.RESOLUTION_SEC)\r
- f += dts.getClockDelimeter() + DateLocale.TOKEN_SECOND + DateLocale.TOKEN_SECOND;\r
- if(currentResolution == IDateField.RESOLUTION_MSEC)\r
- f += "." + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND;\r
- if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock())\r
- f += " " + DateLocale.TOKEN_AM_PM;\r
- \r
- format = new SimpleDateFormat(f);\r
- DateLocale.setLocale(currentLocale);\r
- format.setLocale(dl);\r
- \r
- try {\r
- date = format.parse(text.getText());\r
- } catch (Exception e) {\r
- // TODO redirect to console\r
- System.out.println(e);\r
- text.addStyleName(ITextField.CLASSNAME+"-error");\r
- Timer t = new Timer() {\r
- public void run() {\r
- text.removeStyleName(ITextField.CLASSNAME+"-error");\r
- }\r
- };\r
- t.schedule(2000);\r
- return;\r
- }\r
+ } else\r
+ date = null;\r
\r
// Update variables\r
// (only the smallest defining resolution needs to be immediate)\r
- client.updateVariable(id, "year", date.getYear()+1900, currentResolution==IDateField.RESOLUTION_YEAR);\r
+ client.updateVariable(id, "year", date!=null?date.getYear()+1900:-1, currentResolution==IDateField.RESOLUTION_YEAR);\r
if(currentResolution >= IDateField.RESOLUTION_MONTH)\r
- client.updateVariable(id, "month", date.getMonth()+1, currentResolution==IDateField.RESOLUTION_MONTH&&immediate);\r
+ client.updateVariable(id, "month", date!=null?date.getMonth()+1:-1, currentResolution==IDateField.RESOLUTION_MONTH&&immediate);\r
if(currentResolution >= IDateField.RESOLUTION_DAY)\r
- client.updateVariable(id, "day", date.getDate(), currentResolution==IDateField.RESOLUTION_DAY&&immediate);\r
+ client.updateVariable(id, "day", date!=null?date.getDate():-1, currentResolution==IDateField.RESOLUTION_DAY&&immediate);\r
if(currentResolution >= IDateField.RESOLUTION_HOUR)\r
- client.updateVariable(id, "hour", date.getHours(), currentResolution==IDateField.RESOLUTION_HOUR&&immediate);\r
+ client.updateVariable(id, "hour", date!=null?date.getHours():-1, currentResolution==IDateField.RESOLUTION_HOUR&&immediate);\r
if(currentResolution >= IDateField.RESOLUTION_MIN)\r
- client.updateVariable(id, "min", date.getMinutes(), currentResolution==IDateField.RESOLUTION_MIN&&immediate);\r
+ client.updateVariable(id, "min", date!=null?date.getMinutes():-1, currentResolution==IDateField.RESOLUTION_MIN&&immediate);\r
if(currentResolution >= IDateField.RESOLUTION_SEC)\r
- client.updateVariable(id, "sec", date.getSeconds(), currentResolution==IDateField.RESOLUTION_SEC&&immediate);\r
+ client.updateVariable(id, "sec", date!=null?date.getSeconds():-1, currentResolution==IDateField.RESOLUTION_SEC&&immediate);\r
if(currentResolution == IDateField.RESOLUTION_MSEC)\r
- client.updateVariable(id, "msec", getMilliseconds(), immediate);\r
+ client.updateVariable(id, "msec", date!=null?getMilliseconds():-1, immediate);\r
\r
- buildTime();\r
+ buildDate();\r
}\r
}\r
\r
boolean ro = datefield.readonly;\r
\r
if(ro) {\r
- int h = datefield.date.getHours();\r
+ int h = 0;\r
+ if(datefield.date != null)\r
+ h = datefield.date.getHours();\r
if(thc) h -= h<12? 0 : 12;\r
add(new ILabel(h<10? "0"+h : ""+h));\r
} else add(hours);\r
public void updateTime(boolean redraw) {\r
buildTime(redraw || resolution != datefield.currentResolution \r
|| readonly != datefield.readonly);\r
+ if(datefield instanceof ITextualDate)\r
+ ((ITextualDate) datefield).buildDate();\r
resolution = datefield.currentResolution;\r
readonly = datefield.readonly;\r
}\r
h = h + ampm.getSelectedIndex()*12;\r
datefield.date.setHours(h);\r
datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate);\r
- //updateTime(false);\r
+ updateTime(false);\r
}\r
else if(sender == mins) {\r
int m = mins.getSelectedIndex();\r
datefield.date.setMinutes(m);\r
datefield.client.updateVariable(datefield.id, "min", m, datefield.immediate);\r
- //updateTime(false);\r
+ updateTime(false);\r
}\r
else if(sender == sec) {\r
int s = sec.getSelectedIndex();\r
datefield.date.setSeconds(s);\r
datefield.client.updateVariable(datefield.id, "sec", s, datefield.immediate);\r
- //updateTime(false);\r
+ updateTime(false);\r
}\r
else if(sender == msec) {\r
int ms = msec.getSelectedIndex();\r
datefield.setMilliseconds(ms);\r
datefield.client.updateVariable(datefield.id, "msec", ms, datefield.immediate);\r
- //updateTime(false);\r
+ updateTime(false);\r
}\r
else if(sender == ampm) {\r
int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12;\r
datefield.date.setHours(h);\r
datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate);\r
- //updateTime(false);\r
+ updateTime(false);\r
}\r
}\r
\r
\r
private static void load(Date date, String text, String component, String input, Pattern regex) {\r
if (component.equals(DateLocale.TOKEN_MILLISECOND)) {\r
- // TODO implement setMilliseconds to date object\r
+ date.setTime(date.getTime() / 1000 * 1000 + Integer.parseInt(text));\r
}\r
\r
if (component.equals(DateLocale.TOKEN_SECOND)) {\r
--- /dev/null
+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
+ \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
+ \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
+ /* Object values for slider in stead of numeric.\r
+ * If this is set, min, max and resolution values are ignored.\r
+ */\r
+ private Object[] values;\r
+ \r
+ private int orientation = ORIENTATION_HORIZONTAL;\r
+ \r
+ private List listeners;\r
+ \r
+ private int width;\r
+ private int height;\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
+ }\r
+\r
+ public int getMax() {\r
+ return max;\r
+ }\r
+\r
+ public void setMax(int max) {\r
+ this.max = max;\r
+ }\r
+\r
+ public int getMin() {\r
+ return min;\r
+ }\r
+\r
+ public void setMin(int min) {\r
+ this.min = min;\r
+ }\r
+\r
+ public int getOrientation() {\r
+ return orientation;\r
+ }\r
+\r
+ public void setOrientation(int orientation) {\r
+ this.orientation = orientation;\r
+ }\r
+\r
+ public int getResolution() {\r
+ return resolution;\r
+ }\r
+\r
+ public void setResolution(int resolution) {\r
+ this.resolution = resolution;\r
+ }\r
+\r
+ public Object[] getValues() {\r
+ return values;\r
+ }\r
+\r
+ public void setValues(Object[] values) {\r
+ this.values = values;\r
+ }\r
+\r
+ public int getWidth() {\r
+ return width;\r
+ }\r
+\r
+ public void setWidth(int width) {\r
+ this.width = width;\r
+ }\r
+\r
+ public List getListeners() {\r
+ return listeners;\r
+ }\r
+ \r
+ public void addListener(SlideListener l) {\r
+ addListener(SlideEvent.class, l, SLIDER_SLIDE_METHOD);\r
+ }\r
+ \r
+ public void removeListener(SlideListener l) {\r
+ removeListener(SlideEvent.class, l, SLIDER_SLIDE_METHOD);\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
+\r
+ /**\r
+ * Invoked when the value of a variable has changed. Slider listeners are\r
+ * notified if the slider value has changed.\r
+ * \r
+ * @param source\r
+ * @param variables\r
+ */\r
+ public void changeVariables(Object source, Map variables) {\r
+ if (variables.containsKey("value")) {\r
+ // TODO update value\r
+ fireSlide();\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
+\r
+ /**\r
+ * Serial generated by Eclipse.\r
+ */\r
+ private static final long serialVersionUID = -2092497444591455077L;\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
+ }\r
+\r
+}\r