Java tutorial
/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.ui.editors.messagebundle; import org.opencms.i18n.CmsLocaleManager; import org.opencms.i18n.CmsMessages; import org.opencms.ui.FontOpenCms; import org.opencms.ui.editors.messagebundle.CmsMessageBundleEditorTypes.EditMode; import org.opencms.ui.editors.messagebundle.CmsMessageBundleEditorTypes.I_OptionListener; import java.util.Collection; import java.util.Locale; import com.vaadin.data.Property.ValueChangeEvent; import com.vaadin.data.Property.ValueChangeListener; import com.vaadin.event.FieldEvents.BlurEvent; import com.vaadin.event.FieldEvents.BlurListener; import com.vaadin.event.FieldEvents.FocusEvent; import com.vaadin.event.FieldEvents.FocusListener; import com.vaadin.event.ShortcutAction.KeyCode; import com.vaadin.event.ShortcutListener; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.ComboBox; import com.vaadin.ui.Component; import com.vaadin.ui.FormLayout; import com.vaadin.ui.GridLayout; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.Notification; import com.vaadin.ui.TextField; import com.vaadin.ui.UI; /** View of the message bundle editor options, i.e., language/mode switcher, file name display and "Add key" option. */ public class CmsMessageBundleEditorOptions { /** Messages used by the GUI. */ CmsMessages m_messages; /** Grid with all options (2x2). */ private GridLayout m_optionsComponent; /** The upper left component in the options grid (containing the language/mode switches and the label for the file path). */ private HorizontalLayout m_upperLeftComponent; /** The lower left component in the options grid (containing the "Add key" label). */ private Component m_lowerLeftComponent; /** The lower right component in the options grid (containing the "Add key" input field and the "Add key" button). */ private Component m_lowerRightComponent; /** The select box for choosing the currently edited language. */ private ComboBox m_languageSelect; /** The component that contains the language switch. */ private Component m_languageSwitch; /** The component that contains the mode switch. */ private Component m_modeSwitch; /** The select box for the current edit mode. */ private ComboBox m_modeSelect; /** The component with the label of the "File"-Display. */ private Component m_filePathLabel; /** The input field that displays the path of the currently edited file. */ private TextField m_filePathField; /** The "Add key" input field. */ TextField m_addKeyInput; /** A flag, indicating if the mode switch should be shown. */ private boolean m_showModeSwitch; /** A flag, indicating if the "Add key" row should be shown. */ private boolean m_showAddKeyOption; /** The listener for option changes. */ I_OptionListener m_listener; /** * Default constructor. * @param locales the locales shown in the language switch. * @param currentLocale the currently edited locale. * @param currentMode the current edit mode. * @param optionListener the option listener. */ public CmsMessageBundleEditorOptions(final Collection<Locale> locales, final Locale currentLocale, final EditMode currentMode, final I_OptionListener optionListener) { m_messages = Messages.get().getBundle(UI.getCurrent().getLocale()); m_listener = optionListener; initLanguageSwitch(locales, currentLocale); initModeSwitch(currentMode); initFilePathLabel(); initUpperLeftComponent(); initLowerLeftComponent(); initLowerRightComponent(); initOptionsComponent(); } /** * Puts focus on the "Add key" input field, iff it is shown. * @return <code>true</code> if the focus has been set, <code>false</code> otherwise. */ public boolean focusAddKey() { if (m_showAddKeyOption) { m_addKeyInput.focus(); } return m_showAddKeyOption; } /** * Returns the options component. * @return the options component. */ public Component getOptionsComponent() { return m_optionsComponent; } /** * Sets the path of the edited file in the corresponding display. * @param editedFilePath path of the edited file to set. */ public void setEditedFilePath(final String editedFilePath) { m_filePathField.setReadOnly(false); m_filePathField.setValue(editedFilePath); m_filePathField.setReadOnly(true); } /** * Set the edit mode. * @param mode the edit mode to set. */ public void setEditMode(final EditMode mode) { if (!m_modeSelect.getValue().equals(mode)) { m_modeSelect.setValue(mode); } } /** * Update which options are shown. * @param showModeSwitch flag, indicating if the mode switch should be shown. * @param showAddKeyOption flag, indicating if the "Add key" row should be shown. */ public void updateShownOptions(boolean showModeSwitch, boolean showAddKeyOption) { if (showModeSwitch != m_showModeSwitch) { m_upperLeftComponent.removeAllComponents(); m_upperLeftComponent.addComponent(m_languageSwitch); if (showModeSwitch) { m_upperLeftComponent.addComponent(m_modeSwitch); } m_upperLeftComponent.addComponent(m_filePathLabel); m_showModeSwitch = showModeSwitch; } if (showAddKeyOption != m_showAddKeyOption) { if (showAddKeyOption) { m_optionsComponent.addComponent(m_lowerLeftComponent, 0, 1); m_optionsComponent.addComponent(m_lowerRightComponent, 1, 1); } else { m_optionsComponent.removeComponent(0, 1); m_optionsComponent.removeComponent(1, 1); } m_showAddKeyOption = showAddKeyOption; } } /** * Handles adding a key. Calls the registered listener and wraps it's method in some GUI adjustments. */ void handleAddKey() { String key = m_addKeyInput.getValue(); if (m_listener.handleAddKey(key)) { Notification.show(key.isEmpty() ? m_messages.key(Messages.GUI_NOTIFICATION_MESSAGEBUNDLEEDITOR_EMPTY_KEY_SUCCESSFULLY_ADDED_0) : m_messages.key(Messages.GUI_NOTIFICATION_MESSAGEBUNDLEEDITOR_KEY_SUCCESSFULLY_ADDED_1, key)); } else { CmsMessageBundleEditorTypes.showWarning( m_messages.key(Messages.GUI_NOTIFICATION_MESSAGEBUNDLEEDITOR_KEY_ALREADEY_EXISTS_CAPTION_0), m_messages.key(Messages.GUI_NOTIFICATION_MESSAGEBUNDLEEDITOR_KEY_ALREADEY_EXISTS_DESCRIPTION_1, key)); } m_addKeyInput.focus(); m_addKeyInput.selectAll(); } /** * Sets the currently edited locale. * @param locale the locale to set. */ void setLanguage(final Locale locale) { if (!m_languageSelect.getValue().equals(locale)) { m_languageSelect.setValue(locale); } } /** * Creates the "Add key" button. * @return the "Add key" button. */ private Component createAddKeyButton() { // the "+" button Button addKeyButton = new Button(); addKeyButton.addStyleName("icon-only"); addKeyButton.addStyleName("borderless-colored"); addKeyButton.setDescription(m_messages.key(Messages.GUI_ADD_KEY_0)); addKeyButton.setIcon(FontOpenCms.CIRCLE_PLUS, m_messages.key(Messages.GUI_ADD_KEY_0)); addKeyButton.addClickListener(new ClickListener() { private static final long serialVersionUID = 1L; public void buttonClick(ClickEvent event) { handleAddKey(); } }); return addKeyButton; } /** * Creates the upper right component of the options grid. * Creation includes the initialization of {@link #m_filePathField}. * * @return the upper right component in the options grid. */ private Component createUpperRightComponent() { HorizontalLayout upperRight = new HorizontalLayout(); upperRight.setSizeFull(); FormLayout fileNameDisplay = new FormLayout(); fileNameDisplay.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); fileNameDisplay.setSizeFull(); m_filePathField = new TextField(); m_filePathField.setWidth("100%"); m_filePathField.setEnabled(true); m_filePathField.setReadOnly(true); fileNameDisplay.addComponent(m_filePathField); fileNameDisplay.setSpacing(true); FormLayout filePathDisplay = new FormLayout(); filePathDisplay.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); filePathDisplay.setSizeFull(); filePathDisplay.addComponent(m_filePathField); filePathDisplay.setSpacing(true); upperRight.addComponent(filePathDisplay); upperRight.setExpandRatio(filePathDisplay, 2f); HorizontalLayout placeHolder = new HorizontalLayout(); placeHolder.setWidth(CmsMessageBundleEditorTypes.OPTION_COLUMN_WIDTH_PX); upperRight.addComponent(placeHolder); return upperRight; } /** * Initializes the input field for new keys {@link #m_addKeyInput}. */ private void initAddKeyInput() { //the input field for the key m_addKeyInput = new TextField(); m_addKeyInput.setWidth("100%"); m_addKeyInput.setInputPrompt(m_messages.key(Messages.GUI_INPUT_PROMPT_ADD_KEY_0)); final ShortcutListener shortCutListener = new ShortcutListener("Add key via ENTER", KeyCode.ENTER, null) { private static final long serialVersionUID = 1L; @Override public void handleAction(Object sender, Object target) { handleAddKey(); } }; m_addKeyInput.addFocusListener(new FocusListener() { private static final long serialVersionUID = 1L; public void focus(FocusEvent event) { m_addKeyInput.addShortcutListener(shortCutListener); } }); m_addKeyInput.addBlurListener(new BlurListener() { private static final long serialVersionUID = 1L; public void blur(BlurEvent event) { m_addKeyInput.removeShortcutListener(shortCutListener); } }); } /** * Initializes the label for the file path display {@link #m_filePathLabel}. */ private void initFilePathLabel() { m_filePathLabel = new TextField(); m_filePathLabel.setWidth("100%"); m_filePathLabel.setEnabled(true); m_filePathLabel.setReadOnly(true); m_filePathLabel = new Label(m_messages.key(Messages.GUI_FILENAME_LABEL_0)); } /** * Initializes the language switcher UI Component {@link #m_languageSwitch}, including {@link #m_languageSelect}. * @param locales the locales that can be selected. * @param current the currently selected locale. */ private void initLanguageSwitch(Collection<Locale> locales, Locale current) { FormLayout languages = new FormLayout(); languages.setHeight("100%"); languages.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); ComboBox languageSelect = new ComboBox(); languageSelect.setCaption(m_messages.key(Messages.GUI_LANGUAGE_SWITCHER_LABEL_0)); languageSelect.setNullSelectionAllowed(false); // set Locales for (Locale locale : locales) { languageSelect.addItem(locale); String caption = locale.getDisplayName(UI.getCurrent().getLocale()); if (CmsLocaleManager.getDefaultLocale().equals(locale)) { caption += " (" + Messages.get().getBundle(UI.getCurrent().getLocale()).key(Messages.GUI_DEFAULT_LOCALE_0) + ")"; } languageSelect.setItemCaption(locale, caption); } languageSelect.setValue(current); languageSelect.setNewItemsAllowed(false); languageSelect.setTextInputAllowed(false); languageSelect.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 1L; public void valueChange(ValueChangeEvent event) { m_listener.handleLanguageChange((Locale) event.getProperty().getValue()); } }); if (locales.size() == 1) { languageSelect.setEnabled(false); } languages.addComponent(languageSelect); m_languageSwitch = languages; } /** * Initializes the lower left component {@link #m_lowerLeftComponent} with the correctly placed "Add key"-label. */ private void initLowerLeftComponent() { HorizontalLayout placeHolderLowerLeft = new HorizontalLayout(); placeHolderLowerLeft.setWidth("100%"); Label newKeyLabel = new Label(m_messages.key(Messages.GUI_CAPTION_ADD_KEY_0)); newKeyLabel.setWidthUndefined(); HorizontalLayout lowerLeft = new HorizontalLayout(placeHolderLowerLeft, newKeyLabel); lowerLeft.setWidth("100%"); lowerLeft.setExpandRatio(placeHolderLowerLeft, 1f); m_lowerLeftComponent = lowerLeft; } /** * Initializes the lower right component {@link #m_lowerRightComponent}, with all its components, i.e., * the "Add key" input field {@link #m_addKeyInput} and the "Add key" button. */ private void initLowerRightComponent() { initAddKeyInput(); Component addKeyButton = createAddKeyButton(); HorizontalLayout addKeyWrapper = new HorizontalLayout(addKeyButton); addKeyWrapper.setComponentAlignment(addKeyButton, Alignment.MIDDLE_CENTER); addKeyWrapper.setHeight("100%"); addKeyWrapper.setWidth(CmsMessageBundleEditorTypes.OPTION_COLUMN_WIDTH_PX); FormLayout inputForm = new FormLayout(m_addKeyInput); inputForm.setWidth("100%"); HorizontalLayout lowerRight = new HorizontalLayout(); lowerRight.setWidth("100%"); lowerRight.addComponent(inputForm); lowerRight.addComponent(addKeyWrapper); lowerRight.setExpandRatio(inputForm, 1f); m_lowerRightComponent = lowerRight; } /** * Initializes the mode switcher. * @param current the current edit mode */ private void initModeSwitch(final EditMode current) { FormLayout modes = new FormLayout(); modes.setHeight("100%"); modes.setDefaultComponentAlignment(Alignment.MIDDLE_LEFT); m_modeSelect = new ComboBox(); m_modeSelect.setCaption(m_messages.key(Messages.GUI_VIEW_SWITCHER_LABEL_0)); // add Modes m_modeSelect.addItem(CmsMessageBundleEditorTypes.EditMode.DEFAULT); m_modeSelect.setItemCaption(CmsMessageBundleEditorTypes.EditMode.DEFAULT, m_messages.key(Messages.GUI_VIEW_SWITCHER_EDITMODE_DEFAULT_0)); m_modeSelect.addItem(CmsMessageBundleEditorTypes.EditMode.MASTER); m_modeSelect.setItemCaption(CmsMessageBundleEditorTypes.EditMode.MASTER, m_messages.key(Messages.GUI_VIEW_SWITCHER_EDITMODE_MASTER_0)); // set current mode as selected m_modeSelect.setValue(current); m_modeSelect.setNewItemsAllowed(false); m_modeSelect.setTextInputAllowed(false); m_modeSelect.setNullSelectionAllowed(false); m_modeSelect.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 1L; public void valueChange(ValueChangeEvent event) { m_listener.handleModeChange((EditMode) event.getProperty().getValue()); } }); modes.addComponent(m_modeSelect); m_modeSwitch = modes; } /** * Creates the complete options component. * It's a grid with two rows and two columns, styled like: * * || * [language switch] [mode switch] File-Label || [file path display] * -------------------------------------------||---------------------------------- * New-Key-Label || [new key input] [add key button] * || * * NOTE: The second row is not filled with components on initialization, what means keys can not be added * Filling is done via {@link #updateShownOptions(boolean, boolean)} */ private void initOptionsComponent() { // create and layout the component m_optionsComponent = new GridLayout(2, 2); m_optionsComponent.setHideEmptyRowsAndColumns(true); m_optionsComponent.setDefaultComponentAlignment(Alignment.MIDDLE_RIGHT); m_optionsComponent.setWidth("100%"); m_optionsComponent.setColumnExpandRatio(1, 1f); m_optionsComponent.setStyleName("v-options"); // add the components m_optionsComponent.addComponent(m_upperLeftComponent, 0, 0); Component upperRight = createUpperRightComponent(); m_optionsComponent.addComponent(upperRight, 1, 0); } /** * Initializes the upper left component. Does not show the mode switch. */ private void initUpperLeftComponent() { m_upperLeftComponent = new HorizontalLayout(); m_upperLeftComponent.setHeight("100%"); m_upperLeftComponent.setSpacing(true); m_upperLeftComponent.setDefaultComponentAlignment(Alignment.MIDDLE_RIGHT); m_upperLeftComponent.addComponent(m_languageSwitch); m_upperLeftComponent.addComponent(m_filePathLabel); } }