Java tutorial
/* * Copyright 2011 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.controlpanel; import annis.gui.AnnisUI; import annis.gui.ExportPanel; import annis.gui.HistoryPanel; import annis.gui.components.VirtualKeyboardCodeEditor; import annis.gui.components.codemirror.AqlCodeEditor; import annis.gui.frequency.FrequencyQueryPanel; import annis.gui.objects.Query; import annis.gui.objects.QueryUIState; import annis.gui.querybuilder.QueryBuilderChooser; import annis.libgui.Helper; import annis.libgui.IDGenerator; import annis.model.AqlParseError; import annis.model.QueryNode; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.data.util.BeanItemContainer; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.event.ShortcutAction.ModifierKey; import com.vaadin.event.ShortcutListener; import com.vaadin.server.ClassResource; import com.vaadin.server.FontAwesome; import com.vaadin.server.ThemeResource; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.GridLayout; import com.vaadin.ui.ListSelect; import com.vaadin.ui.ProgressBar; import com.vaadin.ui.TabSheet; import com.vaadin.ui.TabSheet.Tab; import com.vaadin.ui.TextArea; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.ValoTheme; import java.util.List; import org.slf4j.LoggerFactory; import org.vaadin.hene.popupbutton.PopupButton; /** * * @author thomas */ public class QueryPanel extends GridLayout implements ValueChangeListener { private static final org.slf4j.Logger log = LoggerFactory.getLogger(QueryPanel.class); public static final int MAX_HISTORY_MENU_ITEMS = 5; // the view name public static final String NAME = "query"; private AqlCodeEditor txtQuery; private TextArea txtStatus; private Button btShowResult; //private Button btShowResultNewTab; private PopupButton btHistory; private final ListSelect lstHistory; private final QueryUIState state; private ProgressBar piCount; private String lastPublicStatus; private Window historyWindow; private PopupButton btMoreActions; private FrequencyQueryPanel frequencyPanel; private final AnnisUI ui; private final BeanItemContainer<Query> historyContainer = new BeanItemContainer<>(Query.class);; public QueryPanel(final AnnisUI ui) { super(4, 5); this.ui = ui; this.lastPublicStatus = "Welcome to ANNIS! " + "A tutorial is available on the right side."; this.state = ui.getQueryState(); setSpacing(true); setMargin(false); setRowExpandRatio(0, 1.0f); setColumnExpandRatio(0, 0.0f); setColumnExpandRatio(1, 0.1f); setColumnExpandRatio(2, 0.0f); setColumnExpandRatio(3, 0.0f); txtQuery = new AqlCodeEditor(); txtQuery.setPropertyDataSource(state.getAql()); txtQuery.setInputPrompt("Please enter AQL query"); txtQuery.addStyleName("query"); if (ui.getInstanceFont() == null) { txtQuery.addStyleName("default-query-font"); txtQuery.setTextareaStyle("default-query-font"); } else { txtQuery.addStyleName(Helper.CORPUS_FONT); txtQuery.setTextareaStyle(Helper.CORPUS_FONT); } txtQuery.addStyleName("keyboardInput"); txtQuery.setWidth("100%"); txtQuery.setHeight(15f, Unit.EM); txtQuery.setTextChangeTimeout(500); final VirtualKeyboardCodeEditor virtualKeyboard; if (ui.getInstanceConfig().getKeyboardLayout() == null) { virtualKeyboard = null; } else { virtualKeyboard = new VirtualKeyboardCodeEditor(); virtualKeyboard.setKeyboardLayout(ui.getInstanceConfig().getKeyboardLayout()); virtualKeyboard.extend(txtQuery); } txtStatus = new TextArea(); txtStatus.setValue(this.lastPublicStatus); txtStatus.setWidth("100%"); txtStatus.setHeight(4.0f, Unit.EM); txtStatus.addStyleName("border-layout"); txtStatus.setReadOnly(true); piCount = new ProgressBar(); piCount.setIndeterminate(true); piCount.setEnabled(false); piCount.setVisible(false); btShowResult = new Button("Search"); btShowResult.setIcon(FontAwesome.SEARCH); btShowResult.setWidth("100%"); btShowResult.addClickListener(new ShowResultClickListener()); btShowResult.setDescription("<strong>Show Result</strong><br />Ctrl + Enter"); btShowResult.setClickShortcut(KeyCode.ENTER, ModifierKey.CTRL); btShowResult.setDisableOnClick(true); VerticalLayout historyListLayout = new VerticalLayout(); historyListLayout.setSizeUndefined(); lstHistory = new ListSelect(); lstHistory.setWidth("200px"); lstHistory.setNullSelectionAllowed(false); lstHistory.setValue(null); lstHistory.addValueChangeListener((ValueChangeListener) this); lstHistory.setImmediate(true); lstHistory.setContainerDataSource(historyContainer); lstHistory.setItemCaptionPropertyId("query"); lstHistory.addStyleName(Helper.CORPUS_FONT); Button btShowMoreHistory = new Button("Show more details", new Button.ClickListener() { @Override public void buttonClick(ClickEvent event) { if (historyWindow == null) { historyWindow = new Window("History"); historyWindow.setModal(false); historyWindow.setWidth("400px"); historyWindow.setHeight("250px"); } historyWindow.setContent(new HistoryPanel(state.getHistory(), ui.getQueryController())); if (UI.getCurrent().getWindows().contains(historyWindow)) { historyWindow.bringToFront(); } else { UI.getCurrent().addWindow(historyWindow); } } }); btShowMoreHistory.setWidth("100%"); historyListLayout.addComponent(lstHistory); historyListLayout.addComponent(btShowMoreHistory); historyListLayout.setExpandRatio(lstHistory, 1.0f); historyListLayout.setExpandRatio(btShowMoreHistory, 0.0f); btHistory = new PopupButton("History"); btHistory.setContent(historyListLayout); btHistory.setDescription("<strong>Show History</strong><br />" + "Either use the short overview (arrow down) or click on the button " + "for the extended view."); Button btShowKeyboard = null; if (virtualKeyboard != null) { btShowKeyboard = new Button(); btShowKeyboard.setWidth("100%"); btShowKeyboard.setDescription("Click to show a virtual keyboard"); btShowKeyboard.addStyleName(ValoTheme.BUTTON_ICON_ONLY); btShowKeyboard.addStyleName(ValoTheme.BUTTON_SMALL); btShowKeyboard.setIcon(new ClassResource(VirtualKeyboardCodeEditor.class, "keyboard.png")); btShowKeyboard.addClickListener(new ShowKeyboardClickListener(virtualKeyboard)); } Button btShowQueryBuilder = new Button("Query<br />Builder"); btShowQueryBuilder.setHtmlContentAllowed(true); btShowQueryBuilder.addStyleName(ValoTheme.BUTTON_SMALL); btShowQueryBuilder.addStyleName(ValoTheme.BUTTON_ICON_ALIGN_TOP); btShowQueryBuilder.setIcon(new ThemeResource("images/tango-icons/32x32/document-properties.png")); btShowQueryBuilder.addClickListener(new ShowQueryBuilderClickListener(ui)); VerticalLayout moreActionsLayout = new VerticalLayout(); moreActionsLayout.setWidth("250px"); btMoreActions = new PopupButton("More"); btMoreActions.setContent(moreActionsLayout); // btShowResultNewTab = new Button("Search (open in new tab)"); // btShowResultNewTab.setWidth("100%"); // btShowResultNewTab.addClickListener(new ShowResultInNewTabClickListener()); // btShowResultNewTab.setDescription("<strong>Show Result and open result in new tab</strong><br />Ctrl + Shift + Enter"); // btShowResultNewTab.setDisableOnClick(true); // btShowResultNewTab.setClickShortcut(KeyCode.ENTER, ModifierKey.CTRL, ModifierKey.SHIFT); // moreActionsLayout.addComponent(btShowResultNewTab); Button btShowExport = new Button("Export", new ShowExportClickListener(ui)); btShowExport.setIcon(FontAwesome.DOWNLOAD); btShowExport.setWidth("100%"); moreActionsLayout.addComponent(btShowExport); Button btShowFrequency = new Button("Frequency Analysis", new ShowFrequencyClickListener(ui)); btShowFrequency.setIcon(FontAwesome.BAR_CHART_O); btShowFrequency.setWidth("100%"); moreActionsLayout.addComponent(btShowFrequency); /* * We use the grid layout for a better rendering efficiency, but this comes * with the cost of some complexity when defining the positions of the * elements in the layout. * * This grid hopefully helps a little bit in understanding the "magic" * numbers better. * * Q: Query text field * QB: Button to toggle query builder // TODO * KEY: Button to show virtual keyboard * SEA: "Search" button * MOR: "More actions" button * HIST: "History" button * STAT: Text field with the real status * PROG: indefinite progress bar (spinning circle) * * \ 0 | 1 | 2 | 3 * --+-----+---+---+---+----- * 0 | Q | Q | Q | QB * --+-----+-----+-----+----- * 1 | Q | Q | Q | KEY * --+-----+-----+-----+----- * 2 | SEA | MOR | HIST| * --+-----+-----+-----+----- * 3 | STAT| STAT| STAT| PROG */ addComponent(txtQuery, 0, 0, 2, 1); addComponent(txtStatus, 0, 3, 2, 3); addComponent(btShowResult, 0, 2); addComponent(btMoreActions, 1, 2); addComponent(btHistory, 2, 2); addComponent(piCount, 3, 3); addComponent(btShowQueryBuilder, 3, 0); if (btShowKeyboard != null) { addComponent(btShowKeyboard, 3, 1); } // alignment setRowExpandRatio(0, 0.0f); setRowExpandRatio(1, 1.0f); setColumnExpandRatio(0, 1.0f); setColumnExpandRatio(1, 0.0f); setColumnExpandRatio(2, 0.0f); setColumnExpandRatio(3, 0.0f); //setComponentAlignment(btShowQueryBuilder, Alignment.BOTTOM_CENTER); } @Override public void attach() { super.attach(); IDGenerator.assignIDForFields(QueryPanel.this, btShowResult, btMoreActions); } public void updateShortHistory() { historyContainer.removeAllItems(); int counter = 0; for (Query q : state.getHistory().getItemIds()) { if (counter >= MAX_HISTORY_MENU_ITEMS) { break; } else { historyContainer.addBean(q); } counter++; } } public void setQuery(String query) { if (txtQuery != null) { txtQuery.setValue(query); } } public String getQuery() { if (txtQuery != null) { return (String) txtQuery.getValue(); } return ""; } public void setNodes(List<QueryNode> nodes) { txtQuery.setNodes(nodes); } public void setErrors(List<AqlParseError> errors) { txtQuery.setErrors(errors); } public void notifyFrequencyTabClose() { txtQuery.removeTextChangeListener(frequencyPanel); frequencyPanel = null; } @Override public void valueChange(ValueChangeEvent event) { btHistory.setPopupVisible(false); Object q = event.getProperty().getValue(); if (ui != null && ui.getQueryController() != null && q instanceof Query) { ui.getQueryController().setQuery((Query) q); } } public class ShowResultClickListener implements Button.ClickListener { @Override public void buttonClick(ClickEvent event) { if (ui != null && ui.getQueryController() != null) { ui.getQueryController().executeSearch(true, true); } } } // public class ShowResultInNewTabClickListener implements Button.ClickListener // { // // @Override // public void buttonClick(ClickEvent event) // { // if(controller != null) // { // controller.setQuery((txtQuery.getValue())); // controller.executeQuery(false); // } // } // } public void setCountIndicatorEnabled(boolean enabled) { if (piCount != null && btShowResult != null && txtStatus != null) { if (enabled) { if (!piCount.isVisible()) { piCount.setVisible(true); piCount.setEnabled(true); } } btShowResult.setEnabled(!enabled); // btShowResultNewTab.setEnabled(!enabled); } } public void setStatus(String status) { if (txtStatus != null) { txtStatus.setReadOnly(false); txtStatus.setValue(status); lastPublicStatus = status; txtStatus.setReadOnly(true); } } public void setStatus(String status, String resultStatus) { if (txtStatus != null) { txtStatus.setReadOnly(false); txtStatus.setValue(status + resultStatus); lastPublicStatus = status; txtStatus.setReadOnly(true); } } private static class ShowKeyboardClickListener implements ClickListener { private final VirtualKeyboardCodeEditor virtualKeyboard; public ShowKeyboardClickListener(VirtualKeyboardCodeEditor virtualKeyboard) { this.virtualKeyboard = virtualKeyboard; } @Override public void buttonClick(ClickEvent event) { virtualKeyboard.show(); } } private class ShowExportClickListener implements ClickListener { private AnnisUI ui; private ExportPanel panel; public ShowExportClickListener(AnnisUI ui) { this.ui = ui; } @Override public void buttonClick(ClickEvent event) { if (panel == null) { panel = new ExportPanel(QueryPanel.this, ui.getQueryController(), state); } final TabSheet tabSheet = ui.getSearchView().getMainTab(); Tab tab = tabSheet.getTab(panel); if (tab == null) { tab = tabSheet.addTab(panel, "Export"); tab.setIcon(FontAwesome.DOWNLOAD); } tab.setClosable(true); tabSheet.setSelectedTab(panel); btMoreActions.setPopupVisible(false); } } private class ShowFrequencyClickListener implements ClickListener { private AnnisUI ui; public ShowFrequencyClickListener(AnnisUI ui) { this.ui = ui; } @Override public void buttonClick(ClickEvent event) { if (frequencyPanel == null) { frequencyPanel = new FrequencyQueryPanel(ui.getQueryController(), state); txtQuery.addTextChangeListener(frequencyPanel); } final TabSheet tabSheet = ui.getSearchView().getMainTab(); Tab tab = tabSheet.getTab(frequencyPanel); if (tab == null) { tab = tabSheet.addTab(frequencyPanel, "Frequency Analysis"); tab.setIcon(FontAwesome.BAR_CHART_O); } tab.setClosable(true); tabSheet.setSelectedTab(frequencyPanel); btMoreActions.setPopupVisible(false); } } private static class ShowQueryBuilderClickListener implements ClickListener { private QueryBuilderChooser queryBuilder; private AnnisUI ui; public ShowQueryBuilderClickListener(AnnisUI ui) { this.ui = ui; } @Override public void buttonClick(ClickEvent event) { if (queryBuilder == null) { queryBuilder = new QueryBuilderChooser(ui.getQueryController(), ui, ui.getInstanceConfig()); } final TabSheet tabSheet = ui.getSearchView().getMainTab(); Tab tab = tabSheet.getTab(queryBuilder); if (tab == null) { tab = tabSheet.addTab(queryBuilder, "Query Builder", new ThemeResource("images/tango-icons/16x16/document-properties.png")); ui.addAction(new ShortcutListener("^Query builder") { @Override public void handleAction(Object sender, Object target) { if (queryBuilder != null && tabSheet.getTab(queryBuilder) != null) { tabSheet.setSelectedTab(queryBuilder); } } }); } tab.setClosable(true); tabSheet.setSelectedTab(queryBuilder); } } public String getLastPublicStatus() { return lastPublicStatus; } public ProgressBar getPiCount() { return piCount; } }