/** * BrowserComparison.java * (c) Peter Bielik and Radek Burget, 2011-2012 * * SwingBox 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 3 of the License, or * (at your option) any later version. * * SwingBox 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. * * You should have received a copy of the GNU Lesser General Public License * along with SwingBox. If not, see <http://www.gnu.org/licenses/>. * */ package org.fit.cssbox.swingbox.demo; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.io.IOException; import java.net.URL; import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; import javax.swing.event.HyperlinkEvent; import javax.swing.event.HyperlinkListener; import javax.swing.text.html.HTMLEditorKit; import org.fit.cssbox.css.CSSNorm; import org.fit.cssbox.css.DOMAnalyzer; import org.fit.cssbox.css.DOMAnalyzer.Origin; import org.fit.cssbox.io.DOMSource; import org.fit.cssbox.io.DefaultDOMSource; import org.fit.cssbox.io.DefaultDocumentSource; import org.fit.cssbox.io.DocumentSource; import org.fit.cssbox.layout.Box; import org.fit.cssbox.layout.BrowserCanvas; import org.fit.cssbox.layout.ElementBox; import org.fit.cssbox.swingbox.BrowserPane; import org.fit.cssbox.swingbox.util.GeneralEvent; import org.fit.cssbox.swingbox.util.GeneralEvent.EventType; import org.fit.cssbox.swingbox.util.GeneralEventListener; import org.w3c.dom.Document; /** * This demo provides 3 result of same location by 3 renderers. You will see CSSBox, SwingBox and JEditorPane + HTMLEditorKit. * Use the "GO!" button to start action. * * @author Peter Bielik * @version 1.0 * @since 1.0 - 22.4.2011 */ public class BrowserComparison extends JFrame { private static final long serialVersionUID = 3078719188136612454L; BrowserPane swingbox = new BrowserPane(); BrowserCanvas cssbox = null; JEditorPane editorkit = new JEditorPane(); JTextField txt = new JTextField("http://www.aktualne.cz", 60); JScrollPane contentScroll = new JScrollPane(); /** * Creates new instance of this demo application. */ public BrowserComparison() { init(); loadPage(txt.getText()); } private void init() { JPanel panel = new JPanel(new BorderLayout()); JPanel tmp = new JPanel(new FlowLayout(FlowLayout.LEFT)); JButton btn = new JButton(" GO! "); tmp.add(txt); tmp.add(btn); btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Thread t = new Thread(new Runnable() { @Override public void run() { loadPage(txt.getText()); } }); t.setDaemon(true); t.start(); } }); txt.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { Thread t = new Thread(new Runnable() { @Override public void run() { loadPage(txt.getText()); } }); t.setDaemon(true); t.start(); } }); JTabbedPane tab = new JTabbedPane(JTabbedPane.TOP); tab.addTab("SwingBox", new JScrollPane(swingbox)); tab.addTab("CSSBox", contentScroll); tab.addTab("JEditorPane + HTMLEditorKit", new JScrollPane(editorkit)); panel.add(tmp, BorderLayout.NORTH); panel.add(tab, BorderLayout.CENTER); setContentPane(panel); swingbox.addHyperlinkListener(new BrowserComparisonHyperlinkHandler(this)); swingbox.addGeneralEventListener(new GeneralEventListener() { private long time; @Override public void generalEventUpdate(GeneralEvent e) { if (e.event_type == EventType.page_loading_begin) { time = System.currentTimeMillis(); } else if (e.event_type == EventType.page_loading_end) { System.out.println("SwingBox: page loaded in: " + (System.currentTimeMillis() - time) + " ms"); } } }); editorkit.setEditorKit(new HTMLEditorKit()); editorkit.setEditable(false); editorkit.addHyperlinkListener(new HyperlinkListener() { @Override public void hyperlinkUpdate(HyperlinkEvent e) { //txt.setText(e.getURL().toString()); //loadPage(txt.getText()); } }); contentScroll.setViewportView(cssbox); contentScroll.addComponentListener(new java.awt.event.ComponentAdapter() { @Override public void componentResized(java.awt.event.ComponentEvent e) { if (cssbox != null && cssbox instanceof BrowserCanvas) { ((BrowserCanvas) cssbox).createLayout(contentScroll.getSize()); contentScroll.repaint(); } } }); setResizable(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setPreferredSize(new Dimension(1200, 1000)); setTitle("Demo"); pack(); setLocationRelativeTo(null); setVisible(true); } public void loadPage(String page) { if (!page.startsWith("http:") && !page.startsWith("ftp:") && !page.startsWith("file:")) { page = "http://" + page; } txt.setText(page); loadPage_editorkit(page); loadPage_cssbox(page); loadPage_swingbox(page); } private void loadPage_swingbox(String url) { try { swingbox.setPage(new URL(url)); } catch (IOException e) { e.printStackTrace(); } } private void loadPage_cssbox(String urlstring) { try { DocumentSource docSource = new DefaultDocumentSource(urlstring); DOMSource parser = new DefaultDOMSource(docSource); Document doc = parser.parse(); DOMAnalyzer da = new DOMAnalyzer(doc, docSource.getURL()); da.attributesToStyles(); da.addStyleSheet(null, CSSNorm.stdStyleSheet(), Origin.AGENT); da.addStyleSheet(null, CSSNorm.userStyleSheet(), Origin.AGENT); da.getStyleSheets(); cssbox = new BrowserCanvas(da.getRoot(), da, docSource.getURL()); cssbox.getConfig().setLoadBackgroundImages(true); cssbox.getConfig().setLoadImages(true); cssbox.createLayout(contentScroll.getSize()); cssbox.addMouseListener(new MouseListener() { public void mouseClicked(MouseEvent e) { System.out.println("Click: " + e.getX() + ":" + e.getY()); //canvasClick(e.getX(), e.getY()); Box node = locateBox(cssbox.getViewport(), e.getX(), e.getY()); System.out.println("Box: " + node); if (node != null) { node.drawExtent(cssbox.getImageGraphics()); cssbox.repaint(); } } public void mousePressed(MouseEvent e) { } public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } }); contentScroll.setViewportView(cssbox); } catch (Exception e) { e.printStackTrace(); } } private void loadPage_editorkit(String url) { try { editorkit.setPage(new URL(url)); } catch (IOException e) { e.printStackTrace(); } } /** * Locates a box from its position */ private Box locateBox(Box root, int x, int y) { if (root.isVisible()) { Box found = null; //Rectangle bounds = root.getAbsoluteContentBounds().intersection(root.getClipBlock().getAbsoluteContentBounds()); Rectangle bounds = root.getAbsoluteBounds(); if (bounds.contains(x, y)) { found = root; System.out.println("Fnd: " + found); found.drawExtent(((BrowserCanvas)cssbox).getImageGraphics()); } //find if there is something smallest that fits among the child boxes if (root instanceof ElementBox) { ElementBox eb = (ElementBox) root; for (int i = eb.getStartChild(); i < eb.getEndChild(); i++) { Box inside = locateBox(((ElementBox) root).getSubBox(i), x, y); if (inside != null) { if (found == null) found = inside; else { if (inside.getAbsoluteBounds().width * inside.getAbsoluteBounds().height < found.getAbsoluteBounds().width * found.getAbsoluteBounds().height) found = inside; } } } } return found; } else return null; } /** * The main method. * * @param args * no arguments needed. */ public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new BrowserComparison(); } }); } }