Project

General

Profile

Download (8.14 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2017 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.vaadin.component.common;
10

    
11
import java.util.HashSet;
12
import java.util.Set;
13

    
14
import com.vaadin.data.Validator.InvalidValueException;
15
import com.vaadin.data.fieldgroup.BeanFieldGroup;
16
import com.vaadin.data.fieldgroup.FieldGroup.CommitException;
17
import com.vaadin.data.util.BeanItem;
18
import com.vaadin.event.FieldEvents.TextChangeEvent;
19
import com.vaadin.server.FontAwesome;
20
import com.vaadin.ui.Alignment;
21
import com.vaadin.ui.Button;
22
import com.vaadin.ui.Component;
23
import com.vaadin.ui.CssLayout;
24
import com.vaadin.ui.CustomField;
25
import com.vaadin.ui.GridLayout;
26
import com.vaadin.ui.Label;
27
import com.vaadin.ui.TextField;
28
import com.vaadin.ui.themes.ValoTheme;
29

    
30
import eu.etaxonomy.cdm.model.common.TimePeriod;
31
import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
32
import eu.etaxonomy.cdm.vaadin.component.PartialDateField;
33
import eu.etaxonomy.cdm.vaadin.component.TextFieldNFix;
34
import eu.etaxonomy.cdm.vaadin.component.registration.RegistrationStyles;
35
import eu.etaxonomy.cdm.vaadin.util.formatter.DateTimeFormat;
36
import eu.etaxonomy.cdm.vaadin.util.formatter.TimePeriodFormatter;
37

    
38
/**
39
 * @author a.kohlbecker
40
 * @since Apr 6, 2017
41
 *
42
 */
43
public class TimePeriodField extends CustomField<TimePeriod> {
44

    
45
    private static final long serialVersionUID = -7377778547595966252L;
46

    
47
    private static final String PRIMARY_STYLE = "v-time-period-field";
48

    
49
    private BeanFieldGroup<TimePeriod> fieldGroup = new BeanFieldGroup<>(TimePeriod.class);
50

    
51
    TextField parseField = null;
52

    
53
    TextField freeText = null;
54

    
55
    Label toLabel = null;
56

    
57
    GridLayout grid = new GridLayout(3, 4);
58

    
59
    CssLayout detailsView = new CssLayout();
60

    
61
    //TODO implement custom button textfield which does not require a gridLayout
62
    GridLayout buttonTextField = new GridLayout(2, 1);
63
    GridLayout simpleView = new GridLayout(2, 1);
64

    
65
    TextField cacheField = new TextFieldNFix();
66

    
67
    Set<Component> styledComponents = new HashSet<>();
68

    
69
    private TimePeriodFormatter timePeriodFormatter = new TimePeriodFormatter(DateTimeFormat.ISO8601_DATE);
70

    
71
    /**
72
     *
73
     */
74
    public TimePeriodField() {
75
        super();
76

    
77
    }
78

    
79
    /**
80
     * @param string
81
     */
82
    public TimePeriodField(String string) {
83
        this();
84
        setCaption(string);
85
    }
86

    
87
    /**
88
     * {@inheritDoc}
89
     */
90
    @Override
91
    protected Component initContent() {
92

    
93
        super.setPrimaryStyleName(PRIMARY_STYLE);
94

    
95
        CssLayout root = new CssLayout();
96

    
97
        initSimpleView();
98
        initDetailsView();
99

    
100
        root.addComponent(simpleView);
101
        root.addComponent(detailsView);
102

    
103
        applyDefaultStyles();
104

    
105
        showSimple();
106

    
107
        return root;
108
    }
109

    
110
    /**
111
     *
112
     */
113
    private void initSimpleView() {
114

    
115
        Button showDetailsButton = new Button(FontAwesome.CALENDAR);
116
        showDetailsButton.addClickListener(e -> showDetails());
117
        cacheField.setWidth(353, Unit.PIXELS); // FIXME 100% does not work
118

    
119
        simpleView.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
120
        simpleView.setWidth(100, Unit.PERCENTAGE);
121
        simpleView.addComponent(showDetailsButton, 0, 0);
122
        simpleView.addComponent(cacheField, 1, 0);
123
        simpleView.setColumnExpandRatio(1, 0.9f);
124
    }
125

    
126
    /**
127
     *
128
     */
129
    private void initDetailsView() {
130

    
131
        parseField = new TextFieldNFix();
132
        // parseField.setWidth(100, Unit.PERCENTAGE);
133
        parseField.setInputPrompt("This field will parse the entered time period");
134
        parseField.addTextChangeListener(e -> parseInput(e));
135
        parseField.setWidth(100, Unit.PERCENTAGE);
136

    
137
        Button closeDetailsButton = new Button(FontAwesome.CLOSE);
138
        closeDetailsButton.addClickListener(e -> {
139
            try {
140
                fieldGroup.commit();
141
            } catch (CommitException e1) {
142
                // TODO Auto-generated catch block
143
                e1.printStackTrace();
144
            }
145
            updateCacheField();
146
            showSimple();
147
        });
148

    
149
        buttonTextField.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
150
        buttonTextField.setWidth(100, Unit.PERCENTAGE);
151
        buttonTextField.addComponent(closeDetailsButton, 0, 0);
152
        buttonTextField.addComponent(parseField, 1, 0);
153
        buttonTextField.setColumnExpandRatio(1, 1.0f);
154

    
155
        PartialDateField startDate = new PartialDateField("Start");
156
        startDate.setInputPrompt("dd.mm.yyyy");
157
        PartialDateField endDate = new PartialDateField("End");
158
        endDate.setInputPrompt("dd.mm.yyyy");
159
        freeText = new TextFieldNFix("FreeText");
160
        freeText.setWidth(100, Unit.PERCENTAGE);
161

    
162
        fieldGroup.bind(startDate, "start");
163
        fieldGroup.bind(endDate, "end");
164
        fieldGroup.bind(freeText, "freeText");
165

    
166
        toLabel = new Label("\u2014"); // EM DASH : 0x2014
167

    
168
        int row = 0;
169
        grid.addComponent(buttonTextField, 0, row, 2, row);
170
        row++;
171
        grid.addComponent(startDate, 0, row);
172
        grid.addComponent(toLabel, 1, row);
173
        grid.setComponentAlignment(toLabel, Alignment.BOTTOM_CENTER);
174
        grid.addComponent(endDate, 2, row);
175
        row++;
176
        grid.addComponent(freeText, 0, row, 2, row);
177

    
178
        // apply the style of the container to all child components. E.g. make all tiny
179
        addStyleName((getStyleName()));
180

    
181
        detailsView.setStyleName("margin-wrapper");
182
        detailsView.addComponent(grid);
183

    
184
    }
185

    
186

    
187
    /**
188
     * @return
189
     */
190
    private void showSimple() {
191
        detailsView.setVisible(false);
192
        simpleView.setVisible(true);
193
    }
194

    
195
    /**
196
     * @return
197
     */
198
    private void showDetails() {
199
        detailsView.setVisible(true);
200
        simpleView.setVisible(false);
201
    }
202

    
203
    /**
204
     * @param e
205
     * @return
206
     */
207
    private void parseInput(TextChangeEvent e) {
208
        if(!e.getText().isEmpty()){
209
            TimePeriod parsedPeriod = TimePeriodParser.parseString(e.getText());
210
            fieldGroup.setItemDataSource(new BeanItem<TimePeriod>(parsedPeriod));
211
        }
212
    }
213

    
214
    /**
215
     *
216
     */
217
    private void applyDefaultStyles() {
218
        if(parseField != null) {
219
            parseField.addStyleName(RegistrationStyles.HELPER_FIELD);
220
            toLabel.addStyleName("to-label");
221
            buttonTextField.addStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
222
        }
223

    
224
    }
225

    
226
    @Override
227
    protected void setInternalValue(TimePeriod newValue) {
228
        if(newValue == null){
229
            newValue = TimePeriod.NewInstance();
230
        }
231
        super.setInternalValue(newValue);
232
            fieldGroup.setItemDataSource(new BeanItem<TimePeriod>(newValue));
233
        updateCacheField();
234
    }
235

    
236
    /**
237
     * @param newValue
238
     */
239
    private void updateCacheField() {
240
        TimePeriod newValue = fieldGroup.getItemDataSource().getBean();
241
        cacheField.setReadOnly(false);
242
        cacheField.setValue(timePeriodFormatter.print(newValue));
243
        cacheField.setReadOnly(true);
244
    }
245

    
246
    @Override
247
    public void setStyleName(String style) {
248
        super.setStyleName(style);
249
        grid.iterator().forEachRemaining(c -> c.setStyleName(style));
250
        buttonTextField.iterator().forEachRemaining(c -> c.setStyleName(style));
251
        simpleView.iterator().forEachRemaining(c -> c.setStyleName(style));
252
        applyDefaultStyles();
253
    }
254

    
255
    @Override
256
    public void addStyleName(String style) {
257
        super.addStyleName(style);
258
        grid.iterator().forEachRemaining(c -> c.addStyleName(style));
259
        simpleView.iterator().forEachRemaining(c -> {
260
            c.addStyleName(style);
261
        });
262

    
263
        buttonTextField.iterator().forEachRemaining(c -> c.addStyleName(style));
264
    }
265

    
266
    /**
267
     * {@inheritDoc}
268
     */
269
    @Override
270
    public Class<? extends TimePeriod> getType() {
271
        return TimePeriod.class;
272
    }
273

    
274
    /**
275
     * {@inheritDoc}
276
     */
277
    @Override
278
    public void commit() throws SourceException, InvalidValueException {
279
        super.commit();
280
        try {
281
            fieldGroup.commit();
282
        } catch (CommitException e) {
283
            throw new RuntimeException(e);
284
        }
285
    }
286

    
287

    
288

    
289

    
290

    
291
}
(5-5/5)