Java tutorial
/* * Copyright 2014 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.admin; import annis.gui.admin.view.GroupListView; import annis.gui.converter.CommaSeperatedStringConverterSet; import annis.security.Group; import com.vaadin.data.Container; import com.vaadin.data.Item; import com.vaadin.data.Property; import com.vaadin.data.fieldgroup.FieldGroup; import com.vaadin.data.util.BeanContainer; import com.vaadin.data.util.GeneratedPropertyContainer; import com.vaadin.data.util.IndexedContainer; import com.vaadin.data.util.PropertyValueGenerator; import com.vaadin.data.util.filter.SimpleStringFilter; import com.vaadin.event.Action; import com.vaadin.event.FieldEvents; import com.vaadin.event.ShortcutAction; import com.vaadin.shared.ui.MarginInfo; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Grid; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Panel; import com.vaadin.ui.ProgressBar; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.renderers.ButtonRenderer; import com.vaadin.ui.renderers.ClickableRenderer; import com.vaadin.ui.themes.ChameleonTheme; import java.util.Collection; import java.util.LinkedList; import java.util.List; import java.util.Set; import java.util.TreeSet; /** * * @author Thomas Krause <krauseto@hu-berlin.de> */ public class GroupManagementPanel extends Panel implements GroupListView { private final List<GroupListView.Listener> listeners = new LinkedList<>(); private final Grid groupsGrid = new Grid(); private final TextField txtGroupName; private final ProgressBar progress; private final HorizontalLayout actionLayout; private final BeanContainer<String, Group> groupsContainer = new BeanContainer<>(Group.class); private final IndexedContainer corpusContainer = new IndexedContainer(); public GroupManagementPanel() { groupsContainer.setBeanIdProperty("name"); progress = new ProgressBar(); progress.setCaption("Loading group list"); progress.setIndeterminate(true); progress.setVisible(false); GeneratedPropertyContainer generated = new GeneratedPropertyContainer(groupsContainer); generated.addGeneratedProperty("edit", new PropertyValueGenerator<String>() { @Override public String getValue(Item item, Object itemId, Object propertyId) { return "Edit"; } @Override public Class<String> getType() { return String.class; } }); groupsGrid.setContainerDataSource(generated); groupsGrid.setSelectionMode(Grid.SelectionMode.MULTI); groupsGrid.setSizeFull(); groupsGrid.setColumns("name", "edit", "corpora"); Grid.HeaderRow filterRow = groupsGrid.appendHeaderRow(); TextField groupFilterField = new TextField(); groupFilterField.setInputPrompt("Filter"); groupFilterField.addTextChangeListener(new FieldEvents.TextChangeListener() { @Override public void textChange(FieldEvents.TextChangeEvent event) { groupsContainer.removeContainerFilters("name"); if (!event.getText().isEmpty()) { groupsContainer .addContainerFilter(new SimpleStringFilter("name", event.getText(), true, false)); } } }); filterRow.getCell("name").setComponent(groupFilterField); TextField corpusFilterField = new TextField(); corpusFilterField.setInputPrompt("Filter by corpus"); corpusFilterField.addTextChangeListener(new FieldEvents.TextChangeListener() { @Override public void textChange(FieldEvents.TextChangeEvent event) { groupsContainer.removeContainerFilters("corpora"); if (!event.getText().isEmpty()) { groupsContainer.addContainerFilter(new StringPatternInSetFilter("corpora", event.getText())); } } }); filterRow.getCell("corpora").setComponent(corpusFilterField); Grid.Column editColumn = groupsGrid.getColumn("edit"); editColumn.setRenderer(new ButtonRenderer(new ClickableRenderer.RendererClickListener() { @Override public void click(ClickableRenderer.RendererClickEvent event) { Group g = groupsContainer.getItem(event.getItemId()).getBean(); FieldGroup fields = new FieldGroup(groupsContainer.getItem(event.getItemId())); fields.addCommitHandler(new GroupCommitHandler(g.getName())); EditSingleGroup edit = new EditSingleGroup(fields, corpusContainer); Window w = new Window("Edit group \"" + g.getName() + "\""); w.setContent(edit); w.setModal(true); w.setWidth("500px"); w.setHeight("250px"); UI.getCurrent().addWindow(w); } })); Grid.Column corporaColumn = groupsGrid.getColumn("corpora"); ; corporaColumn.setConverter(new CommaSeperatedStringConverterSet()); txtGroupName = new TextField(); txtGroupName.setInputPrompt("New group name"); Button btAddNewGroup = new Button("Add new group"); btAddNewGroup.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent event) { handleAdd(); } }); btAddNewGroup.addStyleName(ChameleonTheme.BUTTON_DEFAULT); Button btDeleteGroup = new Button("Delete selected group(s)"); btDeleteGroup.addClickListener(new Button.ClickListener() { @Override public void buttonClick(Button.ClickEvent event) { // get selected groups Set<String> selectedGroups = new TreeSet<>(); for (Object id : groupsGrid.getSelectedRows()) { selectedGroups.add((String) id); } groupsGrid.getSelectionModel().reset(); for (GroupListView.Listener l : listeners) { l.deleteGroups(selectedGroups); } } }); actionLayout = new HorizontalLayout(txtGroupName, btAddNewGroup, btDeleteGroup); VerticalLayout layout = new VerticalLayout(actionLayout, progress, groupsGrid); layout.setSizeFull(); layout.setExpandRatio(groupsGrid, 1.0f); layout.setExpandRatio(progress, 1.0f); layout.setSpacing(true); layout.setMargin(new MarginInfo(true, false, false, false)); layout.setComponentAlignment(actionLayout, Alignment.MIDDLE_CENTER); layout.setComponentAlignment(progress, Alignment.TOP_CENTER); setContent(layout); setSizeFull(); addActionHandler(new AddGroupHandler(txtGroupName)); } private void handleAdd() { for (GroupListView.Listener l : listeners) { l.addNewGroup(txtGroupName.getValue()); } } @Override public void addListener(GroupListView.Listener listener) { listeners.add(listener); } @Override public void setGroupList(Collection<Group> groups) { groupsContainer.removeAllItems(); groupsContainer.addAll(groups); } @Override public void emptyNewGroupNameTextField() { txtGroupName.setValue(""); } @Override public void addAvailableCorpusNames(Collection<String> corpusNames) { for (String c : corpusNames) { corpusContainer.addItem(c); } } @Override public void setLoadingAnimation(boolean show) { progress.setVisible(show); groupsGrid.setVisible(!show); actionLayout.setEnabled(!show); } public class AddGroupHandler implements Action.Handler { private final Action enterKeyShortcutAction = new ShortcutAction(null, ShortcutAction.KeyCode.ENTER, null); private final Object registeredTarget; public AddGroupHandler(Object registeredTarget) { this.registeredTarget = registeredTarget; } @Override public Action[] getActions(Object target, Object sender) { return new Action[] { enterKeyShortcutAction }; } @Override public void handleAction(Action action, Object sender, Object target) { if (action == enterKeyShortcutAction && target == registeredTarget) { handleAdd(); } } } private class GroupCommitHandler implements FieldGroup.CommitHandler { private String groupName; public GroupCommitHandler(String groupName) { this.groupName = groupName; } @Override public void preCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException { } @Override public void postCommit(FieldGroup.CommitEvent commitEvent) throws FieldGroup.CommitException { for (GroupListView.Listener l : listeners) { l.groupUpdated(groupsContainer.getItem(groupName).getBean()); } } } public static class StringPatternInSetFilter implements Container.Filter { private final Object propertyId; private final String pattern; public StringPatternInSetFilter(Object propertyId, String pattern) { this.propertyId = propertyId; this.pattern = pattern.toLowerCase(); } @Override public boolean passesFilter(Object itemId, Item item) throws UnsupportedOperationException { Property<?> p = item.getItemProperty(propertyId); if (p.getValue() instanceof Set) { Set val = (Set) p.getValue(); for (Object o : val) { if ((o.toString().toLowerCase()).contains(pattern)) { return true; } } } else { throw new UnsupportedOperationException(); } return false; } @Override public boolean appliesToProperty(Object propertyId) { return this.propertyId.equals(propertyId); } } }