Java tutorial
/* * Copyright 2012 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.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.event.FieldEvents; import com.vaadin.ui.AbstractSelect; import com.vaadin.ui.Button; import com.vaadin.ui.CheckBox; import com.vaadin.ui.ComboBox; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; 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.List; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import java.util.concurrent.ConcurrentSkipListSet; import org.apache.commons.lang3.StringUtils; /** * @author Tom * @author Martin */ public class SpanBox extends Panel implements Button.ClickListener, FieldEvents.TextChangeListener { private Button btClose; private String ebene; private HorizontalLayout sb; private SensitiveComboBox cb; private CheckBox reBox;//by Martin, tick for regular expression private Collection<String> annonames;//added by Martin, necessary for rebuilding the list of cb-Items private FlatQueryBuilder sq; public static final String BUTTON_CLOSE_LABEL = "Close"; private static final String SB_CB_WIDTH = "140px"; public SpanBox(final String ebene, final FlatQueryBuilder sq) { this(ebene, sq, false); } public SpanBox(final String ebene, final FlatQueryBuilder sq, boolean isRegex) { this.ebene = ebene; this.sq = sq; sb = new HorizontalLayout(); sb.setImmediate(true); sb.setSpacing(true); sb.setMargin(true); ConcurrentSkipListSet<String> annos = new ConcurrentSkipListSet<>(); for (String a : sq.getAvailableAnnotationLevels(ebene)) { annos.add(a); } this.annonames = annos; Label tf = new Label(ebene); sb.addComponent(tf); this.cb = new SensitiveComboBox(); cb.setWidth(SB_CB_WIDTH); cb.addStyleName(Helper.CORPUS_FONT_FORCE); // configure & load content cb.setImmediate(true); cb.setNewItemsAllowed(true); cb.setTextInputAllowed(true); for (String annoname : this.annonames) { cb.addItem(annoname); } cb.setFilteringMode(AbstractSelect.Filtering.FILTERINGMODE_OFF); cb.addListener((FieldEvents.TextChangeListener) this); sb.addComponent(cb); HorizontalLayout sbtoolbar = new HorizontalLayout(); sbtoolbar.setSpacing(true); // searchbox tickbox for regex CheckBox tb = new CheckBox("Regex"); tb.setImmediate(true); tb.setValue(isRegex); sbtoolbar.addComponent(tb); tb.addValueChangeListener(new ValueChangeListener() { // TODO make this into a nice subroutine @Override public void valueChange(ValueChangeEvent event) { boolean r = reBox.getValue(); if (!r) { SpanBox.buildBoxValues(cb, ebene, sq); } else if (cb.getValue() != null) { String escapedItem = sq.escapeRegexCharacters(cb.getValue().toString()); cb.addItem(escapedItem); cb.setValue(escapedItem); } } }); reBox = tb; // close the searchbox btClose = new Button(BUTTON_CLOSE_LABEL, (Button.ClickListener) this); btClose.setStyleName(ChameleonTheme.BUTTON_SMALL); sbtoolbar.addComponent(btClose); // make visable sb.addComponent(sbtoolbar); setContent(sb); } @Override public void buttonClick(Button.ClickEvent event) { // close functionality if (event.getButton() == btClose) { sb.removeComponent(cb); cb.setValue(""); sq.removeSpanBox(this); } // regex box functionality else if (event.getComponent() == reBox) { boolean r = reBox.booleanValue(); cb.setNewItemsAllowed(r); if (!r) { SpanBox.buildBoxValues(cb, ebene, sq); } else if (cb.getValue() != null) { String escapedItem = sq.escapeRegexCharacters(cb.getValue().toString()); cb.addItem(escapedItem); cb.setValue(escapedItem); } } } @Override public void textChange(FieldEvents.TextChangeEvent event) { String txt = event.getText(); HashMap<Integer, Collection> levdistvals = new HashMap<>(); if (txt.length() > 1) { cb.removeAllItems(); for (String s : annonames) { Integer d = StringUtils.getLevenshteinDistance(removeAccents(txt), removeAccents(s)); 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, 5)) { List<String> values = new ArrayList(levdistvals.get(k)); Collections.sort(values, String.CASE_INSENSITIVE_ORDER); for (String v : values) { cb.addItem(v); } } } } public String getAttribute() { return ebene; } public String getValue() { return cb.getValue().toString(); } public void setValue(String value) { if (reBox.getValue()) { cb.addItem(value); } cb.setValue(value); } public boolean isRegEx() { return reBox.getValue(); } public static String removeAccents(String text) { return text == null ? null : Normalizer.normalize(text, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""); } public static void buildBoxValues(ComboBox cb, String level, FlatQueryBuilder sq) { String value = (cb.getValue() != null) ? cb.getValue().toString() : ""; Collection<String> annovals = sq.getAnnotationValues(level); cb.removeAllItems(); for (String s : annovals) { cb.addItem(s); } if (annovals.contains(value)) { cb.setValue(value); } else { cb.setValue(null); } } }