/** * Copyright (C) 2015 Valkyrie RCP * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.valkyriercp.form.binding.swing; import org.valkyriercp.binding.form.FormModel; import org.valkyriercp.form.binding.Binding; import org.valkyriercp.form.binding.support.AbstractBinder; import javax.swing.*; import java.util.*; /** * Binder to configure {@link StringSelectionListBinding}. * * @author jh * */ public class StringSelectionListBinder extends AbstractBinder { /** * Constant to use when having a combobox mapped to a {@link Boolean} which * needs three state logic. */ public static final Collection TRUE_FALSE_NULL = Arrays.asList(new Object[]{Boolean.TRUE, Boolean.FALSE, null}); public static final String LABELS_KEY = "labels"; public static final String LABEL_ID_KEY = "labelId"; public static final String KEYS_KEY = "keys"; public static final String DEFAULT_KEY_INDEX_KEY = "defaultKeyIndex"; public static final String ADD_NULL_KEY = "addNull"; private String labelId = null; private Collection keys = null; private Collection labels = null; private int defaultKeyIndex = -1; private boolean addNull = false; /** * * @param addNull indien deze waarde op true staat, dan wordt null aan de selectiemogelijkheden toegevoegd. * Wordt deze voor de labels en keys geplaatst, dan komt deze eerst, anders laatst. */ public void setAddNull(boolean addNull) { this.addNull = addNull; if (addNull && labels != null && keys == null) throw new IllegalStateException("Keys should be defined before labels!"); // indien keys reeds gezet zijn (dus null moet achteraan toegevoegd worden if (addNull && keys != null) { keys.add(null); // eventueel aan labels toevoegen if (labels != null) labels.add(null); } } public StringSelectionListBinder() { super(null, new String[] {KEYS_KEY, LABELS_KEY, LABEL_ID_KEY, DEFAULT_KEY_INDEX_KEY, ADD_NULL_KEY}); } public void setLabelId(String labelId) { this.labelId = labelId; } protected String getLabelId() { return labelId; } @Override protected JComponent createControl(Map context) { return new JComboBox(); } public void setLabels(Collection labels) { if (addNull) { this.labels = new ArrayList(); this.labels.add(null); this.labels.addAll(labels); } else { this.labels = labels; } } protected Collection getLabels() { return labels; } public void setKeys(Collection keys) { if (addNull) { this.keys = new ArrayList(); this.keys.add(null); this.keys.addAll(keys); } else { this.keys = keys; } } protected Collection getKeys() { return keys; } public void setMap(Map map) { List<Map.Entry> mapEntries = sortMapEntriesOnValues(map); setKeys(new ArrayList()); setLabels(new ArrayList()); extractListFromMapEntries(mapEntries, (List) keys, (List) labels); } private void extractListFromMapEntries(List<Map.Entry> mapEntries, List keys, List values) { for (Map.Entry mapEntry : mapEntries) { keys.add(mapEntry.getKey()); keys.add(mapEntry.getValue()); } } private List<Map.Entry> sortMapEntriesOnValues(Map map) { Set<Map.Entry> entrySet = map.entrySet(); ArrayList<Map.Entry> entries = new ArrayList<Map.Entry>(entrySet); Collections.sort(entries, new MapEntryValueComparator()); return entries; } public static class MapEntryValueComparator implements Comparator<Map.Entry> { public int compare(Map.Entry entryLeft, Map.Entry entryRight) { return ((Comparable) entryLeft.getValue()).compareTo(entryRight.getValue()); } } public void setSubSetOfMap(Collection sortedKeys, Map map) { setKeys(sortedKeys); setLabels(StringSelectionListBinding.getLabelsFromMap(sortedKeys, map)); } public void setDefaultKeyIndex(int defaultKeyIndex) { this.defaultKeyIndex = defaultKeyIndex; } @Override protected Binding doBind(JComponent component, FormModel formModel, String formPropertyPath, Map context) { String labelId = null; Collection keys = null; Collection labels = null; int defaultKeyIndex = -1; boolean addNull = false; if(context.containsKey(LABEL_ID_KEY)) { labelId = (String) context.get(LABEL_ID_KEY); } else { labelId = this.labelId; } if(context.containsKey(KEYS_KEY)) { keys = (Collection) context.get(KEYS_KEY); if(context.containsKey(ADD_NULL_KEY) || (Boolean) context.get(ADD_NULL_KEY)) keys.add(null); else if(!context.containsKey(ADD_NULL_KEY) || addNull) keys.add(null); } else { keys = this.keys; } if(context.containsKey(LABELS_KEY)) { labels = (Collection) context.get(LABELS_KEY); if(context.containsKey(ADD_NULL_KEY) || (Boolean) context.get(ADD_NULL_KEY)) labels.add(null); else if(!context.containsKey(ADD_NULL_KEY) || addNull) labels.add(null); } else { labels = this.labels; } if(context.containsKey(DEFAULT_KEY_INDEX_KEY)) { defaultKeyIndex = (Integer) context.get(DEFAULT_KEY_INDEX_KEY); } else { defaultKeyIndex = this.defaultKeyIndex; } StringSelectionListBinding stringSelectionListBinding = new StringSelectionListBinding( (JComboBox) component, formModel, formPropertyPath, isReadOnly()); stringSelectionListBinding.setId(labelId); stringSelectionListBinding.setDefaultKeyIndex(defaultKeyIndex); if (keys != null) stringSelectionListBinding.setSelectionList(keys, labels == null ? keys : labels); return stringSelectionListBinding; } }