/** * */ package org.geopublishing.atlasViewer.swing; import java.awt.Color; import java.awt.Component; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.net.URL; import javax.swing.JComponent; import javax.swing.JPopupMenu; import org.apache.log4j.Logger; import org.geopublishing.atlasViewer.AtlasConfig; import org.geopublishing.atlasViewer.GpCoreUtil; import org.geopublishing.atlasViewer.http.AtlasProtocol; import org.geopublishing.atlasViewer.http.AtlasProtocolException; import org.geopublishing.atlasViewer.map.Map; import org.lobobrowser.html.FormInput; import org.lobobrowser.html.HtmlRendererContext; import org.lobobrowser.html.UserAgentContext; import org.lobobrowser.html.gui.FrameSetPanel; import org.lobobrowser.html.gui.HtmlBlockPanel; import org.lobobrowser.html.gui.HtmlPanel; import org.lobobrowser.html.test.SimpleHtmlRendererContext; import org.lobobrowser.html.test.SimpleUserAgentContext; import org.w3c.dom.html2.HTMLElement; import de.schmitzm.swing.event.PipedMouseListener; /** * An HTML view based on the {@link HtmlPanel} of <i>LOBO browser Project</i>. */ public class HTMLInfoLoboBrowser extends HtmlPanel implements HTMLInfoPaneInterface { /** * */ private static final long serialVersionUID = 381089767702329569L; final static private Logger LOGGER = Logger.getLogger(HTMLInfoJPane.class); /** * This message is shows when no data can be found. */ final String NODATA_MSG = GpCoreUtil .R("HTMLInfoPane.NODATA.MSG.sorry_no_info_available"); /** Configuration of the atlas */ protected AtlasConfig atlasConfig = null; /** Popup menu for html view. */ protected JPopupMenu popupMenu = null; /** HTML context used for the HtmlPanel */ private SimpleHtmlRendererContext htmlContext; /** * Constructs a new instance. * * @param map * {@link Map} to load HTML for via {@link Map#getInfoURL()} */ public HTMLInfoLoboBrowser(Map map) { this(map.getInfoURL(), map.getAc()); }; /** * Constructs a new instance. * * @param url * Where to load the HTML from? * @param ac * {@link AtlasConfig} */ public HTMLInfoLoboBrowser(URL url, AtlasConfig ac) { super(); this.atlasConfig = ac; SimpleUserAgentContext simpleUserAgentContext = new SimpleUserAgentContext(); htmlContext = new SimpleHtmlRendererContext(this, simpleUserAgentContext) { /** * Indicates whether navigation (via * {@link #submitForm(String, URL, String, String, FormInput[])}) * should be asynchronous. This is overwritten here to avoid * problems with MigLayout rendering. MigLayout has a problem * waiting for a panel to determine its size. */ protected boolean isNavigationAsynchronous() { return false; } @Override public boolean onContextMenu(HTMLElement element, MouseEvent event) { if (HTMLInfoLoboBrowser.this.popupMenu != null) { HTMLInfoLoboBrowser.this.popupMenu.show( event.getComponent(), event.getX(), event.getY()); return false; } return super.onContextMenu(element, event); } }; showDocument(url); } /** * For Screenshots that are better printable */ @Override public void print(Graphics g) { final Color backup = getBackground(); setBackground(Color.white); super.print(g); setBackground(backup); } /** * Loads a document in the html view. * * @param url * source url */ @Override public void showDocument(URL url) { if (url == null) { this.showDocument(NODATA_MSG); return; } // When we had edit a page, there must be a navigate(.) // and reload(.) to show the new content (why??) // Note: because currentURL changes on navigate, we can // not do this check AFTER navigate(.)!! if (htmlContext.getCurrentURL() != null && htmlContext.getCurrentURL().equalsIgnoreCase(url.toString())) { htmlContext.navigate(url, ""); htmlContext.reload(); } else htmlContext.navigate(url, ""); // Document d = (Document) this.getRootNode(); // HTMLDocumentImpl rootNode2 = (HTMLDocumentImpl) // htmlContext.getHtmlPanel().getRootNode(); } /** * Loads a document in the html view. * * @param url * source url */ @Override public void showDocument(String content) { setHtml(content, "", htmlContext); } /** * Returns {@code this}. */ @Override public JComponent getComponent() { return this; } /** * Returns {@code true}, because {@link HtmlPanel} already provides * scrolling. */ @Override public boolean hasScrollPane() { return true; } /** * Connects a popup menu to the html view. */ @Override public void connectPopupMenu(JPopupMenu menu) { this.popupMenu = menu; } /** * Returns the html context used for the browser. */ private SimpleHtmlRendererContext getContext() { return this.htmlContext; } /** * Modifies the {@link HtmlBlockPanel} created by the super-method. The * existing {@link MouseListener MouseListeners} are replaced by * {@link PipedMouseListener PipedMouseListeners} to catch the * {@link AtlasProtocolException} when clicking on a link with special * {@link AtlasProtocol}. Instead of following the link, the special atlas * protocol is performed using ({@link #performSpecialLink(String)}. */ @Override protected HtmlBlockPanel createHtmlBlockPanel(UserAgentContext ucontext, HtmlRendererContext rcontext) { HtmlBlockPanel blockPanel = super.createHtmlBlockPanel(ucontext, rcontext); pipeMouseListeners(blockPanel); return blockPanel; } /** * Modifies the {@link FrameSetPanel} created by the super-method. The * existing {@link MouseListener MouseListeners} are replaced by * {@link PipedMouseListener PipedMouseListeners} to catch the * {@link AtlasProtocolException} when clicking on a link with special * {@link AtlasProtocol}. Instead of following the link, the special atlas * protocol is performed using ({@link #performSpecialLink(String)}. */ @Override protected FrameSetPanel createFrameSetPanel() { FrameSetPanel framesetPanel = super.createFrameSetPanel(); pipeMouseListeners(framesetPanel); return framesetPanel; } /** * Replaces all {@link MouseListener MouseListeners} of a {@link Component} * with a {@link PipedMouseListener}, which catches an * {@link AtlasProtocolException} to perform atlas protocol links. * * @see #performSpecialLink(String) */ private void pipeMouseListeners(Component comp) { for (MouseListener l : comp.getMouseListeners()) { comp.removeMouseListener(l); comp.addMouseListener(new PipedMouseListener(l) { @Override public void mouseReleased(MouseEvent e) { try { super.mouseReleased(e); } catch (AtlasProtocolException err) { // LOGGER.debug("Haha!!! Abgefangen!"); performSpecialLink(err.getURL()); } } }); } } /** * Performs a link by * {@link GpCoreUtil#performSpecialHTMLLink(java.awt.Component, AtlasConfig, String, String)} * * @param destURL */ protected void performSpecialLink(String destURL) { boolean specialLinkPerformed = AtlasProtocol.performLink(this, atlasConfig, getContext().getCurrentURL(), destURL); if (!specialLinkPerformed) throw new AtlasProtocolException(destURL, "Atlas protocol could not be performed: " + destURL); } }