Coverage Report - org.openpermis.editor.policy.gui.component.TimeStampPicker
 
Classes in this File Line Coverage Branch Coverage Complexity
TimeStampPicker
0%
0/31
N/A
1.615
TimeStampPicker$1
N/A
N/A
1.615
TimeStampPicker$TimeOfDayBindingListener
0%
0/6
N/A
1.615
TimeStampPicker$TimeOfDayConverter
0%
0/14
0%
0/10
1.615
 
 1  
 /*
 2  
  * Copyright (c) 2009, Ergon Informatik AG (http://www.ergon.ch)
 3  
  * All rights reserved.
 4  
  * 
 5  
  * Licensed under the Open Permis License which accompanies this distribution, 
 6  
  * and is available at http://www.openpermis.org/BSDlicenceKent.txt
 7  
  */
 8  
 package org.openpermis.editor.policy.gui.component;
 9  
 
 10  
 import java.awt.Color;
 11  
 import java.awt.LayoutManager;
 12  
 import java.util.Date;
 13  
 import java.util.StringTokenizer;
 14  
 import java.util.TimeZone;
 15  
 
 16  
 import javax.swing.JPanel;
 17  
 import javax.swing.JTextField;
 18  
 
 19  
 import org.jdesktop.beansbinding.AbstractBindingListener;
 20  
 import org.jdesktop.beansbinding.BeanProperty;
 21  
 import org.jdesktop.beansbinding.Binding;
 22  
 import org.jdesktop.beansbinding.BindingGroup;
 23  
 import org.jdesktop.beansbinding.Bindings;
 24  
 import org.jdesktop.beansbinding.Converter;
 25  
 import org.jdesktop.beansbinding.AutoBinding.UpdateStrategy;
 26  
 import org.jdesktop.beansbinding.Binding.SyncFailure;
 27  
 import org.jdesktop.swingx.JXDatePicker;
 28  
 import org.jdesktop.swingx.calendar.SingleDaySelectionModel;
 29  
 
 30  
 import com.jgoodies.forms.layout.CellConstraints;
 31  
 import com.jgoodies.forms.layout.FormLayout;
 32  
 
 33  
 import org.openpermis.policy.TimeStamp;
 34  
 
 35  
 /**
 36  
  * Allows users to pick time stamps.
 37  
  * @since 0.3.0
 38  
  */
 39  0
 public class TimeStampPicker
 40  
         extends JPanel
 41  
 {
 42  
 
 43  
         //---- Static
 44  
         
 45  
         /**
 46  
          * @since 0.3.0
 47  
          */
 48  0
         private static class TimeOfDayConverter
 49  
                 extends Converter<Long, String>
 50  
         {
 51  
 
 52  
                 private static final long MILLIS_PER_MINUTE = 60000L;
 53  
                 private static final long MINUTES_PER_HOUR = 60L;
 54  
 
 55  
                 @Override
 56  
                 public String convertForward (Long value) {
 57  0
                         return String.format(
 58  
                                 "%02d:%02d",
 59  
                                 hoursFromMillis(value.longValue()),
 60  
                                 minutesFromMillis(value.longValue())
 61  
                         );
 62  
                 }
 63  
 
 64  
                 private Object minutesFromMillis (long millis) {
 65  0
                         return Long.valueOf((millis / MILLIS_PER_MINUTE) % MINUTES_PER_HOUR);
 66  
                 }
 67  
 
 68  
                 private Object hoursFromMillis (long millis) {
 69  0
                         return Long.valueOf(millis / (MILLIS_PER_MINUTE * MINUTES_PER_HOUR));
 70  
                 }
 71  
 
 72  
                 @Override
 73  
                 public Long convertReverse (String value) {
 74  0
                         StringTokenizer st = new StringTokenizer(value, ":");
 75  0
                         if (st.countTokens() != 2) {
 76  0
                                 throw new IllegalArgumentException("Illegal number of tokens: " + value);
 77  
                         }
 78  0
                         final long hours = Long.parseLong(st.nextToken());
 79  0
                         if (hours < 0 || 24 <= hours) {
 80  0
                                 throw new IllegalArgumentException("Illegal hour in " + value);
 81  
                         }
 82  0
                         final long minutes = Long.parseLong(st.nextToken());
 83  0
                         if (minutes < 0 || MINUTES_PER_HOUR <= minutes) {
 84  0
                                 throw new IllegalArgumentException("Illegal minute in " + value);
 85  
                         }
 86  0
                         return Long.valueOf((MINUTES_PER_HOUR * hours + minutes) * MILLIS_PER_MINUTE);
 87  
                 }
 88  
         }
 89  
 
 90  
         /**
 91  
          * @since 0.3.0
 92  
          */
 93  
         private static final long serialVersionUID = 6646587876890127513L;
 94  
         
 95  
         /**
 96  
          * @since 0.3.0
 97  
          */
 98  
         private static LayoutManager createPanelLayout () {
 99  0
                 return new FormLayout("pref, $rgap, pref, fill:pref", "pref");
 100  
         }
 101  
 
 102  
         //---- State
 103  
         
 104  
         /**
 105  
          * @since 0.3.0
 106  
          */
 107  0
         private class TimeOfDayBindingListener
 108  
                 extends AbstractBindingListener
 109  
         {
 110  
         
 111  0
                 final Color defaultBackground = TimeStampPicker.this.timeField.getBackground();
 112  
         
 113  
                 @SuppressWarnings("unchecked")
 114  
                 @Override
 115  
                 public void syncFailed (Binding binding, SyncFailure failure) {
 116  0
                         TimeStampPicker.this.timeField.setBackground(Color.RED);
 117  0
                 }
 118  
         
 119  
                 @SuppressWarnings("unchecked")
 120  
                 @Override
 121  
                 public void synced (Binding binding) {
 122  0
                         TimeStampPicker.this.timeField.setBackground(this.defaultBackground);
 123  0
                 }
 124  
         }
 125  
 
 126  
         /**
 127  
          * @since 0.3.0
 128  
          */
 129  
         private JXDatePicker datePicker;
 130  
         
 131  
         /**
 132  
          * @since 0.3.0
 133  
          */
 134  
         private JTextField timeField;
 135  
 
 136  
         /**
 137  
          * @since 0.3.0
 138  
          */
 139  
         private TimeStamp timeStamp;
 140  
         
 141  
         /**
 142  
          * @since 0.3.0
 143  
          */
 144  
         private final TimeStampModel model;
 145  
         
 146  
         //---- Constructors
 147  
         
 148  
         /**
 149  
          * @since 0.3.0
 150  
          */
 151  
         public TimeStampPicker () {
 152  0
                 super(createPanelLayout());
 153  0
                 this.model = new TimeStampModel(new TimeStamp(new Date(), TimeZone.getDefault()));
 154  0
                 fillContentPane();
 155  0
                 bindToModel();
 156  0
         }
 157  
 
 158  
         //---- Methods
 159  
         
 160  
         /**
 161  
          * @since 0.3.0
 162  
          */
 163  
         private void fillContentPane () {
 164  0
                 final CellConstraints cc = new CellConstraints();
 165  
                 
 166  0
                 this.datePicker = new JXDatePicker();
 167  0
                 this.datePicker.getMonthView().setSelectionModel(new SingleDaySelectionModel());
 168  0
                 add(this.datePicker, cc.xy(1, 1));
 169  
                 
 170  0
                 this.timeField = new JTextField(5);
 171  0
                 add(this.timeField, cc.xy(3, 1));
 172  0
         }
 173  
         
 174  
         /**
 175  
          * @since 0.3.0
 176  
          */
 177  
         private void bindToModel () {
 178  0
                 final BindingGroup bindings = new BindingGroup();
 179  0
                 bindings.addBinding(
 180  
                         Bindings.createAutoBinding(
 181  
                                 UpdateStrategy.READ_WRITE,
 182  
                                 this.model,
 183  
                                 BeanProperty.create("date"),
 184  
                                 this.datePicker,
 185  
                                 BeanProperty.create("date")
 186  
                         )
 187  
                 );
 188  0
                 addTimeOfDayBinding(bindings);
 189  0
                 bindings.bind();
 190  0
         }
 191  
 
 192  
         /**
 193  
          * @since 0.3.0
 194  
          */
 195  
         @SuppressWarnings("unchecked")
 196  
         private void addTimeOfDayBinding (final BindingGroup bindings) {
 197  0
                 Binding binding = Bindings.createAutoBinding(
 198  
                         UpdateStrategy.READ_WRITE,
 199  
                         this.model,
 200  
                         BeanProperty.create("timeOfDay"),
 201  
                         this.timeField,
 202  
                         BeanProperty.create("text_ON_ACTION_OR_FOCUS_LOST")
 203  
                 );
 204  0
                 binding.setConverter(new TimeOfDayConverter());
 205  0
                 binding.addBindingListener(new TimeOfDayBindingListener());
 206  0
                 bindings.addBinding(binding);
 207  0
         }
 208  
 
 209  
         /**
 210  
          * Returns the selected date as a time stamp.
 211  
          * @return the selected date as a time stamp.
 212  
          * @since 0.3.0
 213  
          */
 214  
         public TimeStamp getTimeStamp () {
 215  0
                 return this.timeStamp;
 216  
         }
 217  
 
 218  
         /**
 219  
          * Selects a time stamp.
 220  
          * @param timeStamp the time stamp to select.
 221  
          * @since 0.3.0
 222  
          */
 223  
         public void setTimeStamp (TimeStamp timeStamp) {
 224  0
                 final TimeStamp old = this.timeStamp;
 225  0
                 this.timeStamp = timeStamp;
 226  0
                 firePropertyChange("timeStamp", old, timeStamp);
 227  
 
 228  0
                 this.datePicker.setDate(timeStamp.getDate());
 229  0
                 this.datePicker.setTimeZone(timeStamp.getTimeZone());
 230  0
         }
 231  
 
 232  
 }