/******************************************************************************* * Copyright (c) 2012-2013 RelationWare, Benno Luthiger * 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: * RelationWare, Benno Luthiger ******************************************************************************/ package org.ripla.web.util; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.URL; import java.util.HashMap; import java.util.Map; import org.ripla.web.Activator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.vaadin.shared.ui.label.ContentMode; import com.vaadin.ui.Alignment; import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickEvent; import com.vaadin.ui.CustomComponent; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Label; import com.vaadin.ui.UI; import com.vaadin.ui.VerticalLayout; import com.vaadin.ui.Window; import com.vaadin.ui.themes.BaseTheme; /** * <p> * UI component that displays a <code>[Help]</code> link button. When clicked, a * window containing help text is displayed. * </p> * Usage: * * <pre> * URL lHelpContent = this.getClass().getClassLoader().getResource("help.html"); * layout.addComponent(new HelpButton("Help", lHelpContent, 700, 600)); * </pre> * * @author Luthiger */ @SuppressWarnings("serial") public final class HelpButton extends CustomComponent { private static final Logger LOG = LoggerFactory.getLogger(HelpButton.class); private final static String NL = System.getProperty("line.separator"); //$NON-NLS-1$ // NOPMD private final Map<URL, String> helpCache = new HashMap<URL, String>(); /** * HelpButton constructor. * * @param inCaption * String the link button's caption * @param inHelpContent * URL the file's url containing the html formatted help text to * display * @param inWidth * int the popup windos's width * @param inHeight * int the popup windos's height */ public HelpButton(final String inCaption, final URL inHelpContent, final int inWidth, final int inHeight) { super(); final HorizontalLayout lLayout = new HorizontalLayout(); lLayout.setStyleName("ripla-help"); //$NON-NLS-1$ setCompositionRoot(lLayout); setWidth(SIZE_UNDEFINED, Unit.PIXELS); lLayout.setWidth(SIZE_UNDEFINED, Unit.PIXELS); Label lLabel = new Label("["); //$NON-NLS-1$ RiplaViewHelper.makeUndefinedWidth(lLabel); lLayout.addComponent(lLabel); lLayout.addComponent(createLinkButton(inCaption, inHelpContent, inWidth, inHeight)); lLabel = new Label("]"); //$NON-NLS-1$ RiplaViewHelper.makeUndefinedWidth(lLabel); lLayout.addComponent(lLabel); } private Button createLinkButton(final String inCaption, final URL inHelpContent, final int inWidth, final int inHeight) { final Button outLink = new Button(inCaption); outLink.setStyleName(BaseTheme.BUTTON_LINK); outLink.addClickListener(new Button.ClickListener() { @Override public void buttonClick(final ClickEvent inEvent) { final HelpWindow lHelpWindow = new HelpWindow(Activator .getMessages().getMessage("help.window.title"), //$NON-NLS-1$ getHelpText(inHelpContent), inWidth, inHeight); if (lHelpWindow.getParent() == null) { UI.getCurrent().addWindow(lHelpWindow); } lHelpWindow.setPosition(50, 50); } }); return outLink; } private String getHelpText(final URL inHelpContent) { String out = helpCache.get(inHelpContent); if (out == null) { try { out = readHelpContent(inHelpContent); } catch (final IOException exc) { LOG.error("Problem reading from {}!", inHelpContent, exc); //$NON-NLS-1$ out = String .format("<p>%s</p>", Activator.getMessages().getMessage("help.errormsg.readmsg")); //$NON-NLS-1$ //$NON-NLS-2$ } helpCache.put(inHelpContent, out); } return out; } private String readHelpContent(final URL inHelpContent) throws IOException { final StringBuilder outHtml = new StringBuilder(); InputStream lStream = null; InputStreamReader lReader = null; BufferedReader lBuffer = null; try { lStream = inHelpContent.openStream(); lReader = new InputStreamReader(lStream); lBuffer = new BufferedReader(lReader); String lLine; while ((lLine = lBuffer.readLine()) != null) { // NOPMD outHtml.append(lLine).append(NL); } } finally { if (lBuffer != null) { try { lBuffer.close(); } catch (final IOException exc) { LOG.error("Error encountered while closing the buffer!", exc); } } if (lReader != null) { try { lReader.close(); } catch (final IOException exc) { LOG.error("Error encountered while closing the reader!", exc); } } if (lStream != null) { try { lStream.close(); } catch (final IOException exc) { LOG.error("Error encountered while closing the stream!", exc); } } } return new String(outHtml); } // --- private static class HelpWindow extends Window { // private final transient Window helpWindow; // NOPMD by Luthiger on HelpWindow(final String inCaption, final String inHelpText, final int inWidth, final int inHeight) { super(inCaption); addStyleName("ripla-lookup"); //$NON-NLS-1$ setWidth(inWidth, Unit.PIXELS); setHeight(inHeight, Unit.PIXELS); final VerticalLayout lLayout = new VerticalLayout(); setContent(lLayout); lLayout.setSpacing(true); lLayout.setMargin(true); lLayout.setSpacing(true); lLayout.setSizeFull(); lLayout.setStyleName("ripla-view"); //$NON-NLS-1$ lLayout.addComponent(new Label(inHelpText, ContentMode.HTML)); final Button lClose = new Button(Activator.getMessages() .getMessage("lookup.window.button.close"), //$NON-NLS-1$ new Button.ClickListener() { @Override public void buttonClick(final ClickEvent inEvent) { UI.getCurrent().removeWindow(HelpWindow.this); } }); lLayout.addComponent(lClose); lLayout.setComponentAlignment(lClose, Alignment.BOTTOM_RIGHT); } protected void setPosition(final int inPositionX, final int inPositionY) { setPositionX(inPositionX); setPositionX(inPositionY); } } }