You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@isis.apache.org by da...@apache.org on 2012/12/08 15:56:02 UTC

[35/53] [partial] ISIS-188: making structure of component viewers consistent

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/tree/TreeBrowserFrameTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/tree/TreeBrowserFrameTest.java b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/tree/TreeBrowserFrameTest.java
new file mode 100644
index 0000000..c7ed6f7
--- /dev/null
+++ b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/tree/TreeBrowserFrameTest.java
@@ -0,0 +1,199 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.dnd.viewer.tree;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.runtimes.dflt.testsupport.IsisSystemWithFixtures;
+import org.apache.isis.viewer.dnd.DummyContent;
+import org.apache.isis.viewer.dnd.DummyView;
+import org.apache.isis.viewer.dnd.DummyViewSpecification;
+import org.apache.isis.viewer.dnd.DummyWorkspaceView;
+import org.apache.isis.viewer.dnd.TestToolkit;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.composite.MasterDetailPanel;
+
+/*
+ * Note that the frame only contains two views and no additional spacing, hence no drawing. The
+ * width is the total of the two decorated views, while the height is the largest of the two.
+ */
+public class TreeBrowserFrameTest {
+
+    @Rule
+    public IsisSystemWithFixtures iswf = IsisSystemWithFixtures.builder().build();
+
+    private DummyWorkspaceView dummyWorkspace;
+    private MasterDetailPanel frame;
+
+    @Before
+    public void setUp() throws Exception {
+        
+        TestToolkit.createInstance();
+
+        dummyWorkspace = new DummyWorkspaceView();
+
+        final DummyContent content = new DummyContent() {};
+        final DummyViewSpecification rhsSpec = new DummyViewSpecification();
+        rhsSpec.setupCreatedViewsSize(new Size(200, 300));
+        final DummyViewSpecification lhsSpec = new DummyViewSpecification();
+        lhsSpec.setupCreatedViewsSize(new Size(350, 250));
+        frame = new MasterDetailPanel(content, rhsSpec, lhsSpec);
+        frame.setParent(dummyWorkspace);
+    }
+
+    @Test
+    public void testViewsParents() throws Exception {
+        final View[] subviews = frame.getSubviews();
+        assertEquals(2, subviews.length);
+        final View lhsView = subviews[0];
+        assertEquals(frame, lhsView.getParent());
+        final View rhsView = subviews[1];
+        assertEquals(frame, rhsView.getParent());
+    }
+
+    @Test
+    public void testLeftViewSize() {
+        // width => width of view (150) + scroll border (0) + resize border (7)
+        // => 159
+        // height => height of view (250) + scroll border (0) => 250
+        assertEquals(leftView(), leftView().getView());
+        assertEquals(new Size(350 + 7, 250), leftView().getView().getRequiredSize(Size.createMax()));
+    }
+
+    @Test
+    public void testInitialBlankViewSize() {
+        // 120 is the minimum width given to the blan view by the
+        // MasterDetailPanel
+        assertEquals(new Size(120, 0), rightView().getRequiredSize(Size.createMax()));
+    }
+
+    @Test
+    public void testInitialBlankViewSizeWithinALimitedSpace() {
+        assertEquals(new Size(100, 0), rightView().getRequiredSize(new Size(100, 200)));
+    }
+
+    private View leftView() {
+        return frame.getSubviews()[0];
+    }
+
+    private View rightView() {
+        return frame.getSubviews()[1];
+    }
+
+    @Test
+    public void testTotalRequiredSize() {
+        assertEquals(new Size(350 + 7 + 120, 250), frame.getRequiredSize(Size.createMax()));
+    }
+
+    @Test
+    public void testInitialSize() {
+        assertEquals(new Size(), frame.getSize());
+    }
+
+    @Test
+    public void testLayoutInReducedSpaceReducesSizeOfLeftView() {
+        layoutFrameInReducedSpace();
+        assertEquals("retains original size", new Size(400 - 120, 200), leftView().getSize());
+
+        // scroll border 16 pixels; resize border 5 pixels; total 21 pixels
+        // assertEquals("width reduces", new Size(100, 200),
+        // rightView.getSize());
+
+        // assertEquals(new Location(100, 0), rightView.getLocation());
+    }
+
+    @Test
+    public void testLayoutInReducedSpaceLeaveBlanksWidthUnchangedAsIsAlreadyMinimumSize() {
+        layoutFrameInReducedSpace();
+        assertEquals("retains original size", new Size(120, 200), rightView().getSize());
+    }
+
+    @Test
+    public void testLayoutInReducedSpaceReducesSizeOfRightView() {
+        frame.removeView(rightView());
+        frame.addView(new DummyView(350, 210));
+        layoutFrameInReducedSpace();
+        final int expectedWidth = 400 - 206 - 1; // total width -
+        assertEquals("retains original size", new Size(expectedWidth, 210), rightView().getSize());
+    }
+
+    @Test
+    public void testLayoutInReducedSpaceReducesSizeOfLeftViewInProportion() {
+        frame.removeView(rightView());
+        frame.addView(new DummyView(350, 210));
+        layoutFrameInReducedSpace();
+        assertEquals("retains original size", new Size(200 + 7 - 1, 210), leftView().getSize());
+    }
+
+    /*
+     * public void testLayoutInReducedSpaceReducesSizeOfRightView() {
+     * layoutFrameInReducedSpace(); assertEquals("retains original size", new
+     * Size(120, 200), rightView().getSize()); }
+     */
+
+    private void layoutFrameInReducedSpace() {
+        frame.invalidateLayout();
+        frame.setSize(new Size(400, 200));
+        frame.layout();
+    }
+
+    @Test
+    public void testLayoutGivesLeftViewAllItWants() {
+        layoutFrameInRequiredSpace();
+        assertEquals("retains original size", new Size(350 + 7, 250), leftView().getSize());
+    }
+
+    @Test
+    public void testLayoutGivesRightViewAllItWants() {
+        layoutFrameInRequiredSpace();
+        assertEquals("height should be the same as left (including borders)", new Size(120, 250), rightView().getSize());
+    }
+
+    @Test
+    public void testLayoutLocatesLeftViewOnLeft() {
+        layoutFrameInRequiredSpace();
+        assertEquals(new Location(), leftView().getLocation());
+    }
+
+    @Test
+    public void testLayoutLocatesRightViewNextToLeftView() {
+        layoutFrameInRequiredSpace();
+        assertEquals(new Location(350 + 7, 0), rightView().getLocation());
+    }
+
+    private void layoutFrameInRequiredSpace() {
+        frame.invalidateLayout();
+        frame.setSize(new Size(350 + 7 + 120, 250));
+        frame.layout();
+    }
+
+    @Test
+    public void testSubviews() {
+        final View[] subviews = frame.getSubviews();
+        assertEquals(leftView().getView(), subviews[0]);
+        assertEquals(rightView().getView(), subviews[1]);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/AbstractViewTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/AbstractViewTest.java b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/AbstractViewTest.java
new file mode 100644
index 0000000..92fc80c
--- /dev/null
+++ b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/AbstractViewTest.java
@@ -0,0 +1,101 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.dnd.viewer.view;
+
+import junit.framework.TestCase;
+
+import org.apache.isis.viewer.dnd.drawing.Bounds;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Padding;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewAreaType;
+import org.apache.isis.viewer.dnd.view.base.AbstractView;
+import org.apache.isis.viewer.dnd.view.content.NullContent;
+
+public class AbstractViewTest extends TestCase {
+    private AbstractView av;
+
+    public static void main(final String[] args) {
+        junit.textui.TestRunner.run(AbstractViewTest.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        av = new AbstractView(new NullContent()) {
+        };
+        super.setUp();
+    }
+
+    public void testBounds() {
+        assertEquals(new Location(), av.getLocation());
+        assertEquals(new Size(), av.getSize());
+        assertEquals(new Bounds(), av.getBounds());
+
+        av.setLocation(new Location(10, 20));
+        assertEquals(new Location(10, 20), av.getLocation());
+        assertEquals(new Size(), av.getSize());
+        assertEquals(new Bounds(10, 20, 0, 0), av.getBounds());
+
+        av.setSize(new Size(30, 40));
+        assertEquals(new Location(10, 20), av.getLocation());
+        assertEquals(new Size(30, 40), av.getSize());
+        assertEquals(new Bounds(10, 20, 30, 40), av.getBounds());
+
+        av.setBounds(new Bounds(new Location(50, 60), new Size(70, 80)));
+        assertEquals(new Location(50, 60), av.getLocation());
+        assertEquals(new Size(70, 80), av.getSize());
+        assertEquals(new Bounds(50, 60, 70, 80), av.getBounds());
+    }
+
+    public void testPadding() {
+        assertEquals(new Padding(0, 0, 0, 0), av.getPadding());
+    }
+
+    public void testViewAreaType() {
+        final Location loc = new Location(10, 10);
+        assertEquals(ViewAreaType.CONTENT, av.viewAreaType(loc));
+    }
+
+    public void testBoundsSetSizeAndLocation() throws Exception {
+        final Location l = new Location();
+        final Size z = new Size();
+        final View view = new AbstractView(new NullContent()) {
+            @Override
+            public void setLocation(final Location location) {
+                l.translate(location);
+            }
+
+            @Override
+            public void setSize(final Size size) {
+                z.extend(size);
+            }
+        };
+
+        view.setBounds(new Bounds(20, 30, 40, 50));
+        assertEquals(new Location(20, 30), l);
+        assertEquals(new Size(40, 50), z);
+    }
+
+    public void testRequiredSizeIsLimitedToTheMaximumSize() throws Exception {
+        assertEquals(Size.createMax(), av.getRequiredSize(Size.createMax()));
+        assertEquals(new Size(100, 50), av.getRequiredSize(new Size(100, 50)));
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/configurable/GridLayoutTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/configurable/GridLayoutTest.java b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/configurable/GridLayoutTest.java
new file mode 100644
index 0000000..c679ce6
--- /dev/null
+++ b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/configurable/GridLayoutTest.java
@@ -0,0 +1,235 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.dnd.viewer.view.configurable;
+
+import junit.framework.Assert;
+
+import org.jmock.Expectations;
+import org.jmock.auto.Mock;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2;
+import org.apache.isis.core.testsupport.jmock.JUnitRuleMockery2.Mode;
+import org.apache.isis.runtimes.dflt.testsupport.IsisSystemWithFixtures;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.composite.GridLayout;
+
+public class GridLayoutTest {
+
+    @Rule
+    public IsisSystemWithFixtures iswf = IsisSystemWithFixtures.builder().build();
+
+    @Rule
+    public JUnitRuleMockery2 context = JUnitRuleMockery2.createFor(Mode.INTERFACES_AND_CLASSES);
+
+    private static final int CONTAINER_HEIGHT = 100;
+    private static final int CONTAINER_WIDTH = 200;
+    
+    @Mock
+    private View container;
+
+    private int viewIndex = 1;
+    private GridLayout layout;
+    
+    @Before
+    public void setup() {
+        layout = new GridLayout();
+    }
+
+    private void createContainer(final View[] views) {
+        context.checking(new Expectations() {
+            {
+                allowing(container).getSubviews();
+                will(returnValue(views));
+            }
+        });
+    }
+
+    private View createView(final int width, final int height) {
+        final View subview = context.mock(View.class, "view" + viewIndex++);
+        context.checking(new Expectations() {
+            {
+                allowing(subview).getRequiredSize(new Size(Integer.MAX_VALUE, Integer.MAX_VALUE));
+                will(returnValue(new Size(width, height)));
+            }
+        });
+        return subview;
+    }
+
+    private View createLayoutView(final int x, final int y, final int width, final int height) {
+        final View view = context.mock(View.class, "view" + viewIndex++);
+        context.checking(new Expectations() {
+            {
+                allowing(view).getRequiredSize(new Size(CONTAINER_WIDTH, CONTAINER_HEIGHT));
+                will(returnValue(new Size(width, height)));
+                
+                one(view).setSize(new Size(width, height));
+                one(view).setLocation(new Location(x, y));
+            }
+        });
+        return view;
+    }
+
+
+    @Test
+    public void noContentSize() {
+        createContainer(new View[0]);
+        Assert.assertEquals(new Size(), layout.getRequiredSize(container));
+    }
+
+    @Test
+    public void sizeEqualToTheOnlySubview() {
+        createContainer(new View[] { createView(20, 40) });
+        Assert.assertEquals(new Size(20, 40), layout.getRequiredSize(container));
+    }
+
+    @Test
+    public void positionVertically() {
+        final View view1 = createLayoutView(0, 0, 20, 10);
+        final View view2 = createLayoutView(0, 10, 20, 10);
+        final View view3 = createLayoutView(0, 20, 20, 10);
+        final View view4 = createLayoutView(0, 30, 20, 10);
+        createContainer(new View[] { view1, view2, view3, view4 });
+
+        layout.layout(container, new Size(CONTAINER_WIDTH, CONTAINER_HEIGHT));
+    }
+
+    @Test
+    public void positionVerticallyOver2Colums() {
+        final View view1 = createLayoutView(0, 0, 20, 10);
+        final View view2 = createLayoutView(20, 0, 20, 10);
+        final View view3 = createLayoutView(0, 10, 20, 10);
+        final View view4 = createLayoutView(20, 10, 20, 10);
+        final View view5 = createLayoutView(0, 20, 20, 10);
+        createContainer(new View[] { view1, view2, view3, view4, view5 });
+
+        layout.setOrientation(GridLayout.COLUMNS);
+        layout.setSize(2);
+        layout.layout(container, new Size(CONTAINER_WIDTH, CONTAINER_HEIGHT));
+    }
+
+    @Test
+    public void positionVerticallyOver3Colums() {
+        final View view1 = createLayoutView(0, 0, 20, 10);
+        final View view2 = createLayoutView(20, 0, 20, 10);
+        final View view3 = createLayoutView(40, 0, 20, 10);
+        final View view4 = createLayoutView(0, 10, 20, 10);
+        final View view5 = createLayoutView(20, 10, 20, 10);
+        createContainer(new View[] { view1, view2, view3, view4, view5 });
+
+        layout.setOrientation(GridLayout.COLUMNS);
+        layout.setSize(3);
+        layout.layout(container, new Size(CONTAINER_WIDTH, CONTAINER_HEIGHT));
+    }
+
+    @Test
+    public void positionHorizontallyOver2Rows() {
+        final View view1 = createLayoutView(0, 0, 20, 10);
+        final View view2 = createLayoutView(0, 10, 20, 10);
+        final View view3 = createLayoutView(20, 0, 20, 10);
+        final View view4 = createLayoutView(20, 10, 20, 10);
+        final View view5 = createLayoutView(40, 0, 20, 10);
+        createContainer(new View[] { view1, view2, view3, view4, view5 });
+
+        layout.setOrientation(GridLayout.ROWS);
+        layout.setSize(2);
+        layout.layout(container, new Size(CONTAINER_WIDTH, CONTAINER_HEIGHT));
+    }
+
+    @Test
+    public void positionHorizontally() {
+        final View view1 = createLayoutView(0, 0, 20, 10);
+        final View view2 = createLayoutView(20, 0, 20, 10);
+        final View view3 = createLayoutView(40, 0, 20, 10);
+        final View view4 = createLayoutView(60, 0, 20, 10);
+        createContainer(new View[] { view1, view2, view3, view4 });
+
+        layout.setOrientation(GridLayout.ROWS);
+        layout.layout(container, new Size(CONTAINER_WIDTH, CONTAINER_HEIGHT));
+    }
+
+    @Test
+    public void heightSumOfTwoViews() {
+        createContainer(new View[] { createView(10, 40), createView(10, 30) });
+        Assert.assertEquals(70, layout.getRequiredSize(container).getHeight());
+    }
+
+    @Test
+    public void widthSumOfTwoViews() {
+        layout.setOrientation(GridLayout.ROWS);
+        createContainer(new View[] { createView(20, 10), createView(30, 10) });
+        Assert.assertEquals(50, layout.getRequiredSize(container).getWidth());
+    }
+
+    @Test
+    public void widthMaxTwoViews() {
+        createContainer(new View[] { createView(25, 10), createView(20, 10) });
+        Assert.assertEquals(25, layout.getRequiredSize(container).getWidth());
+    }
+
+    @Test
+    public void heightMaxOfTwoViews() {
+        layout.setOrientation(GridLayout.ROWS);
+        createContainer(new View[] { createView(10, 40), createView(10, 30) });
+        Assert.assertEquals(40, layout.getRequiredSize(container).getHeight());
+    }
+
+    @Test
+    public void sizeOver2Columns() {
+        final View view1 = createView(30, 10);
+        final View view2 = createView(20, 10);
+        final View view3 = createView(20, 10);
+        createContainer(new View[] { view1, view2, view3 });
+
+        layout.setOrientation(GridLayout.COLUMNS);
+        layout.setSize(2);
+        Assert.assertEquals(new Size(50, 20), layout.getRequiredSize(container));
+    }
+
+    @Test
+    public void sizeOver3Columns() {
+        final View view1 = createView(30, 10);
+        final View view2 = createView(20, 10);
+        final View view3 = createView(20, 10);
+        final View view4 = createView(40, 10);
+        createContainer(new View[] { view1, view2, view3, view4 });
+
+        layout.setOrientation(GridLayout.COLUMNS);
+        layout.setSize(2);
+        Assert.assertEquals(new Size(70, 20), layout.getRequiredSize(container));
+    }
+
+    @Test
+    public void sizeOver2Rows() {
+        final View view1 = createView(20, 10);
+        final View view2 = createView(20, 10);
+        final View view3 = createView(20, 10);
+        createContainer(new View[] { view1, view2, view3 });
+
+        layout.setOrientation(GridLayout.ROWS);
+        layout.setSize(2);
+        Assert.assertEquals(new Size(40, 20), layout.getRequiredSize(container));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/field/TextFieldBorderTest.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/field/TextFieldBorderTest.java b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/field/TextFieldBorderTest.java
new file mode 100644
index 0000000..8120ddb
--- /dev/null
+++ b/component/viewer/dnd/impl/src/test/java/org/apache/isis/viewer/dnd/viewer/view/field/TextFieldBorderTest.java
@@ -0,0 +1,47 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+
+package org.apache.isis.viewer.dnd.viewer.view.field;
+
+import junit.framework.TestCase;
+
+import org.apache.log4j.Level;
+import org.apache.log4j.Logger;
+
+import org.apache.isis.viewer.dnd.DummyView;
+import org.apache.isis.viewer.dnd.drawing.Padding;
+import org.apache.isis.viewer.dnd.field.TextFieldBorder;
+
+public class TextFieldBorderTest extends TestCase {
+
+    public static void main(final String[] args) {
+        junit.textui.TestRunner.run(TextFieldBorderTest.class);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        Logger.getRootLogger().setLevel(Level.OFF);
+    }
+
+    public void testBorder() {
+        final DummyView mockView = new DummyView();
+        final TextFieldBorder border = new TextFieldBorder(mockView);
+        assertEquals(new Padding(2, 2, 2, 2), border.getPadding());
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/pom.xml
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/pom.xml b/component/viewer/dnd/pom.xml
deleted file mode 100644
index ad5f593..0000000
--- a/component/viewer/dnd/pom.xml
+++ /dev/null
@@ -1,146 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-  
-         http://www.apache.org/licenses/LICENSE-2.0
-         
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-	<modelVersion>4.0.0</modelVersion>
-
-	<parent>
-		<groupId>org.apache.isis</groupId>
-		<artifactId>isis-parent</artifactId>
-		<version>0.3.1-SNAPSHOT</version>
-		<relativePath>../../../isis-parent/pom.xml</relativePath>
-	</parent>
-
-	<groupId>org.apache.isis.viewer</groupId>
-	<artifactId>isis-dnd-viewer</artifactId>
-
-	<name>Drag-n-Drop Viewer</name>
-
-	<properties>
-        <siteBaseDir>.</siteBaseDir>
-		<relativeUrl/>
-
-		<docbkxGuideTitle>Apache Isis DnD Viewer</docbkxGuideTitle>
-        <docbkxGuideSubTitle>Configuration, Customization and Deployment Guide</docbkxGuideSubTitle>
-		<docbkxGuideName>isis-dnd-viewer</docbkxGuideName>
-    </properties>
-
-    <!-- used in Site generation for relative references. -->
-    <url>http://incubator.apache.org/isis/${relativeUrl}</url>
-
-	<build>
-		<plugins>
-            <plugin>
-                <groupId>com.agilejava.docbkx</groupId>
-                <artifactId>docbkx-maven-plugin</artifactId>
-                <inherited>false</inherited>
-            </plugin>
-		</plugins>
-	</build>
-
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-project-info-reports-plugin</artifactId>
-				<version>${maven-project-info-reports-plugin}</version>
-                <inherited>false</inherited>
-                <configuration>
-                	<dependencyLocationsEnabled>false</dependencyLocationsEnabled>
-                </configuration>
-                <reportSets>
-                    <reportSet>
-                        <inherited>false</inherited>
-                        <reports>
-                            <report>dependencies</report>
-                            <report>dependency-convergence</report>
-                            <report>plugins</report>
-                            <report>summary</report>
-                        </reports>
-                    </reportSet>
-                </reportSets>
-            </plugin>
-        </plugins>
-    </reporting>
-
-	<dependencies>
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-unittestsupport</artifactId>
-            <version>0.3.1-SNAPSHOT</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-runtime</artifactId>
-            <version>0.3.1-SNAPSHOT</version>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-integtestsupport</artifactId>
-	            <version>0.3.1-SNAPSHOT</version>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-runtime</artifactId>
-	        <version>0.3.1-SNAPSHOT</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-inmemory-objectstore</artifactId>
-            <version>0.3.1-SNAPSHOT</version>
-            <type>test-jar</type>
-            <scope>test</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.apache.isis.core</groupId>
-            <artifactId>isis-cglib-bytecode</artifactId>
-            <version>0.3.1-SNAPSHOT</version>
-            <scope>test</scope>
-        </dependency>
-
-		<dependency>
-			<groupId>org.easymock</groupId>
-			<artifactId>easymock</artifactId>
-			<scope>test</scope>
-		</dependency>
-
-		<dependency>
-			<groupId>org.jmock</groupId>
-			<artifactId>jmock-legacy</artifactId>
-			<scope>test</scope>
-		</dependency>
-
-        <dependency>
-            <groupId>org.jmock</groupId>
-            <artifactId>jmock-junit4</artifactId>
-            <scope>test</scope>
-        </dependency>
-
-	</dependencies>
-
-</project>

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/src/docbkx/guide/images/debug-graphics.png
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/docbkx/guide/images/debug-graphics.png b/component/viewer/dnd/src/docbkx/guide/images/debug-graphics.png
deleted file mode 100755
index 5f26128..0000000
Binary files a/component/viewer/dnd/src/docbkx/guide/images/debug-graphics.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/src/docbkx/guide/images/debug-system.png
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/docbkx/guide/images/debug-system.png b/component/viewer/dnd/src/docbkx/guide/images/debug-system.png
deleted file mode 100755
index 6ea85b4..0000000
Binary files a/component/viewer/dnd/src/docbkx/guide/images/debug-system.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/src/docbkx/guide/images/debug-view.png
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/docbkx/guide/images/debug-view.png b/component/viewer/dnd/src/docbkx/guide/images/debug-view.png
deleted file mode 100755
index 98f7b9a..0000000
Binary files a/component/viewer/dnd/src/docbkx/guide/images/debug-view.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/src/docbkx/guide/images/debug-viewer.png
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/docbkx/guide/images/debug-viewer.png b/component/viewer/dnd/src/docbkx/guide/images/debug-viewer.png
deleted file mode 100755
index 7373975..0000000
Binary files a/component/viewer/dnd/src/docbkx/guide/images/debug-viewer.png and /dev/null differ

http://git-wip-us.apache.org/repos/asf/isis/blob/eb613703/component/viewer/dnd/src/docbkx/guide/isis-dnd-viewer.xml
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/docbkx/guide/isis-dnd-viewer.xml b/component/viewer/dnd/src/docbkx/guide/isis-dnd-viewer.xml
deleted file mode 100644
index 5fbf8e3..0000000
--- a/component/viewer/dnd/src/docbkx/guide/isis-dnd-viewer.xml
+++ /dev/null
@@ -1,1298 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-"file:./src/docbkx/dtd-4.5/docbookx.dtd">
-<!--
-  Licensed to the Apache Software Foundation (ASF) under one
-  or more contributor license agreements.  See the NOTICE file
-  distributed with this work for additional information
-  regarding copyright ownership.  The ASF licenses this file
-  to you under the Apache License, Version 2.0 (the
-  "License"); you may not use this file except in compliance
-  with the License.  You may obtain a copy of the License at
-
-        http://www.apache.org/licenses/LICENSE-2.0
-
-  Unless required by applicable law or agreed to in writing,
-  software distributed under the License is distributed on an
-  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-  KIND, either express or implied.  See the License for the
-  specific language governing permissions and limitations
-  under the License.
--->
-<book>
-  <bookinfo>
-    <title><?eval ${docbkxGuideTitle}?></title>
-
-    <subtitle><?eval ${docbkxGuideSubTitle}?></subtitle>
-
-    <releaseinfo><?eval ${project.version}?></releaseinfo>
-
-    <authorgroup>
-      <author>
-        <firstname>Robert</firstname>
-
-        <surname>Matthews</surname>
-      </author>
-    </authorgroup>
-
-    <legalnotice>
-      <para>Permission is granted to make and distribute verbatim copies of
-      this manual provided that the copyright notice and this permission
-      notice are preserved on all copies.</para>
-    </legalnotice>
-  </bookinfo>
-
-  <!-- front matter -->
-
-  <toc></toc>
-
-  <preface id="preface">
-    <title>Preface</title>
-
-    <para><emphasis>Apache Isis</emphasis> is designed to allow programmers
-    rapidly develop domain-driven applications following the <ulink
-    url="http://en.wikipedia.org/wiki/Naked_Objects">Naked Objects</ulink>
-    pattern. It is made up of a core framework plus a number of alternate
-    implementations, and supports various viewers and object stores. Apache
-    Isis is hosted at the <ulink url="http://incubator.apache.org/isis">Apache
-    Foundation</ulink>, and is licensed under <ulink
-    url="http://www.apache.org/licenses/LICENSE-2.0.html">Apache Software
-    License v2</ulink>.</para>
-
-    <para>This guide is written for programmers looking to customize,
-    configure and deploy <emphasis>Apache Isis</emphasis> applications using
-    the <emphasis>DnD viewer</emphasis> as the primary user interface.
-    Deployment takes in both standalone operation and running in client/server
-    mode.</para>
-  </preface>
-
-  <!-- main content -->
-
-  <part>
-    <title>Users Guide</title>
-
-    <chapter>
-      <title>Using the DnD Viewer</title>
-
-      <abstract>
-        <para>*** yada</para>
-      </abstract>
-
-      <section>
-        <title>*** yada</title>
-
-        <para></para>
-      </section>
-
-      <section>
-        <title>Using Perspectives</title>
-
-        <para>A perspective represents an end-users' desktop perspective; that
-        is icons/links for domain services and domain objects). The
-        <emphasis>dnd viewer</emphasis> allows users to customize their
-        perspective:</para>
-
-        <itemizedlist>
-          <listitem>
-            <para>To remove a service icon right-click on the grey border and
-            select the close option.</para>
-          </listitem>
-
-          <listitem>
-            <para>To add a service select the Services... option from the
-            application menu (accessed by right-clicking on the application
-            background) and drag the required service onto the desktop.</para>
-          </listitem>
-        </itemizedlist>
-
-        <para></para>
-
-        <para></para>
-
-        <para></para>
-      </section>
-    </chapter>
-  </part>
-
-  <part>
-    <title>Programmers Guide</title>
-
-    <partintro>
-      <para>This part of the documentation is for programmers who are
-      developing applications using Isis, and wish to configure or customize
-      the DnD viewer for their needs.</para>
-    </partintro>
-
-    <chapter>
-      <title>***</title>
-
-      <abstract>
-        <para>*** yada yada</para>
-      </abstract>
-
-      <sect1>
-        <title>***</title>
-
-        <para><emphasis>*** yada yada</emphasis></para>
-      </sect1>
-
-      <sect1>
-        <title>Viewer Properties</title>
-
-        <para>The look of the viewing mechanism can be changed by using
-        different fonts, colours and icons. All viewer properties for the drag
-        and drop user interface have a common root of
-        <methodname>isis.viewer.dnd</methodname> and for the HTML interface
-        <methodname>isis.viewer.html</methodname>.</para>
-
-        <sect2>
-          <title>Initial size and location</title>
-
-          <para>The size and location of the application within the windowing
-          systems can be specified using the
-          <methodname>initial.size</methodname> and
-          <methodname>initial.location</methodname> properties. If not
-          specified the size defaults to nearly full screen and location to
-          near the top-left corner.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.initial.size = 800 x 600
-isis.viewer.dnd.initial.location = 100, 200</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Large icon size</title>
-
-          <para>The width of the resource icons (as shown on the desktop) can
-          be specified using the <methodname>large-icon-size</methodname>
-          property. If not specified it will default to 34 pixels.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.large-icon-size = 48</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Resize border</title>
-
-          <para>The amount of space allocated for the resize border on a text
-          field can be set using the
-          <methodname>field-resize-border</methodname> property. Unless set
-          this will default to 5 pixels.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.field-resize-border = 3</programlisting>
-
-          <para>The amount of space allocated for the resize border on a tree
-          view can be set using the
-          <methodname>tree-resize-border</methodname> property. Unless set
-          this will default to 5 pixels.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.tree-resize-border = 3</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Exploration menu options</title>
-
-          <para>To turn off exploration menus set the
-          <methodname>show-exploration</methodname> property to
-          <emphasis>off</emphasis>.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.show-exploration = off</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Double buffering</title>
-
-          <para>The whole viewer is double buffered by default, but this can
-          be turned off by setting the <methodname>double-buffer</methodname>
-          property to <emphasis>off</emphasis>.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.double-buffer = off</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Background logo</title>
-
-          <para>A background logo can be added to the workspace using the
-          <methodname>logo-background</methodname> properties. The image
-          sub-property indicates that a logo should be displayed and what
-          image to use. The size and location are then optional.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.logo-background.image = background.jpg
-isis.viewer.dnd.logo-background.size = 400 x 300
-isis.viewer.dnd.logo-background.location = 100, 200</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Loading images from files</title>
-
-          <para>Images are normally loaded directly from the Java resources
-          (accessed via the class path) or as files within the <filename
-          class="directory" moreinfo="none">images</filename> directory. If
-          necessary the loading of files can be suspended so they are only
-          loaded from resources. This is done via the
-          <methodname>load-images-from-files</methodname> property.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.load-images-from-files = false</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Padding</title>
-
-          <programlisting format="linespecific">isis.viewer.dnd.hpadding = 5
-isis.viewer.dnd.vpadding = 5</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Default image</title>
-
-          <para>The default image is the one used if the image file/resource
-          that should be used cannot be found. This simply ensures that an
-          image is available for all icons. The default image can be changed
-          using the <methodname>default-image</methodname> property.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.default-image = square.png</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Image directory</title>
-
-          <para>The directory in which the images are to be found can be
-          specified via the <methodname>image-directory</methodname>
-          property.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.image-directory = graphics</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>View specifications</title>
-
-          <para>The views used to render objects and collection are created by
-          view specifications. These specifications are installed at start up
-          and can be added to. The <methodname>specification.view</methodname>
-          property lists the specifications to load.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.specification.view = org.apache.isis.viewer.skylark.basic.FormSpecification, \
-        org.apache.isis.viewer.skylark.basic.ListSpecification</programlisting>
-
-          <para>The viewer has a set of default set of views that it loads up,
-          these include specifications for forms, lists, tree browsers and
-          tables. To disable this default set, normally so you can explicitly
-          set up the specification list as above, use the
-          <methodname>specification.defaults</methodname> property with the
-          <emphasis>false</emphasis> value.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.specification.defaults =off
-</programlisting>
-
-          <para>Specific field and subview types can be also specified, so
-          they no longer use the built-in default. These all have the same
-          property name root of
-          <methodname>isis.viewer.dnd.specification</methodname> and
-          are:-</para>
-
-          <itemizedlist>
-            <listitem>
-              <para><property moreinfo="none">field.image</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">field.color</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">field.password</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property
-              moreinfo="none">field.wrappedtext</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">field.checkbox</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">field.text</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">field.empty</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">icon.subview</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">icon.object</property></para>
-            </listitem>
-
-            <listitem>
-              <para><property moreinfo="none">icon.resource</property></para>
-            </listitem>
-          </itemizedlist>
-
-          <para>The following example causes all logical properties to be
-          shown using the standard text field rather than the default check
-          box.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.specification.field.checkbox = \
-        org.apache.isis.viewer.skylark.basic.TextFieldSpecification</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Fonts</title>
-
-          <para>Fonts can be specified using the following font property
-          names:-</para>
-
-          <itemizedlist>
-            <listitem>
-              <para><methodname>control</methodname>, for the text in control
-              widgets such as buttons</para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>label</methodname>, for the field
-              labels</para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>large-icon</methodname>, for the icons on the
-              desktop such as resources</para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>menu</methodname>, for the menu options</para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>normal</methodname>, for edit fields and
-              object labels in fields</para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>small-title</methodname>, for windows
-              bars</para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>status</methodname>, for text on the status
-              bar</para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>title</methodname>, for titling objects</para>
-            </listitem>
-          </itemizedlist>
-
-          <para>A particular font can be specified for an area by
-          specifying</para>
-
-          <programlisting format="linespecific">org.apache.isis.viewer.dnd.font.&lt;area&gt;=&lt;font&gt;</programlisting>
-
-          <para>Where the <methodname>&lt;area&gt;</methodname> is the name
-          and the <methodname>&lt;font&gt;</methodname> is specified according
-          the <methodname>Font.decode()</methodname> specification
-          (<classname>see java.awt.Font</classname>). This essentially is a
-          concatenation of the name, style and size as below:</para>
-
-          <programlisting format="linespecific">&lt;logical font name&gt;-&lt;style&gt;-&lt;point size&gt;</programlisting>
-
-          <para>In addition to the font the amount of space between lines of
-          text can also be specified.</para>
-
-          <programlisting format="linespecific">org.apache.isis.viewer.dnd.spacing.&lt;area&gt;=&lt;pixels&gt;</programlisting>
-        </sect2>
-
-        <sect2>
-          <title>Colours</title>
-
-          <para>The colour properties are prefixed with
-          <methodname>isis.viewer.dnd.color</methodname> and take a numerical
-          value. The most useful form is in hexadecimal where the six digits
-          are grouped into twos to represent the red, green and blue
-          components. The following example specifies the colours green, red
-          and black respectively.</para>
-
-          <screen format="linespecific">isis.viewer.dnd.color.normal=0x0000FF
-isis.viewer.dnd.color.label=0xFF0000
-isis.viewer.dnd.color.text.edit=0xFFFFFF</screen>
-
-          <para>The basic colour scheme is made up of a palette of eight
-          colours: three primary, three secondary and black and white. These
-          form the basis for many of the other colour properties. The colour
-          property names are:-</para>
-
-          <itemizedlist>
-            <listitem>
-              <para><methodname>black</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>white</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>primary1</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>secondary1</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>primary2</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>secondary2</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>primary3</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>secondary3</methodname></para>
-            </listitem>
-          </itemizedlist>
-
-          <para>The backgrounds of the application, the windows and the menus
-          can be set with the following properties:-</para>
-
-          <itemizedlist>
-            <listitem>
-              <para><methodname>background.application</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>background.window</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>background.content-menu</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>background.value-menu</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>background.view-menu</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>background.workspace-menu</methodname></para>
-            </listitem>
-          </itemizedlist>
-
-          <para>In addition to the setting of a colour for all window
-          backgrounds you can also set the colour for a specific view
-          type.</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.color.background.window.List=0x00ffff</programlisting>
-
-          <para>The colours of the text on the menus can be specified with the
-          following properties:-</para>
-
-          <itemizedlist>
-            <listitem>
-              <para><methodname>menu.normal</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>menu.disabled</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>menu.reversed</methodname></para>
-            </listitem>
-          </itemizedlist>
-
-          <para>The state of the views can be reflected by its colour. The
-          following colour properties can be specified (only the identified
-          property is based on the core colour scheme, all others are unique
-          by default):-</para>
-
-          <itemizedlist>
-            <listitem>
-              <para><methodname>identified</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>valid</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>invalid</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>active</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>error</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>out-of-synch</methodname></para>
-            </listitem>
-          </itemizedlist>
-
-          <para>There are a number of properties relating to text for text
-          fields. These are the colour of text when editing it, the cursor's
-          colour, the colour of the highlight when selecting text, and the
-          colour of text when it has focus for editing but has not been
-          changed yet.</para>
-
-          <itemizedlist>
-            <listitem>
-              <para><methodname>text.edit</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>text.cursor</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>text.highlight</methodname></para>
-            </listitem>
-
-            <listitem>
-              <para><methodname>text.saved</methodname></para>
-            </listitem>
-          </itemizedlist>
-        </sect2>
-
-        <sect2>
-          <title>Echo character</title>
-
-          <para>The single character used to represent an entered character in
-          a password field can be specified with the
-          <methodname>echo</methodname> property, for example to change it
-          from the default * to a hash specify the following:</para>
-
-          <programlisting format="linespecific">isis.viewer.dnd.echo=#</programlisting>
-        </sect2>
-      </sect1>
-    </chapter>
-  </part>
-
-  <chapter>
-    <title>Diagnostics</title>
-
-    <para></para>
-
-    <sect1>
-      <title>Debugging from within the DND viewer</title>
-
-      <para>While using the NOF through the Skylark viewer you a have a number
-      of ways of looking at the state of the system. Every view, including the
-      desktop, has debug options that can be accessed by
-      Crtl-Shift-right-clicking. The following options might be useful to
-      you.</para>
-
-      <sect2>
-        <title>From the desktop menu</title>
-
-        <para></para>
-
-        <itemizedlist>
-          <listitem>
-            <para><emphasis>Log Level
-            OFF/ERROR/WARN/INFO/DEBUG</emphasis></para>
-
-            <para>Change the log level in Log4j</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Debug graphics on/off</emphasis></para>
-
-            <para>Turn on or off the debug drawing within the viewer. This
-            sets/clears the <varname>AbstractView.debug </varname>variable,
-            which is used within draw methods to do additional drawing for
-            debug purposes.</para>
-
-            <mediaobject>
-              <imageobject>
-                <imagedata fileref="images/debug-graphics.png" />
-              </imageobject>
-            </mediaobject>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Show mouse spy</emphasis></para>
-
-            <para>Brings up a debug window showing details about the mouse and
-            it position within the view hierarchy.</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Restart object loader/persistor</emphasis></para>
-
-            <para>Calls <methodname>reset</methodname> on the
-            <classname>ObjectAdapterLoader</classname> and
-            <classname>ObjectAdapterPersistor</classname> objects. This should
-            clear all the objects and adapters from memory, forcing them to be
-            reloaded from persistent storage. It is important not have any
-            open objects on the screen as these will no longer be linked to
-            the known objects and might cause problems.</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Debug system</emphasis></para>
-
-            <para>Brings up a debug frame showing debug details for the main
-            components of the system. These include the persistor, loader,
-            configuration, and specification loader.</para>
-
-            <mediaobject>
-              <imageobject>
-                <imagedata fileref="images/debug-system.png" />
-              </imageobject>
-            </mediaobject>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Debug viewer</emphasis></para>
-
-            <para>Brings up a debug frame showing debug details for the
-            Skylark viewer.</para>
-
-            <mediaobject>
-              <imageobject>
-                <imagedata fileref="images/debug-viewer.png" />
-              </imageobject>
-            </mediaobject>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Dump log to snapshot</emphasis></para>
-
-            <para>Creates a Log4j snapshot, which is send to each of the
-            snapshot appenders. This is only enabled if Log4j is setup with
-            one or more snapshot appenders.</para>
-          </listitem>
-        </itemizedlist>
-      </sect2>
-
-      <sect2>
-        <title>From the view</title>
-
-        <para></para>
-
-        <para>1. From a view we have these debug options available on the
-        <emphasis>view</emphasis> menu:</para>
-
-        <itemizedlist>
-          <listitem>
-            <para><emphasis>Refresh view</emphasis></para>
-
-            <para>Causes the view to be redisplayed after rereading the state
-            of the view's content. This only affects the values and not the
-            reference objects.</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Invalidate content</emphasis></para>
-
-            <para>Flag the view's content as invalid causing the view to be
-            recreated.</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Invalidate layout</emphasis></para>
-
-            <para>Flag the view's layout as invalid causing the view to be
-            relaid out.</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Debug view</emphasis></para>
-
-            <para>Brings up a debug frame showing debug details for the
-            current view/object. These include the adapter's state, the domain
-            object graph, the object specification, the view's content object,
-            the structure of the view, and a full listing of the drawing done
-            to render the view.</para>
-
-            <mediaobject>
-              <imageobject>
-                <imagedata fileref="images/debug-view.png" />
-              </imageobject>
-            </mediaobject>
-          </listitem>
-        </itemizedlist>
-
-        <para>2. Also from the view we have these debug options available on
-        the <emphasis>object</emphasis> menu:</para>
-
-        <itemizedlist>
-          <listitem>
-            <para><emphasis>Destroy object</emphasis></para>
-
-            <para>Forces a destory call to the object persistor.</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Clear resolve</emphasis></para>
-
-            <para>Forces the object's resolve state back to
-            <emphasis>Ghost</emphasis>.</para>
-          </listitem>
-
-          <listitem>
-            <para><emphasis>Debug view</emphasis></para>
-
-            <para>Brings up a debug frame showing debug details for the
-            current view/object (see above).</para>
-          </listitem>
-        </itemizedlist>
-      </sect2>
-
-      <sect2>
-        <title>The DebugInfo interface and the debug viewer</title>
-
-        <para>The framework provides a viewer for showing the debug details
-        about any object in the system that implements the
-        <classname>DebugInfo</classname> interface. The
-        <classname>InfoDebugFrame</classname> shows one or more tabs of
-        <classname>DebugInfo</classname> objects. As it is Java Frame it can
-        be set up as follows.</para>
-
-        <programlisting format="linespecific">import org.apache.isis.viewer.dnd.awt.InfoDebugFrame;
-:
-:
-InfoDebugFrame frame = new InfoDebugFrame();
-frame.setInfo(objectSupportingDebugInfo);
-frame.show();</programlisting>
-
-        <para>The <methodname>setInfo</methodname> mehtod is overloaded to
-        take an array of debug objects.</para>
-
-        <para>To make an object displayable implement the
-        <classname>DebugInfo</classname> interface. The
-        <methodname>debugTitle()</methodname> should return a simple title,
-        and the <methodname>debugData(DebugString)</methodname> should add
-        details to the <classname>DebugString</classname> object to build up
-        suitable debug output. <classname>DebugString</classname> is an
-        appender, like <classname>StringBuffer</classname>, but which provides
-        indentation and a way to add label and detail pairs.</para>
-      </sect2>
-    </sect1>
-  </chapter>
-
-  <part>
-    <title>Contributors Guide</title>
-
-    <partintro>
-      <para>This part of the documentation is for committers or contributors
-      who wish to enhance, extend (or just bugfix) the DnD viewer
-      itself.</para>
-    </partintro>
-
-    <chapter>
-      <title>Design</title>
-
-      <para>The DND viewer basically displays a set of
-      <classname>View</classname> objects, where each view is render its
-      assigned <classname>Content</classname> object. A content is something
-      like a message, a service object, a domain object or a field within a
-      domain object. If a view is to show more than one thing (eg the contents
-      of a list, or the properties of an object) then the view must provide a
-      set of subviews and arrange those views is some orderly fashion. The
-      viewer provides <classname>AbstractCompositeView</classname> for this
-      purpose. A further subclass,
-      <classname>CompositeViewBuilder</classname>, provides an even better
-      mechanism by allowing a ViewBuilder to be assigned to create and add the
-      subviews, while an <classname>AbstractBuilderDecorator</classname> can
-      be assigned to layout the subviews. Many builders and layouts are
-      provided that can be combined to create specific views.</para>
-
-      <para>In addtion to this creation process the views themselves can be
-      decorated to provide specific behaviour and looks.</para>
-
-      <section>
-        <title>Specification</title>
-
-        <para>Each available view is created via a
-        <classname>ViewSpecification</classname> instance. An instance of each
-        specification is registered with the view factory, either directly
-        (via the <classname>ViewFactory</classname> instance) or indirectly
-        via the configuration file. To register a view specification at
-        runtime add something like the following to the
-        <filename>isis.properties</filename>, or other properties,
-        file.</para>
-
-        <programlisting>isis.viewer.dnd.specification.view=org.apache.isis.viewer.dnd.view.calendar.CalendarSpecification, \
-    org.apache.isis.viewer.dnd.view.form.WindowExpandableFormSpecification
-</programlisting>
-
-        <para>Each specification determines if it can display a particular
-        object, by returning <literal>true</literal>/<literal>false</literal>
-        from the <methodname>canDisplay(Content)</methodname> method.</para>
-
-        <para>The name of the specification, provided via the
-        <methodname>getName</methodname> method, is used to create a list of
-        available views that the user can select from.</para>
-
-        <para>An open view (<methodname>isOpen</methodname> returning
-        <literal>true</literal>) indicates that the view shows content of the
-        object, as opposed to just the object itself.</para>
-
-        <para>A subview (<methodname>isSubview</methodname> returning
-        <literal>true</literal>) indicates that the view can be used as a
-        child part of another view. Otherwise the view is a root view,
-        standing by itself.</para>
-
-        <para>A view that can be replaced by another view within the screen
-        area is indicated by <methodname>isReplaceable</methodname> returning
-        <literal>true</literal>.</para>
-
-        <para>TODO what is <methodname>isAligned</methodname>?</para>
-      </section>
-
-      <section>
-        <title>View</title>
-
-        <para>Displayed objects are rendered using an instance of
-        <classname>View</classname>. View classes are typically created by
-        subclassing <classname>AbstractView.</classname></para>
-
-        <para>Views are designed so that the can be decorated to add looks and
-        behaviour. Such decorators are typically created by subclassing
-        AbstractViewDecorator.</para>
-
-        <para></para>
-
-        <section>
-          <title>Sizing</title>
-
-          <para>Views can request a specific area to render themselves within.
-          The parent view, starting from the top-level workspace, asks each
-          component view by calling the view's
-          <methodname>getRequiredSize</methodname> method. The parent passes
-          in the maximum size so that component can make the most of the
-          available space.</para>
-        </section>
-
-        <section>
-          <title>Layout</title>
-
-          <para>Each view provides a layout mechanism (via the
-          <methodname>layout(Size)</methodname> method) that should size and
-          position each of its subviews. This is not applicable to node views,
-          which by definition have no children. The size passed in the amount
-          of space available to the view. Before the layout method is called
-          the getRequiredSize method is called to determine the optimum size
-          to provide for the view. The laying out of a view should only occur
-          when the contents have changed so a flag should be maintained to
-          track this. The <methodname>invalidateLayout</methodname> method
-          should set this flag so the the viewer can indicate when a view
-          needs to be re-laid out. It should also pass up the request to
-          ensure that any work done by the superclass will also be completed.
-          The example below shows a typical layout scenario.</para>
-
-          <programlisting>    public void invalidateLayout() {
-        super.invalidateLayout();
-        invalidLayout = true;
-    }
-
-    public void layout(final Size maximumSize) {
-        if (invalidLayout) {
-            Size formSize = form.getRequiredSize(maximumSize);
-            form.setSize(formSize);
-            form.layout(maximumSize);
-            form.setLocation(new Location(0,0));
-            
-            Size collectionSize = collection.getRequiredSize(maximumSize);
-            collection.setSize(collectionSize);
-            collection.layout(maximumSize);
-            collection.setLocation(new Location(0, formSize.getHeight()));
-
-            invalidLayout = false;
-        }
-    }</programlisting>
-        </section>
-
-        <section>
-          <title>Drawing</title>
-
-          <para>The parent asks each component to draw itself by calling the
-          view's <methodname>draw</methodname> method. A Canvas object is
-          passed in that is then used to do the actual drawing.</para>
-
-          <para>A view can also provide a <methodname>print</methodname>
-          method for drawing to a printing surface. In the AbstractView class
-          this simply delegates to the draw method to allow the one method to
-          render both to screen and paper.</para>
-        </section>
-
-        <section>
-          <title>Window border</title>
-
-          <para>A view can be given a border by chaining a
-          <classname>WindowBorder</classname> decorator to a view as follows,
-          indicating if the window is scrollable with the second
-          parameter.</para>
-
-          <programlisting>new WindowBorder(new SimpleView(content, axis), false);</programlisting>
-
-          <para>The style of the border can be changed by providing a
-          <classname>BorderDrawing</classname> class that is used for all
-          instances.</para>
-        </section>
-      </section>
-
-      <section>
-        <title>Composite views</title>
-
-        <para>Although you can create your own subclass of
-        <classname>View</classname> that contain other views, it can be a lot
-        simpler to extend the <classname>AbstractCompositeView</classname>
-        class or to use the <classname>CompositeViewBuilder</classname> class
-        in conjunction with some <classname>ViewBuilder</classname> objects to
-        build and layout a view. The bulk of the work in a composite view,
-        however, is in passing the events etc on to the right subview, and
-        this is something the <classname>AbstractCompositeView</classname>
-        view does for you.</para>
-
-        <para>For a view that you want to construct and layout extend the
-        <classname>AbstractCompositeView</classname> class and add methods to
-        build the view, determine its required size and layout its components.
-        The following example shows a view for summarising an object. The
-        <methodname>buildView</methodname> method calls addView for each of
-        the component view, which in this example are the default views for
-        each field object. The <methodname>getMaximumSize</methodname> method
-        add the heights of all the component views togther and finds the
-        maximum width. The <methodname>doLayout</methodname> method simply
-        sets the size of each component to its required size and sets the
-        vertical position so they are stacked vertically.</para>
-
-        <programlisting>public class SummaryView extends AbstractCompositeView {
-
-    public SummaryView(Content content, ViewSpecification specification, ViewAxis viewAxis) {
-        super(content, specification, viewAxis);
-    }
-
-    protected void buildView() {
-        ObjectSpecification spec = getContent().getSpecification();
-        AuthenticationSession session = IsisContext.getAuthenticationSession();
-        ObjectAdapter target = getContent().getAdapter();
-        ObjectAssociation[] fields = spec.getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, target));
-        for (int i = 0; i &lt; fields.length; i++) {
-            Content fieldContent = Toolkit.getContentFactory().createFieldContent(fields[i], target, fields[i].get(target));
-            if (fieldContent instanceof TextParseableContent) {
-                View view = Toolkit.getViewFactory().createFieldView((TextParseableField) fieldContent, null);
-                addView(view);
-            }
-            if (fieldContent instanceof ObjectContent) {
-                View view = Toolkit.getViewFactory().createView(new ViewRequirement(fieldContent, ViewRequirement.CLOSED));
-                addView(view);
-            }
-        }
-    }
-
-    public Size getMaximumSize() {
-        Size size = new Size(0, 0);
-        for (View view : getSubviews()) {
-            Size viewSize = view.getMaximumSize();
-            size.extendHeight(viewSize.getHeight());
-            size.ensureWidth(viewSize.getWidth());
-        }
-        return size;
-    }
-
-    protected void doLayout(Size maximumSize) {
-        int y = 0;
-        for (View view : getSubviews()) {
-            Size viewSize = view.getMaximumSize();
-            view.setSize(viewSize);
-            view.layout(maximumSize);
-            view.setLocation(new Location(0, y));
-            y += viewSize.getHeight();
-        }
-    }
-
-    public String toString() {
-        return "Form" + getId();
-    }
-}</programlisting>
-
-        <para>The following example shows this</para>
-
-        <programlisting>
-public class MyListSpecification extends AbstractCompositeViewSpecification {
-
-    public MyListSpecification() {
-        SubviewSpec subviewSpec = new SubviewSpec() {
-            public View createSubview(final Content content, final ViewAxis axis) {
-                return new InternalFormSpecification().createView(content, axis);
-            }
-
-            public View decorateSubview(final View subview) {
-                return new EmptyBorder(3, new BackgroundBorder(new LineBorder(1, 8, new IconBorder(subview))));
-            }
-        };
-        builder = new StackLayout(new CollectionElementBuilder(subviewSpec));
-    }
-
-    public String getName() {
-        return "My List";
-    }
-
-    public boolean canDisplay(final Content content) {
-        return content.isCollection();
-    }
-}
-</programlisting>
-
-        <section>
-          <title>Master/detail panel</title>
-
-          <para>A panel with a set of closed objects on one side and an opened
-          object on the other side can be created using the
-          <classname>MasterDetailPanel</classname> class. When the master view
-          is created a <classname>SelectableViewAxis</classname> is created
-          and passed to each item so that it can indicate that is selected and
-          tell the main view to show that object on the detail side. For this
-          to work the item view must detect the
-          <classname>SelectableViewAxis</classname> and use it to set and show
-          that item's selected state. This is currently provided
-          TreeNodeBorder and by the
-          <classname>SubviewIconSpecification</classname>, which adds a
-          <classname>SelectedBorder</classname> decorator to the icon.</para>
-
-          <para>The detail side is initially created with BlankView object.
-          This is then replaced by a view created for the object that is
-          selected via the <classname>SelectableViewAxis</classname>.</para>
-        </section>
-      </section>
-
-      <section>
-        <title>Axis</title>
-
-        <para>If separate views need to be related, for example for their
-        sizes to be made consistent or find out a maximum value, then an
-        ViewAxis object should be created and passed to each subview.</para>
-
-        <para></para>
-
-        <para></para>
-      </section>
-
-      <section>
-        <title>Borders</title>
-
-        <para>Borders decorate views by adding behaviour and content to their
-        edges. Border are used at all levels to distinguish and control
-        windows, objects and fields. Borders are decorators, so are added like
-        this, which gives 3 pixels of empty space, a default white background,
-        a rounded rectangle and an object icon :</para>
-
-        <programlisting>new EmptyBorder(3, new BackgroundBorder(new LineBorder(1, 8, new IconBorder(subview))));</programlisting>
-
-        <para>Windows can be created by decorating a view with a
-        <classname>WindowBorder</classname> or
-        <classname>DialogBorder</classname>.</para>
-
-        <para>Control buttons can be added to views (as done for dialogs)
-        using a <classname>ButtonBorder</classname>.</para>
-
-        <para>Simple decorative borders include:
-        <classname>BackgroundBorder</classname>,
-        <classname>LineBorder</classname>, <classname>EmptyBorder</classname>
-        and <classname>LabelBorder</classname>.</para>
-
-        <section>
-          <title>Resizable views</title>
-
-          <para>Views are typically fixed size by design so that a view
-          always, where possible, shows it entire content. A view can be made
-          resizable by adding a <classname>ViewResizeBorder</classname>
-          decorator, which will provide a drag handle to resize the view
-          with.</para>
-
-          <programlisting>view = new ViewResizeBorder(view);</programlisting>
-        </section>
-
-        <section>
-          <title></title>
-
-          <para></para>
-        </section>
-      </section>
-
-      <section>
-        <title>Menus</title>
-
-        <para>Menu items are added by creating
-        <classname>UserAction</classname> objects.</para>
-      </section>
-
-      <section>
-        <title>Interactions</title>
-
-        <para>All user events - keyboard and mouse events - are routed through
-        <classname>InteractionHandler</classname>.</para>
-      </section>
-
-      <section>
-        <title>Gotchas</title>
-
-        <para>If a view, and particularly a border, has it contents changed so
-        it is wrapping a different object, then it must reset the view
-        property via a call to the setView method as shown below. This example
-        is from a border that replaces an icon with a form so initially
-        we</para>
-
-        <para>ExpanderBorder --&gt; ObjectBorder --&gt; Icon</para>
-
-        <para>and after the first click we get</para>
-
-        <para>ExpanderBorder --&gt; <emphasis>IconBorder</emphasis> --&gt;
-        <emphasis>CompositeView</emphasis></para>
-
-        <para>where the border and composite are newly created. Because the
-        form was created without reference to the ExpanderBorder it has the
-        <emphasis>view</emphasis> property set to reference the IconBorder.
-        Call setView as below corrects this so that view refers to the
-        ExpanderBorder instead.</para>
-
-        <programlisting>            View parent = wrappedView.getParent();
-            
-            getViewManager().removeFromNotificationList(wrappedView);
-            if (isOpen) {
-                wrappedView = new InternalFormSpecification().createView(getContent(), null);
-            } else {
-                ViewRequirement requirement = new ViewRequirement(getContent(), ViewRequirement.CLOSED);
-                wrappedView = Toolkit.getViewFactory().createView(requirement );
-            }
-            <emphasis role="bold">setView(this);</emphasis>
-            setParent(parent);
-</programlisting>
-      </section>
-
-      <section>
-        <title>Loading images</title>
-
-        <para></para>
-
-        <programlisting>            Image busyImage = ImageFactory.getInstance().loadIcon("busy", 16, null);
-</programlisting>
-      </section>
-    </chapter>
-
-    <chapter>
-      <title>Drag and drop user interface</title>
-
-      <para>The Drag and Drop User Interface (DnD UI) dynamically renders the
-      domain objects held within the system onto various styles of views and
-      automatically provides mechanisms such as menus and dialogs to interact
-      with those same objects.</para>
-
-      <para></para>
-
-      <para>Each view is set up by a <classname>ViewSpecification</classname>
-      that defines how to create a specific view. These specifications know
-      what content they can render via the
-      <methodname>canDisplay()</methodname> method.</para>
-
-      <para></para>
-
-      <para></para>
-
-      <section>
-        <title>Drawing</title>
-
-        <para>Each view can be drawn on buy overriding the
-        <methodname>draw(Canvas)</methodname> method in the view class. The
-        <classname>Canvas</classname> is the drawing surface for the view and
-        the class provides the tools for drawing lines, rectangles, eclipses,
-        text etc. The <classname>Canvas</classname> is used for both drawing
-        to screen and printing via the <methodname>print(Canvas)</methodname>
-        method (when extending the AbstractView the print method simply
-        delegates to the draw method so the former only needs implementing if
-        the rendering for printing is to be different to that shown on the
-        screen). The colour and text style that the drawing methods accept can
-        be got from the <classname>Toolkit</classname> class via the
-        <methodname>getColor</methodname> and <methodname>getText</methodname>
-        methods. The positioning of the drawing on the canvas is across and
-        down from the top-left corner of the canvas (unless an offset has been
-        added using the <methodname>offset(int xOffset, int
-        yOffset)</methodname> method, which will effectively cause every
-        <emphasis>x</emphasis> and <emphasis>y</emphasis> coordinate specified
-        thereafter to be translated to <emphasis>x + xOffset</emphasis> and
-        <emphasis>y + yOffset</emphasis> respectively).</para>
-
-        <para>The following example shows a simple but complete drawing method
-        that not just draws some text and lines but ensures that components
-        always sit properly together irrespective of the content text, which
-        is dynamic as it got from the object that this view is for. This was
-        defined in a subclass of <classname>AbstractView</classname> so there
-        is a call to the <methodname>draw</methodname> method in super class
-        as this will draw debug borders when debugging is turn on.</para>
-
-        <programlisting>    public void draw(Canvas canvas) {
-        super.draw(canvas);
-
-        String text = getContent().title();
-
-        Text textStyle = Toolkit.getText("normal");
-        
-        int x = HPADDING;
-        int y = VPADDING;
-        int maxWidth = 100;
-        int width = textStyle.stringWidth(text, maxWidth) + HPADDING * 2;
-        int height = textStyle.stringHeight(text, maxWidth) + VPADDING * 2;
-        
-        Color borderColor = Toolkit.getColor("secondary1");
-        Color backgroundColor = Toolkit.getColor("secondary3");
-        canvas.drawSolidRectangle(x, y, width, height, backgroundColor);
-        canvas.drawRectangle(x, y, width, height, borderColor);
-
-        x += HPADDING;
-        y += textStyle.getAscent();
-        Color textColor = Toolkit.getColor("primary1");
-        canvas.drawText(text, x, y, maxWidth, textColor,  textStyle);
-    }</programlisting>
-
-        <remark>Detail how this method works....</remark>
-
-        <para></para>
-
-        <remark>Add JavaDoc comments for: Canvas; Toolkit, View, AbstractView
-        (draw, print)</remark>
-      </section>
-    </chapter>
-  </part>
-
-  <chapter id="chp.Intro">
-    <title>Introduction</title>
-
-    <abstract>
-      <para>*** yada yada</para>
-    </abstract>
-
-    <sect1>
-      <title>***</title>
-
-      <para><emphasis>*** yada yada</emphasis></para>
-    </sect1>
-  </chapter>
-
-  <appendix>
-    <title>***</title>
-
-    <abstract>
-      <para>*** yada yada</para>
-    </abstract>
-
-    <sect1 id="sec.module-ui">
-      <title>***</title>
-
-      <para>*** yada yada</para>
-    </sect1>
-  </appendix>
-</book>