IDateField now supports null value. svn changeset:1906/svn branch:trunktags/6.7.0.beta1
@@ -70,6 +70,10 @@ public class ICalendarPanel extends FlexTable implements MouseListener, ClickLis | |||
} | |||
private void buildCalendarHeader(boolean forceRedraw, boolean needsMonth) { | |||
// Can't draw a calendar without a date :) | |||
if(datefield.date == null) | |||
datefield.date = new Date(); | |||
if(forceRedraw) { | |||
if(prevMonth == null) { // Only do once | |||
prevYear = new IEventButton(); prevYear.setHTML("«"); | |||
@@ -119,6 +123,8 @@ public class ICalendarPanel extends FlexTable implements MouseListener, ClickLis | |||
private void buildCalendarBody() { | |||
Date date = datefield.date; | |||
if(date == null) | |||
date = new Date(); | |||
int startWeekDay = datefield.dts.getStartWeekDay(date); | |||
int numDays = DateTimeService.getNumberOfDaysInMonth(date); | |||
int dayCount = 0; | |||
@@ -160,6 +166,8 @@ public class ICalendarPanel extends FlexTable implements MouseListener, ClickLis | |||
public void updateCalendar() { | |||
// Locale and resolution changes force a complete redraw | |||
buildCalendar(locale != datefield.currentLocale || resolution != datefield.currentResolution); | |||
if(datefield instanceof ITextualDate) | |||
((ITextualDate) datefield).buildDate(); | |||
locale = datefield.currentLocale; | |||
resolution = datefield.currentResolution; | |||
} | |||
@@ -275,9 +283,7 @@ public class ICalendarPanel extends FlexTable implements MouseListener, ClickLis | |||
cal.datefield.date.setDate(day.intValue()); | |||
cal.datefield.client.updateVariable(cal.datefield.id, "day", cal.datefield.date.getDate(), cal.datefield.immediate); | |||
// No need to update calendar header | |||
cal.clearCalendarBody(false); | |||
cal.buildCalendarBody(); | |||
updateCalendar(); | |||
} | |||
} |
@@ -34,16 +34,12 @@ public class IDateField extends FlowPanel implements Paintable { | |||
protected boolean enabled; | |||
protected Date date; | |||
/* For easy access, because java.util.Date doesn't have getMilliseconds method */ | |||
private int milliseconds = 0; | |||
protected Date date = null; | |||
protected DateTimeService dts; | |||
public IDateField() { | |||
setStyleName(CLASSNAME); | |||
date = new Date(); | |||
dts = new DateTimeService(); | |||
} | |||
@@ -98,9 +94,9 @@ public class IDateField extends FlowPanel implements Paintable { | |||
int sec = (currentResolution >= RESOLUTION_SEC)? uidl.getIntVariable("sec") : -1; | |||
int msec = (currentResolution >= RESOLUTION_MSEC)? uidl.getIntVariable("msec") : -1; | |||
// Construct new date for this datefield | |||
date = new Date((long) buildTime(year, month, day, hour, min, sec, msec)); | |||
milliseconds = msec<0? 0 : msec; | |||
// Construct new date for this datefield (only if not null) | |||
if(year > -1) | |||
date = new Date((long) getTime(year, month, day, hour, min, sec, msec)); | |||
} | |||
@@ -108,7 +104,7 @@ public class IDateField extends FlowPanel implements Paintable { | |||
* We need this redundant native function because | |||
* Java's Date object doesn't have a setMilliseconds method. | |||
*/ | |||
private static native double buildTime(int y, int m, int d, int h, int mi, int s, int ms) /*-{ | |||
private static native double getTime(int y, int m, int d, int h, int mi, int s, int ms) /*-{ | |||
try { | |||
var date = new Date(); | |||
if(y && y >= 0) date.setFullYear(y); | |||
@@ -127,13 +123,11 @@ public class IDateField extends FlowPanel implements Paintable { | |||
}-*/; | |||
public int getMilliseconds() { | |||
return milliseconds; | |||
return (int) (date.getTime() - date.getTime() / 1000 * 1000); | |||
} | |||
public void setMilliseconds(int ms) { | |||
long time = (long) buildTime(date.getYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), ms); | |||
date = new Date(time); | |||
milliseconds = ms; | |||
date.setTime(date.getTime() / 1000 * 1000 + ms); | |||
} | |||
} |
@@ -33,7 +33,8 @@ public class IPopupCalendar extends ITextualDate implements Paintable, ClickList | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
super.updateFromUIDL(uidl, client); | |||
calendar.updateCalendar(); | |||
if(date != null) | |||
calendar.updateCalendar(); | |||
calendarToggle.setEnabled(enabled); | |||
} | |||
@@ -49,7 +50,7 @@ public class IPopupCalendar extends ITextualDate implements Paintable, ClickList | |||
public void onPopupClosed(PopupPanel sender, boolean autoClosed) { | |||
if(sender == popup) | |||
buildTime(); | |||
buildDate(); | |||
} | |||
} |
@@ -0,0 +1,34 @@ | |||
package com.itmill.toolkit.terminal.gwt.client.ui; | |||
import com.google.gwt.user.client.DOM; | |||
import com.google.gwt.user.client.Element; | |||
import com.google.gwt.user.client.ui.Widget; | |||
import com.itmill.toolkit.terminal.gwt.client.ApplicationConnection; | |||
import com.itmill.toolkit.terminal.gwt.client.Paintable; | |||
import com.itmill.toolkit.terminal.gwt.client.UIDL; | |||
public class ISlider extends Widget implements Paintable { | |||
/* DOM element for slider's base */ | |||
private Element base; | |||
/* DOM element for slider's handle */ | |||
private Element handle; | |||
public ISlider() { | |||
super(); | |||
base = DOM.createElement("div"); | |||
handle = DOM.createElement("div"); | |||
DOM.appendChild(base, handle); | |||
setElement(base); | |||
} | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
// Ensure correct implementation (handle own caption) | |||
if (client.updateComponent(this, uidl, false)) | |||
return; | |||
} | |||
} |
@@ -27,10 +27,10 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene | |||
public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { | |||
super.updateFromUIDL(uidl, client); | |||
buildTime(); | |||
buildDate(); | |||
} | |||
protected void buildTime() { | |||
protected void buildDate() { | |||
dl = new DateLocale(); | |||
DateLocale.setLocale(currentLocale); | |||
@@ -43,29 +43,32 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene | |||
format = new SimpleDateFormat(verifyFormat(dts.getDateFormat())); | |||
format.setLocale(dl); | |||
String dateText = format.format(date); | |||
String dateText = ""; | |||
if(date != null) { | |||
dateText = format.format(date); | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR) { | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL; | |||
int h = date.getHours(); | |||
if(h > 11 && dts.isTwelveHourClock()) | |||
h -= 12; | |||
int m = currentResolution > IDateField.RESOLUTION_HOUR? date.getMinutes() : 0; | |||
dateText += " " + (h<10?"0"+h:""+h) + dts.getClockDelimeter() + (m<10?"0"+m:""+m); | |||
} | |||
if(currentResolution >= IDateField.RESOLUTION_SEC) { | |||
int s = date.getSeconds(); | |||
dateText += dts.getClockDelimeter() + (s<10?"0"+s:""+s); | |||
} | |||
if(currentResolution == IDateField.RESOLUTION_MSEC) { | |||
int ms = getMilliseconds(); | |||
String text = ""+ms; | |||
if(ms<10) text = "00"+text; | |||
else if(ms<100) text = "0"+text; | |||
dateText += "." + text; | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR) { | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL; | |||
int h = date.getHours(); | |||
if(h > 11 && dts.isTwelveHourClock()) | |||
h -= 12; | |||
int m = currentResolution > IDateField.RESOLUTION_HOUR? date.getMinutes() : 0; | |||
dateText += " " + (h<10?"0"+h:""+h) + dts.getClockDelimeter() + (m<10?"0"+m:""+m); | |||
} | |||
if(currentResolution >= IDateField.RESOLUTION_SEC) { | |||
int s = date.getSeconds(); | |||
dateText += dts.getClockDelimeter() + (s<10?"0"+s:""+s); | |||
} | |||
if(currentResolution == IDateField.RESOLUTION_MSEC) { | |||
int ms = getMilliseconds(); | |||
String text = ""+ms; | |||
if(ms<10) text = "00"+text; | |||
else if(ms<100) text = "0"+text; | |||
dateText += "." + text; | |||
} | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock()) | |||
dateText += " " + (date.getHours()<12? dts.getAmPmStrings()[0] : dts.getAmPmStrings()[1]); | |||
} | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock()) | |||
dateText += " " + (date.getHours()<12? dts.getAmPmStrings()[0] : dts.getAmPmStrings()[1]); | |||
text.setText(dateText); | |||
text.setEnabled(enabled&&!readonly); | |||
@@ -78,64 +81,67 @@ public class ITextualDate extends IDateField implements Paintable, ChangeListene | |||
public void onChange(Widget sender) { | |||
if(sender == text) { | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL; | |||
if(currentResolution == IDateField.RESOLUTION_YEAR) | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_YEAR; | |||
else if(currentResolution == IDateField.RESOLUTION_MONTH) | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_MONTH; | |||
else if(currentResolution == IDateField.RESOLUTION_DAY) | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_DAY; | |||
String f = verifyFormat(dts.getDateFormat()); | |||
if(!text.getText().equals("")) { | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_ALL; | |||
if(currentResolution == IDateField.RESOLUTION_YEAR) | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_YEAR; | |||
else if(currentResolution == IDateField.RESOLUTION_MONTH) | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_MONTH; | |||
else if(currentResolution == IDateField.RESOLUTION_DAY) | |||
DateLocale.SUPPORTED_DF_TOKENS = DateLocale.TOKENS_RESOLUTION_DAY; | |||
String f = verifyFormat(dts.getDateFormat()); | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR) | |||
f += " " + (dts.isTwelveHourClock()? | |||
DateLocale.TOKEN_HOUR_12 + DateLocale.TOKEN_HOUR_12 | |||
: DateLocale.TOKEN_HOUR_24 + DateLocale.TOKEN_HOUR_24) | |||
+ dts.getClockDelimeter() + DateLocale.TOKEN_MINUTE + DateLocale.TOKEN_MINUTE; | |||
if(currentResolution >= IDateField.RESOLUTION_SEC) | |||
f += dts.getClockDelimeter() + DateLocale.TOKEN_SECOND + DateLocale.TOKEN_SECOND; | |||
if(currentResolution == IDateField.RESOLUTION_MSEC) | |||
f += "." + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND; | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock()) | |||
f += " " + DateLocale.TOKEN_AM_PM; | |||
format = new SimpleDateFormat(f); | |||
DateLocale.setLocale(currentLocale); | |||
format.setLocale(dl); | |||
try { | |||
date = format.parse(text.getText()); | |||
} catch (Exception e) { | |||
client.console.log(e.getMessage()); | |||
text.addStyleName(ITextField.CLASSNAME+"-error"); | |||
Timer t = new Timer() { | |||
public void run() { | |||
text.removeStyleName(ITextField.CLASSNAME+"-error"); | |||
} | |||
}; | |||
t.schedule(2000); | |||
return; | |||
} | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR) | |||
f += " " + (dts.isTwelveHourClock()? | |||
DateLocale.TOKEN_HOUR_12 + DateLocale.TOKEN_HOUR_12 | |||
: DateLocale.TOKEN_HOUR_24 + DateLocale.TOKEN_HOUR_24) | |||
+ dts.getClockDelimeter() + DateLocale.TOKEN_MINUTE + DateLocale.TOKEN_MINUTE; | |||
if(currentResolution >= IDateField.RESOLUTION_SEC) | |||
f += dts.getClockDelimeter() + DateLocale.TOKEN_SECOND + DateLocale.TOKEN_SECOND; | |||
if(currentResolution == IDateField.RESOLUTION_MSEC) | |||
f += "." + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND + DateLocale.TOKEN_MILLISECOND; | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR && dts.isTwelveHourClock()) | |||
f += " " + DateLocale.TOKEN_AM_PM; | |||
format = new SimpleDateFormat(f); | |||
DateLocale.setLocale(currentLocale); | |||
format.setLocale(dl); | |||
try { | |||
date = format.parse(text.getText()); | |||
} catch (Exception e) { | |||
// TODO redirect to console | |||
System.out.println(e); | |||
text.addStyleName(ITextField.CLASSNAME+"-error"); | |||
Timer t = new Timer() { | |||
public void run() { | |||
text.removeStyleName(ITextField.CLASSNAME+"-error"); | |||
} | |||
}; | |||
t.schedule(2000); | |||
return; | |||
} | |||
} else | |||
date = null; | |||
// Update variables | |||
// (only the smallest defining resolution needs to be immediate) | |||
client.updateVariable(id, "year", date.getYear()+1900, currentResolution==IDateField.RESOLUTION_YEAR); | |||
client.updateVariable(id, "year", date!=null?date.getYear()+1900:-1, currentResolution==IDateField.RESOLUTION_YEAR); | |||
if(currentResolution >= IDateField.RESOLUTION_MONTH) | |||
client.updateVariable(id, "month", date.getMonth()+1, currentResolution==IDateField.RESOLUTION_MONTH&&immediate); | |||
client.updateVariable(id, "month", date!=null?date.getMonth()+1:-1, currentResolution==IDateField.RESOLUTION_MONTH&&immediate); | |||
if(currentResolution >= IDateField.RESOLUTION_DAY) | |||
client.updateVariable(id, "day", date.getDate(), currentResolution==IDateField.RESOLUTION_DAY&&immediate); | |||
client.updateVariable(id, "day", date!=null?date.getDate():-1, currentResolution==IDateField.RESOLUTION_DAY&&immediate); | |||
if(currentResolution >= IDateField.RESOLUTION_HOUR) | |||
client.updateVariable(id, "hour", date.getHours(), currentResolution==IDateField.RESOLUTION_HOUR&&immediate); | |||
client.updateVariable(id, "hour", date!=null?date.getHours():-1, currentResolution==IDateField.RESOLUTION_HOUR&&immediate); | |||
if(currentResolution >= IDateField.RESOLUTION_MIN) | |||
client.updateVariable(id, "min", date.getMinutes(), currentResolution==IDateField.RESOLUTION_MIN&&immediate); | |||
client.updateVariable(id, "min", date!=null?date.getMinutes():-1, currentResolution==IDateField.RESOLUTION_MIN&&immediate); | |||
if(currentResolution >= IDateField.RESOLUTION_SEC) | |||
client.updateVariable(id, "sec", date.getSeconds(), currentResolution==IDateField.RESOLUTION_SEC&&immediate); | |||
client.updateVariable(id, "sec", date!=null?date.getSeconds():-1, currentResolution==IDateField.RESOLUTION_SEC&&immediate); | |||
if(currentResolution == IDateField.RESOLUTION_MSEC) | |||
client.updateVariable(id, "msec", getMilliseconds(), immediate); | |||
client.updateVariable(id, "msec", date!=null?getMilliseconds():-1, immediate); | |||
buildTime(); | |||
buildDate(); | |||
} | |||
} | |||
@@ -79,7 +79,9 @@ public class ITime extends FlowPanel implements ChangeListener { | |||
boolean ro = datefield.readonly; | |||
if(ro) { | |||
int h = datefield.date.getHours(); | |||
int h = 0; | |||
if(datefield.date != null) | |||
h = datefield.date.getHours(); | |||
if(thc) h -= h<12? 0 : 12; | |||
add(new ILabel(h<10? "0"+h : ""+h)); | |||
} else add(hours); | |||
@@ -184,6 +186,8 @@ public class ITime extends FlowPanel implements ChangeListener { | |||
public void updateTime(boolean redraw) { | |||
buildTime(redraw || resolution != datefield.currentResolution | |||
|| readonly != datefield.readonly); | |||
if(datefield instanceof ITextualDate) | |||
((ITextualDate) datefield).buildDate(); | |||
resolution = datefield.currentResolution; | |||
readonly = datefield.readonly; | |||
} | |||
@@ -195,31 +199,31 @@ public class ITime extends FlowPanel implements ChangeListener { | |||
h = h + ampm.getSelectedIndex()*12; | |||
datefield.date.setHours(h); | |||
datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate); | |||
//updateTime(false); | |||
updateTime(false); | |||
} | |||
else if(sender == mins) { | |||
int m = mins.getSelectedIndex(); | |||
datefield.date.setMinutes(m); | |||
datefield.client.updateVariable(datefield.id, "min", m, datefield.immediate); | |||
//updateTime(false); | |||
updateTime(false); | |||
} | |||
else if(sender == sec) { | |||
int s = sec.getSelectedIndex(); | |||
datefield.date.setSeconds(s); | |||
datefield.client.updateVariable(datefield.id, "sec", s, datefield.immediate); | |||
//updateTime(false); | |||
updateTime(false); | |||
} | |||
else if(sender == msec) { | |||
int ms = msec.getSelectedIndex(); | |||
datefield.setMilliseconds(ms); | |||
datefield.client.updateVariable(datefield.id, "msec", ms, datefield.immediate); | |||
//updateTime(false); | |||
updateTime(false); | |||
} | |||
else if(sender == ampm) { | |||
int h = hours.getSelectedIndex() + ampm.getSelectedIndex()*12; | |||
datefield.date.setHours(h); | |||
datefield.client.updateVariable(datefield.id, "hour", h, datefield.immediate); | |||
//updateTime(false); | |||
updateTime(false); | |||
} | |||
} | |||
@@ -92,7 +92,7 @@ public class SimpleDateParser { | |||
private static void load(Date date, String text, String component, String input, Pattern regex) { | |||
if (component.equals(DateLocale.TOKEN_MILLISECOND)) { | |||
// TODO implement setMilliseconds to date object | |||
date.setTime(date.getTime() / 1000 * 1000 + Integer.parseInt(text)); | |||
} | |||
if (component.equals(DateLocale.TOKEN_SECOND)) { |
@@ -0,0 +1,184 @@ | |||
package com.itmill.toolkit.ui; | |||
import java.io.IOException; | |||
import java.lang.reflect.Method; | |||
import java.util.Iterator; | |||
import java.util.LinkedHashSet; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.Set; | |||
import java.util.StringTokenizer; | |||
import com.itmill.toolkit.event.Action; | |||
import com.itmill.toolkit.event.ShortcutAction; | |||
import com.itmill.toolkit.terminal.PaintException; | |||
import com.itmill.toolkit.terminal.PaintTarget; | |||
import com.itmill.toolkit.ui.Button.ClickEvent; | |||
public class Slider extends AbstractComponent { | |||
public static final int ORIENTATION_HORIZONTAL = 0; | |||
public static final int ORIENTATION_VERTICAL = 1; | |||
/* Minimum value of slider */ | |||
private int min = 0; | |||
/* Maximum value of slider */ | |||
private int max = 100; | |||
/* Resolution, how many digits are considered relevant after desimal point */ | |||
private int resolution = 2; | |||
/* Current value */ | |||
private Object value; | |||
/* Object values for slider in stead of numeric. | |||
* If this is set, min, max and resolution values are ignored. | |||
*/ | |||
private Object[] values; | |||
private int orientation = ORIENTATION_HORIZONTAL; | |||
private List listeners; | |||
private int width; | |||
private int height; | |||
public Object getValue() { | |||
return value; | |||
} | |||
public int getHeight() { | |||
return height; | |||
} | |||
public void setHeight(int height) { | |||
this.height = height; | |||
} | |||
public int getMax() { | |||
return max; | |||
} | |||
public void setMax(int max) { | |||
this.max = max; | |||
} | |||
public int getMin() { | |||
return min; | |||
} | |||
public void setMin(int min) { | |||
this.min = min; | |||
} | |||
public int getOrientation() { | |||
return orientation; | |||
} | |||
public void setOrientation(int orientation) { | |||
this.orientation = orientation; | |||
} | |||
public int getResolution() { | |||
return resolution; | |||
} | |||
public void setResolution(int resolution) { | |||
this.resolution = resolution; | |||
} | |||
public Object[] getValues() { | |||
return values; | |||
} | |||
public void setValues(Object[] values) { | |||
this.values = values; | |||
} | |||
public int getWidth() { | |||
return width; | |||
} | |||
public void setWidth(int width) { | |||
this.width = width; | |||
} | |||
public List getListeners() { | |||
return listeners; | |||
} | |||
public void addListener(SlideListener l) { | |||
addListener(SlideEvent.class, l, SLIDER_SLIDE_METHOD); | |||
} | |||
public void removeListener(SlideListener l) { | |||
removeListener(SlideEvent.class, l, SLIDER_SLIDE_METHOD); | |||
} | |||
public String getTag() { | |||
return "slider"; | |||
} | |||
public interface SlideListener { | |||
public void slide(SlideEvent s); | |||
} | |||
public void paintContent(PaintTarget target) throws PaintException { | |||
super.paintContent(target); | |||
// TODO | |||
} | |||
/** | |||
* Invoked when the value of a variable has changed. Slider listeners are | |||
* notified if the slider value has changed. | |||
* | |||
* @param source | |||
* @param variables | |||
*/ | |||
public void changeVariables(Object source, Map variables) { | |||
if (variables.containsKey("value")) { | |||
// TODO update value | |||
fireSlide(); | |||
} | |||
} | |||
/* ************************************************** | |||
* Event handling classes and methods | |||
*/ | |||
public class SlideEvent extends Component.Event { | |||
public SlideEvent(Component source) { | |||
super(source); | |||
} | |||
public Slider getSlider() { | |||
return (Slider) getSource(); | |||
} | |||
/** | |||
* Serial generated by Eclipse. | |||
*/ | |||
private static final long serialVersionUID = -2092497444591455077L; | |||
} | |||
protected void fireSlide() { | |||
fireEvent(new Slider.SlideEvent(this)); | |||
} | |||
/* Slide event ************************************************ */ | |||
private static final Method SLIDER_SLIDE_METHOD; | |||
static { | |||
try { | |||
SLIDER_SLIDE_METHOD = SlideListener.class.getDeclaredMethod( | |||
"slide", new Class[] { ClickEvent.class }); | |||
} catch (java.lang.NoSuchMethodException e) { | |||
// This should never happen | |||
throw new java.lang.RuntimeException(); | |||
} | |||
} | |||
} |