package au.com.vaadinutils.layout; import java.text.DateFormatSymbols; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collection; import java.util.Date; import java.util.LinkedList; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import com.vaadin.data.Property; import com.vaadin.data.Validator; import com.vaadin.data.Validator.InvalidValueException; import com.vaadin.server.FontAwesome; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.CssLayout; import com.vaadin.ui.Field; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.NativeButton; import com.vaadin.ui.Notification; import com.vaadin.ui.Notification.Type; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.Reindeer; @SuppressWarnings("rawtypes") public class TimePicker24 extends HorizontalLayout implements Field { Logger logger = LogManager.getLogger(); protected static final String TIME_FORMAT = "HH:mm a"; protected static final String TIME_FORMAT2 = "HH:mma"; private static final String PM = "pm"; private static final String AM = "am"; private static final long serialVersionUID = 1826417125815798837L; private static final String EMPTY = "--:--"; String headerColor = "#B2D7FF"; final private TextField displayTime = new TextField(); String hour = "12"; String minute = "00"; boolean isSet = false; // private Button zeroHourButton; // private Button zeroMinuteButton; private String title; private TextField field; private Property<Date> datasource; // private boolean isRequired; private String requiredErrorMessage; private int tabIndex; private boolean isBuffered; private Validator validator; private SimpleDateFormat sdf; private String amPm; private Button pickerButton; public TimePicker24(String title, String format) { sdf = new SimpleDateFormat(format); DateFormatSymbols symbols = new DateFormatSymbols(); symbols.setAmPmStrings(new String[] { AM, PM }); sdf.setDateFormatSymbols(symbols); setCaption(title); field = new TextField(); field.setWidth("125"); field.setImmediate(true); displayTime.setImmediate(true); validator = new Validator() { private static final long serialVersionUID = 6579163030027373837L; @Override public void validate(Object value) throws InvalidValueException { if (value == null || value.equals(EMPTY)) { return; } try { sdf.parse((String) value); } catch (ParseException e) { throw new InvalidValueException("Invalid time" + value); } } }; displayTime.addValidator(validator); field.addValidator(validator); field.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 1L; @Override public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) { if (event.getProperty().getValue() != null) { try { final Date parsedDate = parseDate((String) event.getProperty().getValue()); if (parsedDate != null) { setValue(parsedDate); } } catch (InvalidValueException e) { Notification.show(e.getMessage(), Type.ERROR_MESSAGE); } } } }); this.title = title; CssLayout hl = new CssLayout(); hl.addStyleName("v-component-group"); hl.setWidth("100%"); hl.setHeight("35"); pickerButton = new Button(); pickerButton.setIcon(FontAwesome.CLOCK_O); hl.addComponent(field); hl.addComponent(pickerButton); pickerButton.addClickListener(new ClickListener() { private static final long serialVersionUID = 1L; @Override public void buttonClick(ClickEvent event) { showPopupTimePicker(); } }); addComponent(hl); } protected Date parseDate(String value) { if (value == null || value.equals(EMPTY)) { return null; } SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT); try { return sdf.parse(value); } catch (ParseException e) { sdf = new SimpleDateFormat(TIME_FORMAT2); try { return sdf.parse(value); } catch (ParseException e2) { throw new InvalidValueException("Time format is " + TIME_FORMAT); } } } @Override public void setReadOnly(boolean readOnly) { pickerButton.setReadOnly(true); } public void focus() { super.focus(); } private void showPopupTimePicker() { String value = field.getValue(); try { String[] parts = value.split(":"); hour = parts[0]; String[] np = parts[1].split(" "); minute = np[0]; displayTime.setValue(value); } catch (Exception e) { clearValue(); } final Window window = new Window(title); window.setModal(true); window.setResizable(false); window.setWidth("430"); window.setHeight("240"); window.setClosable(false); HorizontalLayout layout = new HorizontalLayout(); layout.setSizeFull(); layout.setMargin(true); layout.setSpacing(true); layout.setStyleName(Reindeer.BUTTON_SMALL); displayTime.setWidth("100"); VerticalLayout hourPanelLabelWrapper = new VerticalLayout(); Label hourLabel = new Label("Hour"); // hourLabel.setBackgroundColor(headerColor); hourLabel.setWidth("230"); // hourLabel.setHeight("30"); // hourLabel.setAutoFit(false); HorizontalLayout innerHourLabelPanel = new HorizontalLayout(); // innerHourLabelPanel.setPadding(5); innerHourLabelPanel.addComponent(hourLabel); innerHourLabelPanel.setWidth("100"); // innerHourLabelPanel.setHeight("30"); hourPanelLabelWrapper.addComponent(innerHourLabelPanel); VerticalLayout minuteLabelWrapper = new VerticalLayout(); minuteLabelWrapper.setWidth("60"); Label minuteLabel = new Label("Minute"); // minuteLabel.setBackgroundColor(headerColor); // minuteLabel.setStyleName("njadmin-search-colour"); minuteLabel.setWidth("45"); // minuteLabel.setHeight("30"); // minuteLabel.setAutoFit(false); VerticalLayout innerMinuteLabelPanel = new VerticalLayout(); // innerMinuteLabelPanel.setPadding(5); innerMinuteLabelPanel.addComponent(minuteLabel); innerMinuteLabelPanel.setWidth("45"); // innerMinuteLabelPanel.setHeight("30"); minuteLabelWrapper.addComponent(innerMinuteLabelPanel); HorizontalLayout hourPanel = new HorizontalLayout(); // hourPanel.setPadding(5); HorizontalLayout hourButtonPanel = new HorizontalLayout(); hourPanel.addComponent(hourButtonPanel); addHourButtons(hourButtonPanel, 3, 8); HorizontalLayout minutePanel = new HorizontalLayout(); // minutePanel.setPadding(5); HorizontalLayout minuteButtonPanel = new HorizontalLayout(); minutePanel.addComponent(minuteButtonPanel); addMinuteButtons(minuteButtonPanel, 2, 4); HorizontalLayout amPmHourWrapper = new HorizontalLayout(); amPmHourWrapper.addComponent(hourPanel); hourPanelLabelWrapper.addComponent(amPmHourWrapper); layout.addComponent(hourPanelLabelWrapper); minuteLabelWrapper.addComponent(minutePanel); layout.addComponent(minuteLabelWrapper); layout.setExpandRatio(hourPanelLabelWrapper, 0.7f); layout.setExpandRatio(minuteLabelWrapper, 0.3f); HorizontalLayout okcancel = new HorizontalLayout(); okcancel.setSizeFull(); Button ok = new Button("OK"); ok.setWidth("75"); ok.addClickListener(new ClickListener() { /** * */ private static final long serialVersionUID = 1L; @Override public void buttonClick(ClickEvent event) { try { displayTime.validate(); if (displayTime.getValue().equals(EMPTY)) { field.setValue(""); } else { field.setValue(displayTime.getValue()); } window.close(); } catch (InvalidValueException e) { } } }); Button cancel = new Button("Cancel"); cancel.setWidth("75"); cancel.addClickListener(new ClickListener() { /** * */ private static final long serialVersionUID = 1L; @Override public void buttonClick(ClickEvent event) { window.close(); } }); okcancel.addComponent(displayTime); okcancel.addComponent(cancel); okcancel.addComponent(ok); okcancel.setMargin(true); okcancel.setSpacing(true); okcancel.setExpandRatio(displayTime, 0.50f); // okcancel.setExpandRatio(ok, 0.25f); // okcancel.setExpandRatio(cancel, 0.25f); VerticalLayout wrapper = new VerticalLayout(); // wrapper.setStyleName("njadmin-search-colour"); wrapper.setSizeFull(); wrapper.addComponent(layout); wrapper.addComponent(okcancel); wrapper.setExpandRatio(layout, 0.9f); wrapper.setExpandRatio(okcancel, 0.5f); window.setContent(wrapper); UI.getCurrent().addWindow(window); } private void addMinuteButtons(HorizontalLayout minuteButtonPanel, int rows, int cols) { String[] numbers = new String[] { "00", "10", "15", "20", "30", "40", "45", "50" }; for (int col = 0; col < cols; col++) { VerticalLayout rowsLayout = new VerticalLayout(); for (int row = 0; row < rows; row++) { final NativeButton button = new NativeButton("" + numbers[row + (col * rows)]); rowsLayout.addComponent(button); button.setStyleName(Reindeer.BUTTON_SMALL); button.setWidth("30"); // button.setHeight("30"); // button.setAutoFit(false); // button.setActionType(SelectionType.RADIO); // button.addToRadioGroup("minuteButtons"); // if (row == 0 && col == 0) // { // zeroMinuteButton = button; // // } button.addClickListener(new ClickListener() { /** * */ private static final long serialVersionUID = 1L; @Override public void buttonClick(ClickEvent event) { String title = button.getCaption(); minute = title; isSet = true; setNewValue(); } }); } minuteButtonPanel.addComponent(rowsLayout); } } private void addHourButtons(HorizontalLayout hourButtonPanel, int rows, int cols) { int[] numbers = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23 }; for (int col = 0; col < cols; col++) { VerticalLayout rowsLayout = new VerticalLayout(); for (int row = 0; row < rows; row++) { final NativeButton button = new NativeButton("" + numbers[col + (row * cols)]); rowsLayout.addComponent(button); button.setStyleName(Reindeer.BUTTON_SMALL); button.setWidth("30"); // button.setHeight("15"); // button.setAutoFit(false); // button.setActionType(SelectionType.RADIO); // button.addToRadioGroup("hourButtons"); // if (row == 0 && col == 0) // { // zeroHourButton = button; // // } button.addClickListener(new ClickListener() { /** * */ private static final long serialVersionUID = 1L; @Override public void buttonClick(ClickEvent event) { String title = button.getCaption(); hour = title; isSet = true; amPm = AM; if (Integer.parseInt(hour) > 11) { amPm = PM; } setNewValue(); } }); } hourButtonPanel.addComponent(rowsLayout); } } // public void addChangedHandler(ChangedHandler pChangedHandler) // { // this.changedHandler = pChangedHandler; // // } public void clearValue() { // am.setSelected(true); // am.setSelected(false); // zeroHourButton.setSelected(true); // zeroHourButton.setSelected(false); // zeroMinuteButton.setSelected(true); // zeroMinuteButton.setSelected(false); hour = "12"; minute = "00"; isSet = false; displayTime.setValue(EMPTY); field.setValue(EMPTY); } public final String getValueAsString() { if (isSet) { String tmp = "" + hour + ":" + minute + amPm; Date date; try { date = sdf.parse(tmp); return sdf.format(date); } catch (ParseException e) { } return tmp; } return null; } @SuppressWarnings("deprecation") public void setValues(Date date) { hour = "" + date.getHours(); minute = "" + date.getMinutes(); if (date.getMinutes() < 10) { minute = "0" + minute; } amPm = AM; if (Integer.parseInt(hour) > 11) { amPm = PM; } isSet = true; displayTime.setValue(getValueAsString()); field.setValue(getValueAsString()); // logger.info("set to " + getValueAsString()); } private void setNewValue() { displayTime.setValue(getValueAsString()); } @Override public boolean isInvalidCommitted() { return false; } @Override public void setInvalidCommitted(boolean isCommitted) { } @Override public void commit() throws SourceException, InvalidValueException { datasource.setValue((Date) getValue()); } @Override public void discard() throws SourceException { setValues(datasource.getValue()); } @Override public void setBuffered(boolean buffered) { this.isBuffered = buffered; } @Override public boolean isBuffered() { return isBuffered; } @Override public boolean isModified() { Date value = (Date) getValue(); if (datasource == null) { return false; } Date dsValue = datasource.getValue(); if (dsValue == null) { return value != null; } if (value == null) { return true; } return !dsValue.equals(value); } @Override public void addValidator(Validator validator) { } @Override public void removeValidator(Validator validator) { } @Override public void removeAllValidators() { } @Override public Collection<Validator> getValidators() { Collection<Validator> validators = new LinkedList<Validator>(); validators.add(validator); return validators; } @Override public boolean isValid() { boolean valid = true; try { validator.validate(getValueAsString()); } catch (Exception e) { valid = false; } return valid; } @Override public void validate() throws InvalidValueException { validator.validate(getValueAsString()); } @Override public boolean isInvalidAllowed() { return false; } @Override public void setInvalidAllowed(boolean invalidValueAllowed) throws UnsupportedOperationException { } @Override public Object getValue() { try { if (getValueAsString() == null) { return null; } return sdf.parse(getValueAsString()); } catch (ParseException e) { throw new RuntimeException(e); } } @Override public void setValue(Object newValue) { setValues((Date) newValue); } @Override public Class getType() { return Date.class; } @Override public void addValueChangeListener(ValueChangeListener listener) { } @Override public void addListener(ValueChangeListener listener) { } @Override public void removeValueChangeListener(ValueChangeListener listener) { } @Override public void removeListener(ValueChangeListener listener) { } @Override public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) { logger.info("Value change"); } @SuppressWarnings("unchecked") @Override public void setPropertyDataSource(Property newDataSource) { clearValue(); datasource = newDataSource; if (datasource.getValue() != null) { setValues(datasource.getValue()); } } @Override public Property<Date> getPropertyDataSource() { return datasource; } @Override public int getTabIndex() { return tabIndex; } @Override public void setTabIndex(int tabIndex) { this.tabIndex = tabIndex; } @Override public boolean isRequired() { return isVisible(); } @Override public void setRequired(boolean required) { // isRequired = required; } @Override public void setRequiredError(String requiredMessage) { requiredErrorMessage = requiredMessage; } @Override public String getRequiredError() { return requiredErrorMessage; } @Override public boolean isEmpty() { // TODO Auto-generated method stub return false; } @Override public void clear() { // TODO Auto-generated method stub } }