Revision: 642
Author: allain.lalonde
Date: Tue Aug 4 07:26:15 2009
Log: issue#111: merged phtml branch to trunk
http://code.google.com/p/piccolo2d/source/detail?r=642
Added:
/piccolo2d.java/trunk/core/src/main/java/edu/umd/cs/piccolo/nodes/PHtmlView.java
/piccolo2d.java/trunk/core/src/test/java/edu/umd/cs/piccolo/nodes/PHtmlViewTest.java
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/HtmlViewExample.java
Modified:
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java
=======================================
--- /dev/null
+++
/piccolo2d.java/trunk/core/src/main/java/edu/umd/cs/piccolo/nodes/PHtmlView.java
Tue Aug 4 07:26:15 2009
@@ -0,0 +1,442 @@
+/*
+ * Copyright (c) 1998-2008, University of Maryland
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
modification, are permitted provided
+ * that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice,
this list of conditions
+ * and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright
notice, this list of conditions
+ * and the following disclaimer in the documentation and/or other
materials provided with the
+ * distribution.
+ *
+ * None of the name of the University of Maryland, the name of the
Piccolo2D project, or the names of its
+ * contributors may be used to endorse or promote products derived from
this software without specific
+ * prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package edu.umd.cs.piccolo.nodes;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.geom.Point2D;
+import java.awt.geom.Rectangle2D;
+
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+import javax.swing.plaf.basic.BasicHTML;
+import javax.swing.text.Position;
+import javax.swing.text.View;
+
+import edu.umd.cs.piccolo.PNode;
+import edu.umd.cs.piccolo.util.PPaintContext;
+
+/**
+ * PHtml is a Piccolo node for rendering HTML text. It uses a JLabel under
the
+ * hood so you have the same restrictions regarding html as you have when
using
+ * standard Swing components (HTML 3.2 + subset of CSS 1.0).
+ *
+ * @author Chris Malley ([email protected])
+ * @author Sam Reid
+ * @author Allain Lalonde
+ */
+public class PHtmlView extends PNode {
+
+ private static final long serialVersionUID = 1L;
+
+ /** Default font to use if not overridden in the HTML markup. */
+ private static final Font DEFAULT_FONT = new JTextField().getFont();
+
+ /** Default font color to use if not overridden in the HTML markup */
+ private static final Color DEFAULT_HTML_COLOR = Color.BLACK;
+
+ /**
+ * The property name that identifies a change of this node's font (see
+ * {...@link #getFont getFont}). Both old and new value will be set in any
+ * property change event.
+ */
+ public static final String PROPERTY_FONT = "font";
+
+ /**
+ * The property code that identifies a change of this node's font (see
+ * {...@link #getFont getFont}). Both old and new value will be set in any
+ * property change event.
+ */
+ public static final int PROPERTY_CODE_FONT = 1 << 20;
+
+ /**
+ * The property name that identifies a change of this node's HTML (see
+ * {...@link #getHTML getHTML}). Both old and new value will be set in any
+ * property change event.
+ */
+ public static final String PROPERTY_HTML = "html";
+
+ /**
+ * The property code that identifies a change of this node's HTML (see
+ * {...@link #getHTML getHTML}). Both old and new value will be set in any
+ * property change event.
+ */
+ public static final int PROPERTY_CODE_HTML = 1 << 21;
+
+ /**
+ * The property name that identifies a change of this node's HTML
color (see
+ * {...@link #getHtml getHTMLColor}). Both old and new value will be set
in any
+ * property change event.
+ */
+ public static final String PROPERTY_HTML_COLOR = "html color";
+
+ /**
+ * The property code that identifies a change of this node's HTML
color (see
+ * {...@link #getHtml getHTMLColor}). Both old and new value will be set
in any
+ * property change event.
+ */
+ public static final int PROPERTY_CODE_HTML_COLOR = 1 << 22;
+
+ /** Underlying JLabel used to handle the rendering logic. */
+ private final JLabel htmlLabel;
+
+ /** Object that encapsulates the HTML rendering logic. */
+ private View htmlView;
+
+ /** Used to enforce bounds and wrapping on the HTML. */
+ private final Rectangle htmlBounds;
+
+ /**
+ * Creates an empty PHtml node with default font and color.
+ */
+ public PHtmlView() {
+ this(null, DEFAULT_FONT, DEFAULT_HTML_COLOR);
+ }
+
+ /**
+ * Creates a PHtml node that contains the provided HTML. It will have
+ * default font and color.
+ *
+ * @param html markup label should contain
+ */
+ public PHtmlView(final String html) {
+ this(html, DEFAULT_FONT, DEFAULT_HTML_COLOR);
+ }
+
+ /**
+ * Creates a PHtml node with the given markup and default html color.
+ *
+ * @param html markup label should contain
+ * @param htmlColor color that will be used unless overridden by the
markup
+ */
+ public PHtmlView(final String html, final Color htmlColor) {
+ this(html, DEFAULT_FONT, htmlColor);
+ }
+
+ /**
+ * Creates a PHtml node with the given markup and default HTML color.
+ *
+ * @param html markup label should contain
+ * @param font font that will be used unless overriden by the markup
+ * @param htmlColor color that will be used unless overridden by the
markup
+ */
+ public PHtmlView(final String html, final Font font, final Color
htmlColor) {
+ htmlLabel = new JLabel(html);
+ htmlLabel.setFont(font);
+ htmlLabel.setForeground(htmlColor);
+ htmlBounds = new Rectangle();
+ update();
+ }
+
+ /**
+ * @return HTML being rendered by this node
+ */
+ public String getHtml() {
+ return htmlLabel.getText();
+ }
+
+ /**
+ * Changes the HTML being rendered by this node.
+ *
+ * @param newHtml markup to swap with existing HTML
+ */
+ public void setHtml(final String newHtml) {
+ if (isNewHtml(newHtml)) {
+ final String oldHtml = htmlLabel.getText();
+ htmlLabel.setText(newHtml);
+ update();
+ firePropertyChange(PROPERTY_CODE_HTML, PROPERTY_HTML, oldHtml,
newHtml);
+ }
+ }
+
+ private boolean isNewHtml(final String html) {
+ if (html == null && getHtml() == null) {
+ return false;
+ }
+ else if (html == null || getHtml() == null) {
+ return true;
+ }
+ else {
+ return !htmlLabel.getText().equals(html);
+ }
+ }
+
+ /**
+ * Returns the default font being used when not overridden in the
markup.
+ *
+ * @return font being used when not overridden by the markup
+ */
+ public Font getFont() {
+ return htmlLabel.getFont();
+ }
+
+ /**
+ * Set the font of this PHtml. This may be overridden by the markup
using
+ * either styles or the font tag.
+ *
+ * @param newFont font to set as the default
+ */
+ public void setFont(final Font newFont) {
+ final Font oldFont = htmlLabel.getFont();
+ htmlLabel.setFont(newFont);
+ update();
+
+ firePropertyChange(PROPERTY_CODE_FONT, PROPERTY_FONT, oldFont,
newFont);
+ }
+
+ /**
+ * Gets the color used to render the HTML. If you want to get the
paint used
+ * for the node, use getPaint.
+ *
+ * @return the color used to render the HTML.
+ */
+ public Color getHtmlColor() {
+ return htmlLabel.getForeground();
+ }
+
+ /**
+ * Sets the color used to render the HTML. If you want to set the
paint used
+ * for the node, use setPaint.
+ *
+ * @param newColor new color to use when rendering HTML
+ */
+ public void setHtmlColor(final Color newColor) {
+ final Color oldColor = htmlLabel.getForeground();
+ htmlLabel.setForeground(newColor);
+ repaint();
+ firePropertyChange(PROPERTY_CODE_HTML_COLOR, PROPERTY_HTML_COLOR,
oldColor, newColor);
+ }
+
+ /**
+ * Applies all properties to the underlying JLabel, creates an
htmlView and
+ * updates bounds
+ */
+ private void update() {
+ htmlLabel.setSize(htmlLabel.getPreferredSize());
+ htmlView = BasicHTML.createHTMLView(htmlLabel, htmlLabel.getText()
== null ? "" : htmlLabel.getText());
+
+ final Rectangle2D bounds = getBounds();
+ htmlBounds.setRect(0, 0, bounds.getWidth(), bounds.getHeight());
+ repaint();
+ }
+
+ /** {...@inheritdoc} */
+ public boolean setBounds(final double x, final double y, final double
width, final double height) {
+ final boolean boundsChanged = super.setBounds(x, y, width, height);
+ update();
+ return boundsChanged;
+ }
+
+ /** {...@inheritdoc} */
+ public boolean setBounds(final Rectangle2D newBounds) {
+ final boolean boundsChanged = super.setBounds(newBounds);
+ update();
+ return boundsChanged;
+ }
+
+ /**
+ * Paints the node. The HTML string is painted last, so it appears on
top of
+ * any child nodes.
+ *
+ * @param paintContext the context in which painting is occurring
+ */
+ protected void paint(final PPaintContext paintContext) {
+ super.paint(paintContext);
+
+ if (htmlLabel.getWidth() != 0 && htmlLabel.getHeight() != 0) {
+ final Graphics2D g2 = paintContext.getGraphics();
+
+ htmlView.paint(g2, htmlBounds);
+ }
+ }
+
+ /**
+ * Returns the address specified in the link under the given point.
+ *
+ * @param clickedPoint
+ * @return String containing value of href for clicked link, or null
if no
+ * link clicked
+ */
+ public String getClickedAddress(final Point2D.Double clickedPoint) {
+ return getClickedAddress(clickedPoint.getX(), clickedPoint.getY());
+ }
+
+ /**
+ * Returns the address specified in the link under the given point.
+ *
+ * @param clickedPoint
+ * @return String containing value of href for clicked link, or null
if no
+ * link clicked
+ */
+ public String getClickedAddress(final double x, final double y) {
+ int position = pointToModelIndex(x, y);
+
+ final String html = htmlLabel.getText();
+
+ String address = null;
+
+ int currentPos = 0;
+ while (currentPos < html.length()) {
+ currentPos = html.indexOf('<', currentPos);
+ if (currentPos == -1 || position < currentPos) {
+ break;
+ }
+
+ final int tagStart = currentPos;
+ final int tagEnd = findTagEnd(html, currentPos);
+
+ if (tagEnd == -1) {
+ return null;
+ }
+
+ currentPos = tagEnd + 1;
+
+ final String tag = html.substring(tagStart, currentPos);
+
+ position += tag.length();
+
+ if ("</a>".equals(tag)) {
+ address = null;
+ }
+ else if (tag.startsWith("<a ")) {
+ address = extractHref(tag);
+ }
+ }
+
+ return address;
+ }
+
+ /**
+ * Returns the index into the raw text (without HTML) that the click
+ * occurred.
+ *
+ * @param x x component of the point clicked
+ * @param y y component of the point clicked
+ * @return index into the raw text (without HTML) that the click
occurred
+ */
+ private int pointToModelIndex(final double x, final double y) {
+ final Position.Bias[] biasReturn = new Position.Bias[1];
+ return htmlView.viewToModel((float) x, (float) y, getBounds(),
biasReturn);
+ }
+
+ /**
+ * Starting from the startPos, it finds the position at which the
given tag
+ * ends. Returns -1 if the end of the string was encountered before
the end
+ * of the tag was encountered.
+ *
+ * @param html raw HTML string being searched
+ * @param startPos where in the string to start searching for ">"
+ * @return index after the ">" character
+ */
+ private int findTagEnd(final String html, final int startPos) {
+ int currentPos = startPos;
+
+ currentPos++;
+
+ while (currentPos > 0 && currentPos < html.length() &&
html.charAt(currentPos) != '>') {
+ if (html.charAt(currentPos) == '\"') {
+ currentPos = html.indexOf('\"', currentPos + 1);
+ }
+ else if (html.charAt(currentPos) == '\'') {
+ currentPos = html.indexOf('\'', currentPos + 1);
+ }
+ currentPos++;
+ }
+
+ return currentPos == 0 || currentPos >= html.length() ? -1 :
currentPos + 1;
+ }
+
+ /**
+ * Given a tag, extracts the value of the href attribute, returns null
if
+ * none was found.
+ *
+ * @param tag from which to extract the href value
+ * @return href value without quotes or null if not found
+ */
+ private String extractHref(final String tag) {
+ int currentPos = 0;
+
+ final String href = null;
+
+ while (currentPos >= 0 && currentPos < tag.length() - 1) {
+ currentPos = tag.indexOf('=', currentPos + 1);
+ if (currentPos != -1 && isHrefAttributeAssignment(tag,
currentPos)) {
+ return extractHrefValue(tag, currentPos + 1);
+ }
+ }
+ return href;
+ }
+
+ /**
+ * Starting at the character after the equal sign of an href=..., it
extract
+ * the value. Handles single, double, and no quotes.
+ *
+ * @param tag
+ * @param startPos
+ * @return value of href or null if not found.
+ */
+ private String extractHrefValue(final String tag, final int startPos) {
+ int currentPos = startPos;
+
+ if (tag.charAt(currentPos) == '\"') {
+ final int startHref = currentPos + 1;
+ currentPos = tag.indexOf('\"', startHref);
+ return currentPos == -1 ? null : tag.substring(startHref,
currentPos);
+ }
+ else if (currentPos < tag.length() && tag.charAt(currentPos)
== '\'') {
+ final int startHref = currentPos + 1;
+ currentPos = tag.indexOf('\'', startHref);
+ return currentPos == -1 ? null : tag.substring(startHref,
currentPos);
+ }
+ else {
+ final int startHref = currentPos;
+
+ if (currentPos < tag.length()) {
+ do {
+ currentPos++;
+ } while (currentPos < tag.length() &&
tag.charAt(currentPos) != ' ' && tag.charAt(currentPos) != '>');
+ }
+ return tag.substring(startHref, currentPos);
+ }
+ }
+
+ /**
+ * Given the position in a string returns whether it points to the
equal
+ * sign of an href attribute.
+ *
+ * @param tag html code of the tag
+ * @param equalPos the index of the assignment
+ *
+ * @return true if to left of assignment is href
+ */
+ private boolean isHrefAttributeAssignment(final String tag, final int
equalPos) {
+ return tag.charAt(equalPos) == '=' && equalPos > 4 && "
href".equals(tag.substring(equalPos - 5, equalPos));
+ }
+}
=======================================
--- /dev/null
+++
/piccolo2d.java/trunk/core/src/test/java/edu/umd/cs/piccolo/nodes/PHtmlViewTest.java
Tue Aug 4 07:26:15 2009
@@ -0,0 +1,128 @@
+package edu.umd.cs.piccolo.nodes;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import junit.framework.TestCase;
+import edu.umd.cs.piccolo.MockPropertyChangeListener;
+import edu.umd.cs.piccolo.util.PBounds;
+
+public class PHtmlViewTest extends TestCase {
+
+ private MockPropertyChangeListener mockListener;
+
+ public void setUp() {
+ mockListener = new MockPropertyChangeListener();
+ }
+
+ public void testGetClickedAddressReturnsSingleQuotedAddress() {
+ PHtmlView html = new PHtmlView("<a
href='http://www.testing.com'>testing</a>");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("http://www.testing.com",
html.getClickedAddress(5,5));
+ }
+
+ public void testGetClickedAddressReturnsDoubleQuotedAddress() {
+ PHtmlView html = new PHtmlView("<a
href=\"http://www.testing.com\">testing</a>");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("http://www.testing.com",
html.getClickedAddress(5,5));
+ }
+
+ public void testBracketsAreValidInHrefs() {
+ PHtmlView html = new PHtmlView("<a href='a>b'>testing</a>");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("a>b", html.getClickedAddress(5,5));
+ }
+
+ public void testGetClickedAddressReturnsNullWhenInvalid() {
+ PHtmlView html = new PHtmlView("<a ='a>b'>testing</a>");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertNull(html.getClickedAddress(5,5));
+ }
+
+ public void testGetClickedAddressReturnsHrefWhenMissingEndAnchorTag() {
+ PHtmlView html = new PHtmlView("<a href='testing.com'>testing");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("testing.com", html.getClickedAddress(5,5));
+ }
+
+ public void testHandlesTricksyTitles() {
+ PHtmlView html = new PHtmlView("<a href=\"where to go\"
title=\"this is not the href='gotcha!' \">testing</a>");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("where to go", html.getClickedAddress(5,5));
+ }
+
+ public void testHandlesHrefWithoutQuotes() {
+ PHtmlView html = new PHtmlView("<a href=testing.com>testing</a>");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("testing.com", html.getClickedAddress(5,5));
+ }
+
+ public void testUnclosedTagsCauseIgnoreOfTag() {
+ PHtmlView html = new PHtmlView("<a href='testing.com' ");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertNull(html.getClickedAddress(5,5));
+ }
+
+ public void testMissingEndTagCausesRemainderOfHtmlToBeLinkTarget() {
+ PHtmlView html = new PHtmlView("<a href='testing.com'>Missing End
TAg ");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("testing.com", html.getClickedAddress(5,5));
+ }
+
+ public void testUnclosedQuotesCauseIgnoreOfLink() {
+ PHtmlView html = new PHtmlView("<a href='testing.com>testing");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertNull(html.getClickedAddress(5,5));
+ }
+
+ public void testEmptyAddressReturnsEmptyString() {
+ PHtmlView html = new PHtmlView("<a href=''>testing");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertEquals("", html.getClickedAddress(5,5));
+ }
+
+ public void testReturnsNullWhenClickOutsideLink() {
+ PHtmlView html = new PHtmlView("0123456789 <a href=#>testing</a>");
+ html.setBounds(new PBounds(0, 0, 100, 100));
+ assertNull(html.getClickedAddress(5,5));
+ }
+
+ public void testSetHtmlColorPersists() {
+ PHtmlView html = new PHtmlView();
+ html.setHtmlColor(Color.RED);
+ assertEquals(Color.RED, html.getHtmlColor());
+ }
+
+ public void testFontIsNotNullByDefault() {
+ PHtmlView html = new PHtmlView();
+ assertNotNull(html.getFont());
+ }
+
+ public void testHtmlColorIsNotNullByDefault() {
+ PHtmlView html = new PHtmlView();
+ assertNotNull(html.getHtmlColor());
+ }
+
+ public void testSetHtmlFiresEventOnChangeOnly() {
+ PHtmlView html = new PHtmlView();
+ html.addPropertyChangeListener(mockListener);
+ html.setHtml("testing");
+ assertEquals(1, mockListener.getPropertyChangeCount());
+ assertEquals(PHtmlView.PROPERTY_HTML,
mockListener.getPropertyChange(0).getPropertyName());
+ html.setHtml("testing");
+ assertEquals(1, mockListener.getPropertyChangeCount());
+ }
+
+ public void testSetHtmlToNullIsAllowed() {
+ PHtmlView html = new PHtmlView();
+ html.setHtml(null);
+ assertNull(html.getHtml());
+ }
+
+ public void testSetFontPerists() {
+ PHtmlView html = new PHtmlView();
+ Font font = Font.getFont("arial");
+ html.setFont(font);
+ assertSame(font, html.getFont());
+ }
+}
=======================================
--- /dev/null
+++
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/HtmlViewExample.java
Tue Aug 4 07:26:15 2009
@@ -0,0 +1,74 @@
+package edu.umd.cs.piccolo.examples;
+
+import java.awt.geom.Point2D;
+
+import javax.swing.JOptionPane;
+
+import edu.umd.cs.piccolo.PCanvas;
+import edu.umd.cs.piccolo.PNode;
+import edu.umd.cs.piccolo.event.PBasicInputEventHandler;
+import edu.umd.cs.piccolo.event.PInputEvent;
+import edu.umd.cs.piccolo.nodes.PHtmlView;
+import edu.umd.cs.piccolox.PFrame;
+
+public class HtmlViewExample extends PFrame {
+ private static final long serialVersionUID = 1L;
+ private StringBuffer html;
+
+ public HtmlViewExample() {
+ this(null);
+ }
+
+ public HtmlViewExample(final PCanvas aCanvas) {
+ super("HTMLExample", false, aCanvas);
+ }
+
+ public void initialize() {
+ html = new StringBuffer();
+ html.append("<p style='margin-bottom: 10px;'>");
+ html.append("This is an example <a href='#testing'>of what can</a>
be done with PHtml.");
+ html.append("</p>");
+ html.append("<p>It supports:</p>");
+ appendFeatures();
+
+ final PHtmlView htmlNode = new PHtmlView(html.toString());
+ htmlNode.setBounds(0, 0, 400, 400);
+ getCanvas().getLayer().addChild(htmlNode);
+
+ getCanvas().addInputEventListener(new PBasicInputEventHandler() {
+ public void mouseClicked(final PInputEvent event) {
+ final PNode clickedNode = event.getPickedNode();
+ if (!(clickedNode instanceof PHtmlView)) {
+ return;
+ }
+
+ final Point2D clickPoint =
event.getPositionRelativeTo(clickedNode);
+ final PHtmlView htmlNode = (PHtmlView) clickedNode;
+
+ final String url = htmlNode.getClickedAddress(clickPoint);
+ JOptionPane.showMessageDialog(null, url);
+ }
+ });
+ }
+
+ private void appendFeatures() {
+ html.append("<ul>");
+ html.append("<li><b>HTML</b> 3.2</li>");
+ html.append("<li><font style='color:red; font-style:
italic;'>Limited CSS 1.0</font></li>");
+ html.append("<li>Tables:");
+ appendTable();
+ html.append("</li>");
+ html.append("</ul>");
+ }
+
+ private void appendTable() {
+ html.append("<table border='1' cellpadding='2' cellspacing='0'>");
+ html.append("<tr><th>Col 1</th><th>Col 2</th></tr>");
+ html.append("<tr><td>Col 1 val</td><td>Col 2 val</td></tr>");
+ html.append("</table>");
+ }
+
+ public static void main(final String[] args) {
+ new HtmlViewExample();
+ }
+}
=======================================
---
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java
Tue Jul 28 12:46:54 2009
+++
/piccolo2d.java/trunk/examples/src/main/java/edu/umd/cs/piccolo/examples/ExampleRunner.java
Tue Aug 4 07:26:15 2009
@@ -107,13 +107,13 @@
BirdsEyeViewExample.class, CameraExample.class,
CenterExample.class, ChartLabelExample.class,
ClipExample.class, CompositeExample.class,
DynamicExample.class, EventHandlerExample.class,
FullScreenNodeExample.class, GraphEditorExample.class,
GridExample.class, GroupExample.class,
- HandleExample.class, HelloWorldExample.class,
HierarchyZoomExample.class, KeyEventFocusExample.class,
- LayoutExample.class, LensExample.class,
NavigationExample.class, NodeCacheExample.class,
- NodeEventExample.class, NodeExample.class,
NodeLinkExample.class, PanToExample.class,
- PathExample.class, PositionExample.class,
PositionPathActivityExample.class, PulseExample.class,
- ScrollingExample.class, SelectionExample.class,
SquiggleExample.class, StickyExample.class,
- StickyHandleLayerExample.class, StrokeExample.class,
TextExample.class, TooltipExample.class,
- TwoCanvasExample.class, WaitForActivitiesExample.class });
+ HandleExample.class, HelloWorldExample.class,
HierarchyZoomExample.class, HtmlViewExample.class,
+ KeyEventFocusExample.class, LayoutExample.class,
LensExample.class, NavigationExample.class,
+ NodeCacheExample.class, NodeEventExample.class,
NodeExample.class, NodeLinkExample.class,
+ PanToExample.class, PathExample.class,
PositionExample.class, PositionPathActivityExample.class,
+ PulseExample.class, ScrollingExample.class,
SelectionExample.class, SquiggleExample.class,
+ StickyExample.class, StickyHandleLayerExample.class,
StrokeExample.class, TextExample.class,
+ TooltipExample.class, TwoCanvasExample.class,
WaitForActivitiesExample.class });
}
private void addExampleButtons(final JPanel panel, final Class[]
exampleClasses) {
--~--~---------~--~----~------------~-------~--~----~
Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en
-~----------~----~----~----~------~----~------~--~---