Java tutorial
/** * Copyright (c) 2011 - 2015, Lunifera GmbH (Gross Enzersdorf), Loetz KG (Heidelberg) * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Florian Pirchner - Initial implementation */ package org.lunifera.vaaclipse.ui.preferences.addon.internal; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import javax.annotation.PostConstruct; import javax.inject.Inject; import org.eclipse.e4.core.contexts.ContextInjectionFactory; import org.eclipse.e4.core.contexts.IEclipseContext; import org.eclipse.e4.core.di.annotations.Optional; import org.eclipse.e4.core.services.events.IEventBroker; import org.eclipse.emf.common.util.EList; import org.lunifera.vaaclipse.ui.preferences.addon.PreferencesAuthorization; import org.lunifera.vaaclipse.ui.preferences.addon.PreferencesEvents; import org.lunifera.vaaclipse.ui.preferences.addon.internal.exception.ValidationFailedException; import org.lunifera.vaaclipse.ui.preferences.addon.internal.util.ModelHelper; import org.lunifera.vaaclipse.ui.preferences.addon.internal.util.PrefHelper; import org.lunifera.vaaclipse.ui.preferences.model.FieldEditor; import org.lunifera.vaaclipse.ui.preferences.model.PreferencesCategory; import org.lunifera.vaaclipse.ui.preferences.model.PreferencesPage; import org.osgi.framework.BundleContext; import org.osgi.service.prefs.BackingStoreException; import org.osgi.service.prefs.Preferences; import org.semanticsoft.vaaclipse.publicapi.resources.BundleResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.vaadin.data.Item; import com.vaadin.event.FieldEvents.TextChangeEvent; import com.vaadin.event.FieldEvents.TextChangeListener; import com.vaadin.event.ItemClickEvent; import com.vaadin.server.Sizeable; import com.vaadin.shared.MouseEventDetails.MouseButton; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.CssLayout; import com.vaadin.ui.HorizontalSplitPanel; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.Panel; import com.vaadin.ui.TextField; import com.vaadin.ui.Tree; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import e4modelextension.VaaclipseApplication; /** * @author rushan * */ public class PreferencesDialog { static final String PAGE_HEADER_ERROR_TEXT = "page-header-error-text"; @Inject IEventBroker eventBroker; @Inject VaaclipseApplication app; @Inject IEclipseContext context; @Inject @Optional PreferencesCategory selectedCategory; @Inject @Optional PreferencesAuthorization authService; Logger logger = LoggerFactory.getLogger(PreferencesDialog.class); @Inject UI ui; TextField filterField = new TextField(); private Tree tree; private Window window; HorizontalSplitPanel splitPanel = new HorizontalSplitPanel(); private Panel treePanel; private VerticalLayout rightSide; private CssLayout leftSide; private Button filterButton = new Button(); private Button clearFilterButton = new Button(); private CssLayout pageHeader; private CssLayout pageContent; private CssLayout pageBottom; private Button restoreDefaults; private Button apply; private VerticalLayout root; private CssLayout dlgButtonPanel; private Button cancelButton; private Button okButton; private Label pageHeaderText; private BundleContext bundleContext; private String errorMessage; List<PreferencesPage> visitedPages = new ArrayList<>(); private HashSet<PreferencesCategory> visibleCategories; private List<PreferencesCategory> categoryList = new ArrayList<>(100); public Window getWindow() { return window; } public PreferencesCategory getSelectedCategory() { return selectedCategory; } public PreferencesPage getCurrentPage() { return selectedCategory.getPage(); } @PostConstruct public void init() { if (selectedCategory == null && !app.getPreferencesCategories().isEmpty()) { selectedCategory = app.getPreferencesCategories().get(0); } createWindow(); createSearchField(); createTree(); addListeners(); } public void createWindow() { window = new Window(); window.setCaption("Preferences"); window.addStyleName("preferences-dialog"); window.setWidth("800px"); window.setHeight("600px"); splitPanel.setSizeFull(); dlgButtonPanel = new CssLayout(); dlgButtonPanel.setWidth("100%"); dlgButtonPanel.addStyleName("dlg-button-panel"); // dlgButtonPanel.addComponent(new Label("<hr/>", ContentMode.HTML)); cancelButton = new Button("Cancel"); cancelButton.addStyleName("cancel-button"); dlgButtonPanel.addComponent(cancelButton); okButton = new Button("OK"); okButton.addStyleName("ok-button"); dlgButtonPanel.addComponent(okButton); root = new VerticalLayout(); root.setSizeFull(); window.setContent(root); root.addComponent(splitPanel); root.addComponent(dlgButtonPanel); root.setExpandRatio(splitPanel, 10); root.setExpandRatio(dlgButtonPanel, 0); treePanel = new Panel(); treePanel.addStyleName("categories-panel"); treePanel.addStyleName("borderless"); treePanel.setSizeFull(); leftSide = new CssLayout(); leftSide.addStyleName("categories"); leftSide.setSizeFull(); // filterField.setWidth("70%"); filterField.addStyleName("categories-filter"); leftSide.addComponent(filterField); filterButton.setIcon(BundleResource .valueOf("platform:/plugin/org.lunifera.vaaclipse.ui.preferences.addon/img/find.png")); filterButton.addStyleName("vaaclipsebutton"); filterButton.addStyleName("icon-only"); filterButton.addStyleName("filter-category-button"); clearFilterButton.setIcon(BundleResource .valueOf("platform:/plugin/org.lunifera.vaaclipse.ui.preferences.addon/img/clear.png")); clearFilterButton.addStyleName("vaaclipsebutton"); clearFilterButton.addStyleName("icon-only"); clearFilterButton.addStyleName("clear-filter-button"); leftSide.addComponent(clearFilterButton); leftSide.addComponent(filterButton); leftSide.addComponent(treePanel); rightSide = new VerticalLayout(); rightSide.setSizeFull(); // rightSide.setMargin(new MarginInfo(true, true, false, true)); pageHeader = new CssLayout(); pageHeader.addStyleName("page-header-panel"); pageHeader.setWidth("100%"); pageHeaderText = new Label("Page"); pageHeaderText.addStyleName("page-header-text"); pageHeader.addComponent(pageHeaderText); rightSide.addComponent(pageHeader); pageContent = new CssLayout(); // pageContent.setSizeFull(); Panel pageContentPanel = new Panel(pageContent);// wrap page content to // panel - if content is // too large, scrolling // needed pageContentPanel.setSizeFull(); rightSide.addComponent(pageContentPanel); pageBottom = new CssLayout(); pageBottom.addStyleName("page-bottom-panel"); pageBottom.setWidth("100%"); rightSide.addComponent(pageBottom); apply = new Button("Apply"); apply.addStyleName("apply"); pageBottom.addComponent(apply); restoreDefaults = new Button("RestoreDefaults"); restoreDefaults.addStyleName("restore-defaults"); pageBottom.addComponent(restoreDefaults); splitPanel.addComponent(leftSide); splitPanel.addComponent(rightSide); splitPanel.setSplitPosition(30, Sizeable.Unit.PERCENTAGE); rightSide.setExpandRatio(pageHeader, 0); rightSide.setExpandRatio(pageContentPanel, 1); rightSide.setExpandRatio(pageBottom, 0); clearFilterButton.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { filterField.setValue(""); refreshTree(); } }); filterButton.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { refreshTree(); } }); } public void createSearchField() { filterField.addTextChangeListener(new TextChangeListener() { @Override public void textChange(TextChangeEvent event) { refreshTree(); } }); } private void createTree() { tree = new Tree(); tree.setSizeFull(); tree.setImmediate(true); treePanel.setContent(tree); tree.addContainerProperty("name", String.class, "NoName"); tree.setItemCaptionPropertyId("name"); ModelHelper.buildChildCategoryListIncludeThisList(app.getPreferencesCategories(), categoryList); refreshTree(); tree.addItemClickListener(new ItemClickEvent.ItemClickListener() { public void itemClick(final ItemClickEvent event) { if (event.getButton() == MouseButton.LEFT) { PreferencesCategory selectedCat = (PreferencesCategory) event.getItemId(); if (selectedCat != null) { openPreferencePageForCategory(selectedCat); } } } }); if (selectedCategory != null) { tree.select(selectedCategory); openPreferencePageForCategory(selectedCategory); } } private void refreshTree() { tree.removeAllItems(); EList<PreferencesCategory> catList = app.getPreferencesCategories(); markVisibility(); fillCategories(catList, null); for (Object id : tree.rootItemIds()) { tree.expandItemsRecursively(id); } } private void markVisibility() { visibleCategories = new HashSet<PreferencesCategory>(); String filterValue = filterField.getValue(); if (filterValue.isEmpty()) { return; } for (PreferencesCategory category : categoryList) { if (category != null && category.getName().contains(filterValue)) { do { visibleCategories.add(category); category = category.getParentCategory(); } while (category != null); } } } @SuppressWarnings("unchecked") private void fillCategories(List<PreferencesCategory> list, PreferencesCategory parentCat) { String search = filterField.getValue().trim(); for (PreferencesCategory c : list) { if (authService != null && c.getParentCategory() != null && "user".equals(c.getParentCategory().getId()) && !authService.isAllowed(c)) { continue; } if (c.getName() == null) c.setName("No Name"); if (filterField.getValue().isEmpty() || visibleCategories.contains(c)) { Item catItem = tree.addItem(c); catItem.getItemProperty("name").setValue(c.getName()); if (c.getChildCategories().isEmpty()) tree.setChildrenAllowed(c, false); if (parentCat != null) tree.setParent(c, parentCat); fillCategories(c.getChildCategories(), c); } } } private void openPreferencePageForCategory(PreferencesCategory selectedCat) { selectedCategory = selectedCat; refreshHeaderMessage(); pageContent.removeAllComponents(); if (selectedCat.getPage() != null) { IEclipseContext pageContext = context.createChild(); pageContext.set(CssLayout.class, pageContent); pageContext.set(PreferencesPage.class, selectedCat.getPage()); PreferencesPageRenderer pageRenderer = ContextInjectionFactory.make(PreferencesPageRenderer.class, pageContext); pageRenderer.render(); visitedPages.add(selectedCat.getPage()); } else if (!selectedCat.getChildCategories().isEmpty()) { pageContent.addComponent(new Label("Expand the tree to edit a preferences for a specific feature")); } } private void addListeners() { restoreDefaults.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { restoreDefaults(); } }); apply.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { applyPressed(); } }); okButton.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { okPressed(); } }); cancelButton.addClickListener(new ClickListener() { @Override public void buttonClick(ClickEvent event) { cancelPressed(); } }); } public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; refreshHeaderMessage(); } public void clearErrorMessage() { this.errorMessage = null; refreshHeaderMessage(); } public void refreshHeaderMessage() { if (errorMessage != null) { pageHeaderText.addStyleName(PAGE_HEADER_ERROR_TEXT); pageHeaderText.setValue(errorMessage); } else { pageHeaderText.removeStyleName(PAGE_HEADER_ERROR_TEXT); pageHeaderText.setValue(selectedCategory.getName()); } } private void restoreDefaults() { PreferencesPage currentPage = getCurrentPage(); if (currentPage != null) { try { restoreDefaultsOnPage(currentPage); } catch (Exception e) { Notification.show("Error restoring defaults", "Restoring defaults on this page failed", Notification.Type.ERROR_MESSAGE); return; } fireEvent(PreferencesEvents.PREFERENCES_TO_DEFAULTS, currentPage); // Refresh the current page (it should be rerendered) openPreferencePageForCategory(getSelectedCategory()); } } private void okPressed() { Exception exception = null; for (PreferencesPage page : visitedPages) { try { applyChangesOnPage(page); } catch (ValidationFailedException validationException) { setErrorMessage(validationException.getLocalizedMessage()); Notification.show("Validation failed", validationException.getLocalizedMessage(), Notification.Type.WARNING_MESSAGE); return; } catch (Exception e) { exception = e; } } if (exception != null) { String errorMessage = "Saving changes was failed on some pages"; setErrorMessage(errorMessage); Notification.show("Error apply changes", errorMessage, Notification.Type.ERROR_MESSAGE); return; } else { fireEvent(PreferencesEvents.PREFERENCES_APPLIED, (PreferencesPage[]) visitedPages.toArray(new PreferencesPage[visitedPages.size()])); } clearErrorMessage(); ui.removeWindow(window); } private void cancelPressed() { ui.removeWindow(window); } private void applyPressed() { PreferencesPage currentPage = getCurrentPage(); if (currentPage != null) { try { applyChangesOnPage(currentPage); } catch (ValidationFailedException validationException) { setErrorMessage(validationException.getLocalizedMessage()); Notification.show("Validation failed", "The preferences is not correct", Notification.Type.WARNING_MESSAGE); return; } catch (Exception e) { setErrorMessage("Applying changes on this page failed"); Notification.show("Error apply changes", "Applying changes on this page failed", Notification.Type.ERROR_MESSAGE); return; } clearErrorMessage(); fireEvent(PreferencesEvents.PREFERENCES_APPLIED, currentPage); } } private void applyChangesOnPage(PreferencesPage page) throws BackingStoreException, ValidationFailedException { PreferencesPageRenderer pageRenderer = (PreferencesPageRenderer) page.getRenderer(); pageRenderer.validate(); try { pageRenderer.save(); } catch (Exception e) { logger.error("Error copy changes from UI to preferences for category {}", selectedCategory.getName(), e); throw e; } try { PrefHelper.flush(page); } catch (BackingStoreException e) { logger.error("Error flushing changes for category {}", page.getCategory().getName(), e); throw e; } } private void restoreDefaultsOnPage(PreferencesPage page) throws BackingStoreException { try { for (FieldEditor<?> fieldEditor : page.getChildren()) { String defaultValue = fieldEditor.getDefaultValue(); if (defaultValue != null) ((Preferences) fieldEditor.getPreferences()).put(fieldEditor.getPreferenceName(), defaultValue); } } catch (Exception e) { logger.error("Error copy default values from model to preferences for category {}", page.getCategory().getName(), e); throw e; } try { PrefHelper.flush(page); } catch (BackingStoreException e) { logger.error("Error flushing changes for category {}", page.getCategory().getName(), e); throw e; } } private void fireEvent(String topic, PreferencesPage... pages) { eventBroker.send(topic, pages); } }