Project

General

Profile

Download (8.11 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 abstract class AbstractTimePeriodField<T extends TimePeriod> extends CustomField<T> {
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 AbstractTimePeriodField() {
75
        super();
76

    
77
    }
78

    
79
    /**
80
     * @param string
81
     */
82
    public AbstractTimePeriodField(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(T newValue) {
228
        if(newValue == null){
229
            newValue = newModelInstance();
230
        }
231
        super.setInternalValue(newValue);
232
            fieldGroup.setItemDataSource(new BeanItem<TimePeriod>(newValue));
233
        updateCacheField();
234
    }
235

    
236
    /**
237
     * @return
238
     */
239
    protected abstract T newModelInstance();
240

    
241
    /**
242
     * @param newValue
243
     */
244
    private void updateCacheField() {
245
        TimePeriod newValue = fieldGroup.getItemDataSource().getBean();
246
        cacheField.setReadOnly(false);
247
        cacheField.setValue(timePeriodFormatter.print(newValue));
248
        cacheField.setReadOnly(true);
249
    }
250

    
251
    @Override
252
    public void setStyleName(String style) {
253
        super.setStyleName(style);
254
        grid.iterator().forEachRemaining(c -> c.setStyleName(style));
255
        buttonTextField.iterator().forEachRemaining(c -> c.setStyleName(style));
256
        simpleView.iterator().forEachRemaining(c -> c.setStyleName(style));
257
        applyDefaultStyles();
258
    }
259

    
260
    @Override
261
    public void addStyleName(String style) {
262
        super.addStyleName(style);
263
        grid.iterator().forEachRemaining(c -> c.addStyleName(style));
264
        simpleView.iterator().forEachRemaining(c -> {
265
            c.addStyleName(style);
266
        });
267

    
268
        buttonTextField.iterator().forEachRemaining(c -> c.addStyleName(style));
269
    }
270

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

    
284

    
285

    
286

    
287

    
288
}
(1-1/7)