Author: tchemit Date: 2010-09-04 22:12:30 +0200 (Sat, 04 Sep 2010) New Revision: 2056 Url: http://nuiton.org/repositories/revision/jaxx/2056 Log: Evolution #845: Improve TimeEditor Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.css trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.jaxx trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditorHandler.java trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-en_GB.properties trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-fr_FR.properties Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.css =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.css 2010-08-30 10:01:11 UTC (rev 2055) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.css 2010-09-04 20:12:30 UTC (rev 2056) @@ -23,28 +23,33 @@ * #L% */ -#title{ +#title { text:{getLabel()}; horizontalAlignment:center; } -#hour{ - value:{getTimeModel()/60}; +#hour { + value:{getTimeModel() / 60}; enabled:{isEnabled()}; - model:{new SpinnerNumberModel(0,0,23,1)}; + model:{new SpinnerNumberModel(0, 0, 23, 1)}; } #labelH { text:"timeeditor.H"; horizontalAlignment:center; } -#minute{ - value:{getTimeModel()%60}; + +#minuteModel { + calendarField:{java.util.Calendar.MINUTE}; + value:{getHandler().setMinuteModel(getDate())}; +} + +#minute { enabled:{isEnabled()}; - model:{new SpinnerNumberModel(0,0,59,1)}; + model:{minuteModel}; } -#slider{ +#slider { font-size: 11; paintTicks:true; paintLabels:true; @@ -52,5 +57,5 @@ minorTickSpacing:30; value:{getTimeModel()}; enabled:{isEnabled()}; - model:{new DefaultBoundedRangeModel(0,1,0,60*24)}; + model:{new DefaultBoundedRangeModel(0, 1, 0, 60 * 24)}; } Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.jaxx =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.jaxx 2010-08-30 10:01:11 UTC (rev 2055) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditor.jaxx 2010-09-04 20:12:30 UTC (rev 2056) @@ -26,7 +26,9 @@ <JPanel layout='{new BorderLayout()}'> - <!--<style source='TimeEditor.css'/>--> + <import> + java.util.Date + </import> <!-- bean property --> <String id='property' javaBean='""'/> @@ -43,11 +45,15 @@ <!-- the real date --> <java.util.Date id="date" javaBean='null'/> + <!-- spinner minute editor --> + <SpinnerDateModel id="minuteModel"/> + <!-- ui handler --> <TimeEditorHandler id='handler' constructorParams='this'/> <script><![CDATA[ public void init() { + minute.setEditor(new JSpinner.DateEditor(minute, "mm")); handler.init(); } ]]> @@ -63,14 +69,14 @@ </cell> <cell> <JSpinner id='hour' - onStateChanged='setTimeModel((Integer)hour.getValue()* 60 + timeModel % 60)'/> + onStateChanged='setTimeModel((Integer)hour.getValue() * 60 + getHandler().getMinute())'/> </cell> <cell> <JLabel id='labelH'/> </cell> <cell> <JSpinner id='minute' - onStateChanged='setTimeModel((timeModel / 60) * 60 + (Integer) minute.getValue())'/> + onStateChanged='getHandler().updateTimeModelFromMinuteModel(minuteModel.getDate())'/> </cell> </row> </Table> Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditorHandler.java =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditorHandler.java 2010-08-30 10:01:11 UTC (rev 2055) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/TimeEditorHandler.java 2010-09-04 20:12:30 UTC (rev 2056) @@ -25,13 +25,16 @@ package jaxx.runtime.swing.editor; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; import org.apache.commons.beanutils.PropertyUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import javax.swing.JLabel; +import javax.swing.JSlider; +import javax.swing.plaf.basic.BasicSliderUI; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseWheelEvent; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.beans.PropertyDescriptor; @@ -41,26 +44,34 @@ import java.util.Dictionary; import java.util.Hashtable; import java.util.Map; -import javax.swing.JSlider; -import javax.swing.plaf.basic.BasicSliderUI; /** @author tchemit <chemit@codelutin.com> */ public class TimeEditorHandler { public static final Log log = LogFactory.getLog(TimeEditorHandler.class); + public static final String BEAN_PROPERTY = "bean"; + public static final String PROPERTY_PROPERTY = "property"; + public static final String DATE_PROPERTY = "date"; + public static final String TIME_MODEL_PROPERTY = "timeModel"; + /** editor ui */ protected TimeEditor editor; + /** the mutator method on the property of boxed bean in the editor */ protected Method mutator; + protected Calendar calendar; + protected Calendar calendarMinute; + public TimeEditorHandler(TimeEditor ui) { - this.editor = ui; - this.calendar = Calendar.getInstance(); + editor = ui; + calendar = Calendar.getInstance(); + calendarMinute = Calendar.getInstance(); } public void init() { @@ -75,7 +86,7 @@ labelTable.put(i * 60, new JLabel(i + "")); } JSlider slider = editor.getSlider(); - slider.setLabelTable((Dictionary<?,?>) labelTable); + slider.setLabelTable((Dictionary<?, ?>) labelTable); MouseAdapter m = new MouseAdapter() { @@ -111,6 +122,21 @@ showToolTip(e); } + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + JSlider slider = (JSlider) e.getComponent(); + + // compute new value + int nb = e.getWheelRotation(); + int value = slider.getValue() - nb; + + // set the value + slider.setValueIsAdjusting(true); + slider.setValue(value); + slider.setValueIsAdjusting(false); + e.consume(); + } + int getSliderValue(MouseEvent e) { JSlider slider = (JSlider) e.getSource(); int value = -1; @@ -149,6 +175,7 @@ }; slider.addMouseListener(m); slider.addMouseMotionListener(m); + slider.addMouseWheelListener(m); // listen when date changes (should come from outside) editor.addPropertyChangeListener(DATE_PROPERTY, new PropertyChangeListener() { @@ -166,7 +193,7 @@ if (log.isDebugEnabled()) { log.debug("date changed : new value " + hours + ":" + minutes); } - getEditor().setTimeModel((hours * 60) + minutes); + getEditor().setTimeModel(hours * 60 + minutes); } }); @@ -189,6 +216,97 @@ return editor; } + protected Date setMinuteModel(Date incomingDate) { + if (incomingDate == null) { + incomingDate = new Date(); + } + calendarMinute.setTime(incomingDate); + calendarMinute.set(Calendar.HOUR_OF_DAY, 0); + incomingDate = calendarMinute.getTime(); + return incomingDate; + } + + public int getMinute() { + return getEditor().getTimeModel() % 60; + } + + public int getHour() { + return getEditor().getTimeModel() / 60; + } + + public void updateTimeModelFromMinuteModel(Date minuteDate) { + + calendarMinute.setTime(minuteDate); + int newHour = calendarMinute.get(Calendar.HOUR_OF_DAY); + int newMinute = calendarMinute.get(Calendar.MINUTE); + + int oldHour = getHour(); + int oldMinute = getMinute(); + + if (oldHour == newHour && oldMinute == newMinute) { + + // do nothing, same data + if (log.isDebugEnabled()) { + log.debug("Do not update time model , stay on same time = " + oldHour + ":" + oldMinute); + } + return; + } + + // by default stay on same hour + int hour = oldHour; + + // by default, use the new minute data + int minute = newMinute; + + if (log.isDebugEnabled()) { + log.debug("hh:mm (old from dateModel) = " + oldHour + ":" + oldMinute); + log.debug("hh:mm (new from minuteModel) = " + newHour + ":" + newMinute); + } + + if (newMinute == 0) { + + // minute pass to zero (check if a new hour is required) + if (newHour == 1) { + + if (oldHour == 23) { + + // can't pass from 23:59 to 0:00, stay on 23:59 + if (log.isDebugEnabled()) { + log.debug("Do not update time model , stay on hh:mm = " + oldHour + ":" + oldMinute); + } + getEditor().getMinuteModel().setValue(getEditor().getMinuteModel().getPreviousValue()); + return; + } + hour = (oldHour + 1) % 24; + } + } else if (newMinute == 59) { + + // minute pass to 59 (check if a new hour is required) + + if (newHour == 23) { + + if (oldHour == 0) { + + // can't pass from 0:00 to 23:59, stay on 0:00 + if (log.isDebugEnabled()) { + log.debug("Do not update time model , stay on hh:mm = " + oldHour + ":" + oldMinute); + } + getEditor().getMinuteModel().setValue(getEditor().getMinuteModel().getNextValue()); + return; + } + + // decrease hour + hour = (oldHour - 1) % 24; + } + } + + // date has changed + if (log.isDebugEnabled()) { + log.debug("Update time model to hh:mm = " + hour + ":" + minute); + } + getEditor().setTimeModel(hour * 60 + minute); + } + protected void setDate(Date oldValue, Date newValue) { if (editor.getBean() == null) { return; Modified: trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-en_GB.properties =================================================================== --- trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-en_GB.properties 2010-08-30 10:01:11 UTC (rev 2055) +++ trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-en_GB.properties 2010-09-04 20:12:30 UTC (rev 2056) @@ -9,13 +9,9 @@ config.action.reset.tip=Cancel the modifications for the category config.action.save=Save config.action.save.tip=Save the modifications for the category -config.category.needReloadApplication=Category '%1$s' \: -config.category.needReloadUI=Category '%1$s' \: -config.category.saved=The category '%1$s' was modified \: config.choice.cancel=Cancel config.choice.continue=Continue config.choice.doNotSave=Do not save -config.choice.ok=Ok config.choice.save=Save config.defaultValue=Default value config.defaultValue.tip=Default value of the option @@ -29,8 +25,6 @@ config.launch.callBack.tip=Perform necessary actions config.message.quit.invalid.category=The category '%1$s' is not valid\! config.message.quit.valid.and.modified.category=The category '%1$s' has some modified options \: -config.model.needReloadApplication=Some options were modified and need to reload application.\n -config.model.needReloadUI=Some options were modified and need to reload GUI.\n config.modified=Option was modified (previous value \: %1$s) config.no.option.selected=< No selected option > config.option.final=This option can not be modified @@ -38,8 +32,6 @@ config.option.modified=Value is modified < original value \: '%1$s' - new value \: '%2$s' > config.title=Preferences config.title.need.confirm=A confirmation is required -config.title.will.reload.application=The application need to be restarted -config.title.will.reload.ui=The graphical interface must be relauched config.unmodifiable=Can not be modified config.unvalid=Option is not valid \! (previous value \: %1$s, required type \: %2$s) config.value=Value Modified: trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-fr_FR.properties =================================================================== --- trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-fr_FR.properties 2010-08-30 10:01:11 UTC (rev 2055) +++ trunk/jaxx-widgets/src/main/resources/i18n/jaxx-widgets-fr_FR.properties 2010-09-04 20:12:30 UTC (rev 2056) @@ -9,13 +9,9 @@ config.action.reset.tip=Annuler les modifications de cette cat\u00E9gorie config.action.save=Enregistrer config.action.save.tip=Sauver les modifications de cette cat\u00E9gorie -config.category.needReloadApplication=Cat\u00E9gorie '%1$s' \: -config.category.needReloadUI=Cat\u00E9gorie '%1$s' \: -config.category.saved=La cat\u00E9gorie '%1$s' a \u00E9t\u00E9 modifi\u00E9e \: config.choice.cancel=Annuler config.choice.continue=Continuer config.choice.doNotSave=Ne pas enregistrer -config.choice.ok=Ok config.choice.save=Enregistrer config.defaultValue=Valeur par d\u00E9faut config.defaultValue.tip=Valeur par d\u00E9faut de l'option @@ -29,8 +25,6 @@ config.launch.callBack.tip=Lancer les actions n\u00E9cessaires config.message.quit.invalid.category=La cat\u00E9gorie '%1$s' n'est pas valide\! config.message.quit.valid.and.modified.category=La cat\u00E9gorie '%1$s' poss\u00E8dent des options modifi\u00E9es \: -config.model.needReloadApplication=Des options ont \u00E9t\u00E9 modifi\u00E9es qui n\u00E9cessitent le red\u00E9marrage de l'application.\n -config.model.needReloadUI=Des options ont \u00E9t\u00E9 modifi\u00E9es qui n\u00E9cessitent le red\u00E9marrage de l'interface graphique.\n config.modified=Option modifi\u00E9e (valeur originale \: %1$s) config.no.option.selected=< Pas d'option s\u00E9lectionn\u00E9e > config.option.final=Option non modifiable @@ -38,8 +32,6 @@ config.option.modified=Valeur modifi\u00E9e < ancienne valeur \: '%1$s' - nouvelle valeur \: '%2$s' > config.title=Pr\u00E9f\u00E9rences config.title.need.confirm=Une confirmation de votre part est requise... -config.title.will.reload.application=L'application doit \u00EAtre red\u00E9marrer... -config.title.will.reload.ui=L'interface graphique doit \u00EAtre relancer... config.unmodifiable=Ne peut pas \u00EAtre modifi\u00E9 config.unvalid=Option non valide (valeur originale \: %1$s, type requis \: %2$s) config.value=Valeur
participants (1)
-
tchemit@users.nuiton.org