1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.ui.field.factory;
35
36 import info.magnolia.i18nsystem.SimpleTranslator;
37 import info.magnolia.icons.MagnoliaIcons;
38
39 import java.util.ArrayList;
40 import java.util.Collection;
41 import java.util.List;
42 import java.util.stream.Collectors;
43 import java.util.stream.Stream;
44
45 import com.explicatis.ext_token_field.ExtTokenField;
46 import com.explicatis.ext_token_field.SimpleTokenizable;
47 import com.explicatis.ext_token_field.Tokenizable;
48 import com.vaadin.shared.Registration;
49 import com.vaadin.ui.Button;
50 import com.vaadin.ui.ComboBox;
51 import com.vaadin.ui.Component;
52 import com.vaadin.ui.CustomField;
53 import com.vaadin.ui.HorizontalLayout;
54
55 import lombok.RequiredArgsConstructor;
56
57
58
59
60
61
62
63 @RequiredArgsConstructor
64 public class TokenFieldWrapper<T> extends CustomField<Collection<String>> {
65
66 private final TokenField tokenField = new TokenField();
67 private final ComboBox<T> comboBox;
68 private final SimpleTranslator translator;
69 private Button removeAllTokensBtn;
70
71 @Override
72 public Collection<String> getValue() {
73 return tokenField.getValue().stream()
74 .map(Tokenizable::getStringValue)
75 .collect(Collectors.toList());
76 }
77
78
79 @Override
80 protected void doSetValue(Collection<String> strings) {
81 if (strings == null) {
82 tokenField.doSetValue(new ArrayList<>());
83 } else {
84 tokenField.doSetValue(toTokenizables(strings.stream()));
85 }
86 }
87
88 @Override
89 protected Component initContent() {
90 HorizontalLayout horizontalLayout = new HorizontalLayout();
91 horizontalLayout.setSpacing(false);
92 horizontalLayout.setStyleName("token-field-horizontal-layout");
93 comboBox.addValueChangeListener((ValueChangeListener<T>) event -> {
94 if (event.getValue() != null) {
95
96 tokenField.addTokenizable(new ToStringTokenizable(comboBox.getItemCaptionGenerator().apply(event.getValue())));
97 event.getSource().setValue(null);
98 }
99 });
100 comboBox.setItemIconGenerator(item -> null);
101 tokenField.setTokenDragDropEnabled(true);
102 tokenField.setEnableDefaultDeleteTokenAction(true);
103 tokenField.setInputField(comboBox);
104 horizontalLayout.addComponent(tokenField);
105 removeAllTokensBtn = new Button(MagnoliaIcons.CLOSE);
106 removeAllTokensBtn.setDescription(translator.translate("fields.tokenField.remove.removeAllItems"));
107 removeAllTokensBtn.addStyleName("remove-all-tokens-button");
108 removeAllTokensBtn.addClickListener((event) -> {
109 tokenField.doSetValue(new ArrayList<>());
110 });
111 horizontalLayout.addComponent(removeAllTokensBtn);
112 return horizontalLayout;
113 }
114
115 @Override
116 public Registration addValueChangeListener(ValueChangeListener listener) {
117 tokenField.addValueChangeListener(listener);
118 return super.addValueChangeListener(listener);
119 }
120
121 @Override
122 public void setReadOnly(boolean readOnly) {
123 super.setReadOnly(readOnly);
124 tokenField.setReadOnly(readOnly);
125 }
126
127 private List<Tokenizable> toTokenizables(Stream<?> strings) {
128 return strings
129 .map(ToStringTokenizable::new)
130 .collect(Collectors.toList());
131 }
132
133 private static class ToStringTokenizable extends SimpleTokenizable {
134
135 private ToStringTokenizable(Object stringValue) {
136 super(stringValue.hashCode(), String.valueOf(stringValue));
137 }
138
139 @Override
140 public String toString() {
141 return getStringValue();
142 }
143 }
144
145 private static class TokenField extends ExtTokenField {
146
147 @Override
148 protected void doSetValue(List<Tokenizable> value) {
149 super.doSetValue(value);
150 }
151 }
152 }