Java tutorial
/* * Copyright 2013 Corpuslinguistic working group Humboldt University Berlin. * * 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 annis.gui.flatquerybuilder; import annis.libgui.Helper; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.shared.ui.combobox.FilteringMode; import com.vaadin.ui.AbstractSelect.ItemCaptionMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Panel; import com.vaadin.ui.themes.ChameleonTheme; import java.text.Normalizer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListMap; import java.util.concurrent.ConcurrentSkipListSet; import org.apache.commons.lang3.StringUtils; /** * * @author Martin */ public class ValueField extends Panel implements TextChangeListener, Button.ClickListener { /*BASIC ELEMENTS*/ private HorizontalLayout frame; private SensitiveComboBox scb; private Button bt; /*ADDITIONAL ATTRIBUTES*/ private FlatQueryBuilder sq; private String level; private SearchBox sb; private ConcurrentSkipListMap<String, String> values; private ValueMode vm; /*LABELS AND STRINGS*/ private static final String BUTTON_LABEL_REMOVE = "X"; private static final String SCB_STYLE_NAME = Helper.CORPUS_FONT_FORCE; private static final String SCB_WIDTH = "130px"; public ValueField(FlatQueryBuilder sq, SearchBox sb, String level) { /*INIT VALUES*/ this.sq = sq; this.sb = sb; this.level = level; vm = (sb.isRegEx()) ? ValueMode.REGEX : ValueMode.NORMAL; values = new ConcurrentSkipListMap<>(); for (String v : sq.getAvailableAnnotationLevels(level)) { values.put(v, sq.escapeRegexCharacters(v)); } /*SENSITIVE COMBOBOX*/ scb = new SensitiveComboBox(); scb.setImmediate(true); scb.setNewItemsAllowed(true); scb.setTextInputAllowed(true); scb.setFilteringMode(FilteringMode.OFF); scb.addListener((TextChangeListener) this); scb.setItemCaptionMode(ItemCaptionMode.ID); buildValues(vm); scb.addStyleName(SCB_STYLE_NAME); scb.setWidth(SCB_WIDTH); /*BUTTON*/ bt = new Button(BUTTON_LABEL_REMOVE); bt.addClickListener((Button.ClickListener) this); bt.setStyleName(ChameleonTheme.BUTTON_SMALL); /*HORIZONTAL LAYOUT*/ frame = new HorizontalLayout(); frame.setSpacing(true);//used to be true frame.setCaption(level); /*VISUALIZE*/ frame.addComponent(scb); frame.addComponent(bt); frame.setComponentAlignment(bt, Alignment.BOTTOM_RIGHT); setContent(frame); } @Deprecated /*ever seen this? ^^ just wrote it and it's already deprecated*/ public ValueField(FlatQueryBuilder sq, SearchBox sb, String level, String value) { this(sq, sb, level); scb.setValue(value); } @Override public void buttonClick(Button.ClickEvent event) { if (event.getButton() == bt) { sb.removeValueField(this); } } @Override public void textChange(TextChangeEvent event) { ReducingStringComparator rsc = sq.getRSC(); String fm = sq.getFilterMechanism(); if (!"generic".equals(fm)) { ConcurrentSkipListSet<String> notInYet = new ConcurrentSkipListSet<>(); String txt = event.getText(); if (!txt.equals("")) { scb.removeAllItems(); for (Iterator<String> it = values.keySet().iterator(); it.hasNext();) { String s = it.next(); if (rsc.compare(s, txt, fm) == 0) { scb.addItem(s); } else { notInYet.add(s); } } //startsWith for (String s : notInYet) { if (rsc.startsWith(s, txt, fm)) { scb.addItem(s); notInYet.remove(s); } } //contains for (String s : notInYet) { if (rsc.contains(s, txt, fm)) { scb.addItem(s); } } } else { buildValues(this.vm); } } else { String txt = event.getText(); HashMap<Integer, Collection> levdistvals = new HashMap<>(); if (txt.length() > 1) { scb.removeAllItems(); for (String s : values.keySet()) { Integer d = StringUtils.getLevenshteinDistance(removeAccents(txt).toLowerCase(), removeAccents(s).toLowerCase()); if (levdistvals.containsKey(d)) { levdistvals.get(d).add(s); } if (!levdistvals.containsKey(d)) { Set<String> newc = new TreeSet<>(); newc.add(s); levdistvals.put(d, newc); } } SortedSet<Integer> keys = new TreeSet<>(levdistvals.keySet()); for (Integer k : keys.subSet(0, 10)) { List<String> valueList = new ArrayList(levdistvals.get(k)); Collections.sort(valueList, String.CASE_INSENSITIVE_ORDER); for (String v : valueList) { scb.addItem(v); } } } } } public String getValue() { return (String) scb.getValue(); /*ATTENTION: scb.getValue().toString() causes NullPointerException*/ } public void setValue(String value) { if ((vm.equals(ValueMode.REGEX)) && (!scb.containsId(value))) { scb.addItem(value); scb.setItemCaption(value, value + " (user defined)"); } scb.setValue(value); } public boolean isRegex() { return (vm == ValueMode.REGEX); } public void setValueMode(ValueMode vm) { if (!vm.equals(this.vm)) { buildValues(vm); } } private void buildValues(ValueMode vm) { this.vm = vm; if (vm.equals(ValueMode.REGEX)) { scb.removeAllItems(); //scb.setItemCaptionMode(ItemCaptionMode.EXPLICIT); for (String v : values.keySet()) { String item = values.get(v); //String itemCaption = v; scb.addItem(item); //scb.setItemCaption(item, itemCaption); } } else { scb.removeAllItems(); scb.setItemCaptionMode(ItemCaptionMode.ID); for (String v : values.keySet()) { scb.addItem(v); } } } public Button getButton() { return bt; } public SensitiveComboBox getSCB() { return scb; } public static String removeAccents(String text) { return text == null ? null : Normalizer.normalize(text, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); } public void setProtected(boolean p) { bt.setVisible(!p); } public enum ValueMode { NORMAL, REGEX; } }