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/06 18:42:18 UTC

[42/52] [partial] ISIS-188: moving framework/ subdirs up to parent

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cell.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cell.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cell.java
new file mode 100644
index 0000000..02c4577
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cell.java
@@ -0,0 +1,24 @@
+/*
+ *  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.calendar;
+
+public class Cell {
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cells.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cells.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cells.java
new file mode 100644
index 0000000..ba2e21a
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/Cells.java
@@ -0,0 +1,74 @@
+/*
+ *  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.calendar;
+
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Date;
+
+public abstract class Cells {
+    protected final DateFormat monthFormat = new SimpleDateFormat("MMM");
+    protected final DateFormat dayFormat = new SimpleDateFormat("EEE");
+    protected Calendar date;
+
+    public Cells(final Cells replacing) {
+        if (replacing == null) {
+            today();
+        } else {
+            date = replacing.date;
+        }
+    }
+
+    public void today() {
+        date = Calendar.getInstance();
+        roundDown();
+    }
+
+    public final void setDate(final Calendar date) {
+        this.date = date;
+    }
+
+    public void roundDown() {
+    }
+
+    abstract int defaultRows();
+
+    abstract int defaultColumns();
+
+    abstract void add(int interval);
+
+    abstract String title(int cell);
+
+    public String header(final int cell) {
+        return null;
+    }
+
+    public int getPeriodFor(final Date date) {
+        final Calendar forDate = Calendar.getInstance();
+        forDate.setTime(date);
+        final int baseline = period(this.date);
+        final int comparativePeriod = period(forDate);
+        return baseline - comparativePeriod;
+    }
+
+    protected abstract int period(Calendar forDate);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/DayCells.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/DayCells.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/DayCells.java
new file mode 100644
index 0000000..3913c08
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/DayCells.java
@@ -0,0 +1,71 @@
+/*
+ *  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.calendar;
+
+import java.util.Calendar;
+
+public class DayCells extends Cells {
+
+    public DayCells(final Cells replacing) {
+        super(replacing);
+    }
+
+    @Override
+    public int defaultColumns() {
+        return 7;
+    }
+
+    @Override
+    public int defaultRows() {
+        return 2;
+    }
+
+    @Override
+    public void add(final int interval) {
+        date.add(Calendar.DAY_OF_WEEK, interval);
+    }
+
+    @Override
+    public void roundDown() {
+        final int offset = date.get(Calendar.DAY_OF_WEEK) - date.getFirstDayOfWeek();
+        date.add(Calendar.DAY_OF_MONTH, -offset);
+    }
+
+    @Override
+    public String title(final int cell) {
+        final Calendar d = (Calendar) date.clone();
+        d.add(Calendar.DAY_OF_WEEK, cell);
+        final String displayName = dayFormat.format(d.getTime()) + " " + d.get(Calendar.DAY_OF_MONTH) + " " + monthFormat.format(d.getTime());
+        return displayName;
+    }
+
+    @Override
+    public String header(final int cell) {
+        final Calendar d = (Calendar) date.clone();
+        d.add(Calendar.DAY_OF_WEEK, cell);
+        return dayFormat.format(d.getTime());
+    }
+
+    @Override
+    protected int period(final Calendar forDate) {
+        return forDate.get(Calendar.YEAR) * 12 - forDate.get(Calendar.DAY_OF_YEAR);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/MonthCells.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/MonthCells.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/MonthCells.java
new file mode 100644
index 0000000..7596e63
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/MonthCells.java
@@ -0,0 +1,62 @@
+/*
+ *  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.calendar;
+
+import java.util.Calendar;
+
+public class MonthCells extends Cells {
+
+    public MonthCells(final Cells replacing) {
+        super(replacing);
+    }
+
+    @Override
+    public int defaultColumns() {
+        return 4;
+    }
+
+    @Override
+    public int defaultRows() {
+        return 3;
+    }
+
+    @Override
+    public void roundDown() {
+        date.set(Calendar.MONTH, 0);
+    }
+
+    @Override
+    public void add(final int interval) {
+        date.add(Calendar.MONTH, interval);
+    }
+
+    @Override
+    public String title(final int cell) {
+        final Calendar d = (Calendar) date.clone();
+        d.add(Calendar.MONTH, cell);
+        final String displayName = monthFormat.format(d.getTime()) + " " + d.get(Calendar.YEAR);
+        return displayName;
+    }
+
+    @Override
+    protected int period(final Calendar forDate) {
+        return forDate.get(Calendar.YEAR) * 12 - forDate.get(Calendar.MONTH);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/SingleDayCells.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/SingleDayCells.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/SingleDayCells.java
new file mode 100644
index 0000000..2726017
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/SingleDayCells.java
@@ -0,0 +1,58 @@
+/*
+ *  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.calendar;
+
+import java.util.Calendar;
+
+public class SingleDayCells extends Cells {
+
+    public SingleDayCells(final Cells replacing) {
+        super(replacing);
+    }
+
+    @Override
+    public int defaultColumns() {
+        return 1;
+    }
+
+    @Override
+    public int defaultRows() {
+        return 1;
+    }
+
+    @Override
+    public void add(final int interval) {
+        date.add(Calendar.DAY_OF_WEEK, interval);
+    }
+
+    @Override
+    public String title(final int cell) {
+        final Calendar d = (Calendar) date.clone();
+        d.add(Calendar.DAY_OF_WEEK, cell);
+        final String displayName = dayFormat.format(d.getTime()) + " " + d.get(Calendar.DAY_OF_MONTH) + " " + monthFormat.format(d.getTime());
+        return displayName;
+    }
+
+    @Override
+    protected int period(final Calendar forDate) {
+        return forDate.get(Calendar.YEAR) * 12 - forDate.get(Calendar.DAY_OF_YEAR);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/WeekCells.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/WeekCells.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/WeekCells.java
new file mode 100644
index 0000000..2e7c221
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/WeekCells.java
@@ -0,0 +1,61 @@
+/*
+ *  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.calendar;
+
+import java.util.Calendar;
+
+public class WeekCells extends Cells {
+
+    public WeekCells(final Cells replacing) {
+        super(replacing);
+    }
+
+    @Override
+    public int defaultColumns() {
+        return 4;
+    }
+
+    @Override
+    public int defaultRows() {
+        return 3;
+    }
+
+    @Override
+    public void add(final int interval) {
+        add(date, interval);
+    }
+
+    public void add(final Calendar d, final int interval) {
+        d.add(Calendar.DAY_OF_MONTH, 7 * interval);
+    }
+
+    @Override
+    public String title(final int cell) {
+        final Calendar d = (Calendar) date.clone();
+        add(d, cell);
+        final String displayName = d.get(Calendar.DAY_OF_MONTH) + " " + monthFormat.format(d.getTime());
+        return "w/b " + displayName;
+    }
+
+    @Override
+    protected int period(final Calendar forDate) {
+        return forDate.get(Calendar.YEAR) * 12 - forDate.get(Calendar.WEEK_OF_YEAR);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/YearCells.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/YearCells.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/YearCells.java
new file mode 100644
index 0000000..09f828a
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/calendar/YearCells.java
@@ -0,0 +1,57 @@
+/*
+ *  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.calendar;
+
+import java.util.Calendar;
+
+public class YearCells extends Cells {
+
+    public YearCells(final Cells replacing) {
+        super(replacing);
+    }
+
+    @Override
+    public int defaultColumns() {
+        return 4;
+    }
+
+    @Override
+    public int defaultRows() {
+        return 2;
+    }
+
+    @Override
+    public void add(final int interval) {
+        date.add(Calendar.YEAR, interval);
+    }
+
+    @Override
+    public String title(final int cell) {
+        final Calendar d = (Calendar) date.clone();
+        d.add(Calendar.YEAR, cell);
+        final String displayName = d.get(Calendar.YEAR) + "";
+        return displayName;
+    }
+
+    @Override
+    protected int period(final Calendar forDate) {
+        return forDate.get(Calendar.YEAR);
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/ExpandableListSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/ExpandableListSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/ExpandableListSpecification.java
new file mode 100644
index 0000000..710bb8e
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/ExpandableListSpecification.java
@@ -0,0 +1,52 @@
+/*
+ *  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.combined;
+
+import org.apache.isis.viewer.dnd.form.ExpandableViewBorder;
+import org.apache.isis.viewer.dnd.icon.IconElementFactory;
+import org.apache.isis.viewer.dnd.view.ViewFactory;
+import org.apache.isis.viewer.dnd.view.composite.AbstractCollectionViewSpecification;
+
+public class ExpandableListSpecification extends AbstractCollectionViewSpecification {
+
+    public ExpandableListSpecification() {
+        builder.addSubviewDecorator(new ExpandableViewBorder.Factory());
+    }
+
+    @Override
+    protected ViewFactory createElementFactory() {
+        return new IconElementFactory();
+    }
+
+    @Override
+    public String getName() {
+        return "Expanding List (experimental)";
+    }
+
+    // TODO this should be available if an item can be given more space
+    /*
+     * @Override public boolean canDisplay(final Content content,
+     * ViewRequirement requirement) { return content.isCollection() &&
+     * requirement.is(ViewRequirement.CLOSED) &&
+     * requirement.is(ViewRequirement.SUBVIEW) &&
+     * requirement.is(ViewRequirement.SUBVIEW); }
+     */
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/FormWithTableSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/FormWithTableSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/FormWithTableSpecification.java
new file mode 100644
index 0000000..4dc499d
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/FormWithTableSpecification.java
@@ -0,0 +1,114 @@
+/*
+ *  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.combined;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.dnd.form.FormSpecification;
+import org.apache.isis.viewer.dnd.table.InternalTableSpecification;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.base.Layout;
+import org.apache.isis.viewer.dnd.view.composite.GridLayout;
+import org.apache.isis.viewer.dnd.view.composite.StackLayout;
+
+public class FormWithTableSpecification extends SplitViewSpecification {
+
+    // REVIEW: confirm this rendering context
+    final Where where = Where.OBJECT_FORMS;
+
+    @Override
+    public Layout createLayout(final Content content, final Axes axes) {
+        return new StackLayout();
+    }
+
+    @Override
+    View createMainView(final Axes axes, final Content mainContent, final Content secondaryContent) {
+        final View form1 = new FormSpecification() {
+            @Override
+            protected boolean include(final Content content, final int sequence) {
+                return !secondaryContent.getId().equals(content.getId());
+            };
+
+            @Override
+            public Layout createLayout(final Content content, final Axes axes) {
+                final GridLayout gridLayout = new GridLayout();
+                gridLayout.setSize(2);
+                return gridLayout;
+            }
+        }.createView(mainContent, axes, -1);
+        return form1;
+    }
+
+    @Override
+    View createSecondaryView(final Axes axes, final Content fieldContent) {
+        return new InternalTableSpecification().createView(fieldContent, axes, -1);
+    }
+
+    @Override
+    Content determineSecondaryContent(final Content content) {
+        final ObjectSpecification spec = content.getSpecification();
+        final ObjectAdapter target = content.getAdapter();
+        final AuthenticationSession session = IsisContext.getAuthenticationSession();
+        final List<ObjectAssociation> fields = spec.getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, target, where));
+        for (final ObjectAssociation field : fields) {
+            if (field.isOneToManyAssociation()) {
+                return Toolkit.getContentFactory().createFieldContent(field, target);
+            }
+        }
+        return null;
+    }
+
+    /*
+     * 
+     * @Override protected void init() { addSubviewDecorator(new
+     * FieldLabelsDecorator() { public View decorate(Axes axes, View view) { if
+     * (view.getContent().isCollection()) { return view; } else { return
+     * super.decorate(axes, view); } } }); addViewDecorator(new
+     * IconBorder.Factory()); }
+     * 
+     * @Override protected SubviewSpec createFieldFactory() { return new
+     * SubviewSpec() { public View createView(final Content content, Axes axes,
+     * int sequence) { if (content.isCollection()) { return new
+     * InternalTableSpecification().createView(content, axes, sequence); } else
+     * { final ViewFactory factory = Toolkit.getViewFactory(); int requirement =
+     * ViewRequirement.CLOSED | ViewRequirement.SUBVIEW; ViewRequirement
+     * viewRequirement = new ViewRequirement(content, requirement); return
+     * factory.createView(viewRequirement); } } }; }
+     */
+    @Override
+    public String getName() {
+        return "Form with table (experimental)";
+    }
+
+    @Override
+    boolean validField(final ObjectAssociation field) {
+        return false;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewAccess.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewAccess.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewAccess.java
new file mode 100644
index 0000000..3363563
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewAccess.java
@@ -0,0 +1,39 @@
+/*
+ *  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.combined;
+
+import java.util.List;
+
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.viewer.dnd.view.ViewAxis;
+
+public class SplitViewAccess implements ViewAxis {
+
+    private final List<ObjectAssociation> fields;
+
+    public SplitViewAccess(final List<ObjectAssociation> fields) {
+        this.fields = fields;
+    }
+
+    public List<ObjectAssociation> getFields() {
+        return fields;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewBuilder.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewBuilder.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewBuilder.java
new file mode 100644
index 0000000..63a549d
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewBuilder.java
@@ -0,0 +1,73 @@
+/*
+ *  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.combined;
+
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.composite.AbstractViewBuilder;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+class SplitViewBuilder extends AbstractViewBuilder {
+
+    private final SplitViewSpecification splitViewSpecification;
+
+    public SplitViewBuilder(final SplitViewSpecification splitViewSpecification) {
+        this.splitViewSpecification = splitViewSpecification;
+    }
+
+    @Override
+    public void createAxes(final Axes axes, final Content content) {
+        super.createAxes(axes, content);
+        axes.add(new SplitViewAccess(splitViewSpecification.determineAvailableFields(content)));
+    }
+
+    @Override
+    public void build(final View view, final Axes axes) {
+        if (view.getSubviews().length == 0) {
+            final Content content = view.getContent();
+            final Content fieldContent = splitViewSpecification.determineSecondaryContent(content);
+
+            final View form1 = splitViewSpecification.createMainView(axes, content, fieldContent);
+            view.addView(form1);
+
+            final View labelledForm = splitViewSpecification.createSecondaryView(axes, fieldContent);
+            view.addView(labelledForm);
+        }
+    }
+
+    @Override
+    public void viewMenuOptions(final UserActionSet options, final View view) {
+        super.viewMenuOptions(options, view);
+
+        final SplitViewAccess axis = view.getViewAxes().getAxis(SplitViewAccess.class);
+        for (final ObjectAssociation field : axis.getFields()) {
+            options.add(new UserActionAbstract("Select " + field.getName()) {
+                @Override
+                public void execute(final Workspace workspace, final View view, final Location at) {
+                }
+            });
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewSpecification.java
new file mode 100644
index 0000000..8c21561
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/SplitViewSpecification.java
@@ -0,0 +1,90 @@
+/*
+ *  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.combined;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.composite.CompositeViewSpecification;
+
+public abstract class SplitViewSpecification extends CompositeViewSpecification {
+
+    // REVIEW: should provide this rendering context, rather than hardcoding.
+    // the net effect currently is that class members annotated with 
+    // @Hidden(where=Where.ANYWHERE) or @Disabled(where=Where.ANYWHERE) will indeed
+    // be hidden/disabled, but will be visible/enabled (perhaps incorrectly) 
+    // for any other value for Where
+    final Where where = Where.ANYWHERE;
+
+    public SplitViewSpecification() {
+        builder = new SplitViewBuilder(this);
+    }
+
+    @Override
+    public boolean canDisplay(final ViewRequirement requirement) {
+        if (requirement.isObject() && requirement.is(ViewRequirement.OPEN) && !requirement.isSubview()) {
+            final Content fieldContent = determineSecondaryContent(requirement.getContent());
+            return fieldContent != null && fieldContent.getAdapter() != null;
+        } else {
+            return false;
+        }
+    }
+
+    abstract View createMainView(Axes axes, Content mainContent, final Content secondaryContent);
+
+    abstract View createSecondaryView(Axes axes, final Content fieldContent);
+
+    abstract Content determineSecondaryContent(Content content);
+
+    Content field(final ObjectAssociation field, final Content content) {
+        final ObjectSpecification spec = content.getSpecification();
+        final ObjectAdapter target = content.getAdapter();
+        return Toolkit.getContentFactory().createFieldContent(field, target);
+    }
+
+    List<ObjectAssociation> determineAvailableFields(final Content content) {
+        final ObjectSpecification spec = content.getSpecification();
+        final ObjectAdapter target = content.getAdapter();
+        final AuthenticationSession session = IsisContext.getAuthenticationSession();
+        final List<ObjectAssociation> fields = spec.getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, target, where));
+        final List<ObjectAssociation> selectableFields = new ArrayList<ObjectAssociation>();
+        for (final ObjectAssociation field : fields) {
+            if (validField(field)) {
+                selectableFields.add(field);
+            }
+        }
+        return selectableFields;
+    }
+
+    abstract boolean validField(ObjectAssociation field);
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/TwoPartViewSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/TwoPartViewSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/TwoPartViewSpecification.java
new file mode 100644
index 0000000..335646d
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/combined/TwoPartViewSpecification.java
@@ -0,0 +1,92 @@
+/*
+ *  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.combined;
+
+import java.util.List;
+
+import org.apache.isis.applib.annotation.Where;
+import org.apache.isis.core.commons.authentication.AuthenticationSession;
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.ObjectSpecification;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociationFilters;
+import org.apache.isis.runtimes.dflt.runtime.system.context.IsisContext;
+import org.apache.isis.viewer.dnd.form.FormSpecification;
+import org.apache.isis.viewer.dnd.form.InternalFormSpecification;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.axis.LabelAxis;
+import org.apache.isis.viewer.dnd.view.base.Layout;
+import org.apache.isis.viewer.dnd.view.border.LabelBorder;
+import org.apache.isis.viewer.dnd.view.composite.ColumnLayout;
+
+public class TwoPartViewSpecification extends SplitViewSpecification {
+
+    @Override
+    public Layout createLayout(final Content content, final Axes axes) {
+        return new ColumnLayout();
+    }
+
+    @Override
+    View createMainView(final Axes axes, final Content mainContent, final Content secondaryContent) {
+        final View form1 = new FormSpecification() {
+            @Override
+            protected boolean include(final Content content, final int sequence) {
+                return !secondaryContent.getId().equals(content.getId());
+            };
+        }.createView(mainContent, axes, -1);
+        return form1;
+    }
+
+    @Override
+    View createSecondaryView(final Axes axes, final Content fieldContent) {
+        final View form = new InternalFormSpecification().createView(fieldContent, axes, -1);
+        final View labelledForm = LabelBorder.createFieldLabelBorder(new LabelAxis(), form);
+        return labelledForm;
+    }
+
+    @Override
+    @Deprecated
+    Content determineSecondaryContent(final Content content) {
+        final ObjectSpecification spec = content.getSpecification();
+        final ObjectAdapter target = content.getAdapter();
+        final AuthenticationSession session = IsisContext.getAuthenticationSession();
+        final List<ObjectAssociation> fields = spec.getAssociations(ObjectAssociationFilters.dynamicallyVisible(session, target, where));
+        for (final ObjectAssociation field : fields) {
+            if (validField(field)) {
+                return Toolkit.getContentFactory().createFieldContent(field, target);
+            }
+        }
+        return null;
+    }
+
+    @Override
+    boolean validField(final ObjectAssociation field) {
+        return field.isOneToOneAssociation() && !field.getSpecification().isParseable();
+    }
+
+    @Override
+    public String getName() {
+        return "Two part object (experimental)";
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableCompositeViewBorder.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableCompositeViewBorder.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableCompositeViewBorder.java
new file mode 100644
index 0000000..32ffc80
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableCompositeViewBorder.java
@@ -0,0 +1,138 @@
+/*
+ *  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.configurable;
+
+import java.util.Enumeration;
+
+import org.apache.isis.core.commons.factory.InstanceUtil;
+import org.apache.isis.core.runtime.userprofile.Options;
+import org.apache.isis.viewer.dnd.configurable.GridListSpecification.ElementFactory;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.util.Properties;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.base.AbstractBorder;
+import org.apache.isis.viewer.dnd.view.base.UserViewSpecification;
+import org.apache.isis.viewer.dnd.view.composite.CompositeViewDecorator;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+public class ConfigurableCompositeViewBorder extends AbstractBorder {
+
+    public static class Factory implements CompositeViewDecorator {
+        private final ElementFactory elementSpecification;
+
+        public Factory(final ElementFactory elementSpecification) {
+            this.elementSpecification = elementSpecification;
+        }
+
+        @Override
+        public View decorate(final View view, final Axes axes) {
+            final ConfigurationAxis axis = new ConfigurationAxis();
+            // TODO load previously saved settings for the type of elements
+            // axis.loadSettings(view.getContent());
+            axes.add(axis);
+            return new ConfigurableCompositeViewBorder(view, elementSpecification);
+        }
+    }
+
+    private ViewSpecification elementSpecification;
+
+    protected ConfigurableCompositeViewBorder(final View view, final ElementFactory elementFactory) {
+        super(view);
+    }
+
+    @Override
+    public void loadOptions(final Options viewOptions) {
+        super.loadOptions(viewOptions);
+        final String elementsClass = viewOptions.getString("elements");
+        if (elementsClass != null) {
+            ViewSpecification specification;
+            if (elementsClass.startsWith("user:")) {
+                final String name = elementsClass.substring("user:".length());
+                final String wrappedSpecificationClass = Properties.getUserViewSpecificationOptions(name).getString("wrapped-specification");
+                final ViewSpecification wrappedSpectification = (ViewSpecification) InstanceUtil.createInstance(wrappedSpecificationClass);
+                specification = new UserViewSpecification(wrappedSpectification, name);
+            } else {
+                specification = (ViewSpecification) InstanceUtil.createInstance(elementsClass);
+            }
+            if (specification != null) {
+                getViewAxes().getAxis(ConfigurationAxis.class).setElementSpecification(specification);
+            }
+        }
+    }
+
+    @Override
+    public void saveOptions(final Options viewOptions) {
+        super.saveOptions(viewOptions);
+        if (elementSpecification != null) {
+            final boolean isUserSpecification = elementSpecification instanceof UserViewSpecification;
+            String name;
+            if (isUserSpecification) {
+                name = "user:" + elementSpecification.getName();
+            } else {
+                name = elementSpecification.getClass().getName();
+            }
+            viewOptions.addOption("elements", name);
+        }
+    }
+
+    @Override
+    public void viewMenuOptions(final UserActionSet menuOptions) {
+        super.viewMenuOptions(menuOptions);
+        final UserActionSet subOptions = menuOptions.addNewActionSet("Elements as");
+        final View firstSubview = getSubviews()[0];
+        final int status = ViewRequirement.OPEN | ViewRequirement.CLOSED | ViewRequirement.SUBVIEW | ViewRequirement.FIXED;
+        final ViewRequirement viewRequirement = new ViewRequirement(firstSubview.getContent(), status);
+        final Enumeration<ViewSpecification> possibleViews = Toolkit.getViewFactory().availableViews(viewRequirement);
+        while (possibleViews.hasMoreElements()) {
+            addElementAsOption(subOptions, possibleViews.nextElement());
+        }
+    }
+
+    private void addElementAsOption(final UserActionSet subOptions, final ViewSpecification specification) {
+        if (specification != elementSpecification) {
+            subOptions.add(new UserActionAbstract(specification.getName()) {
+                @Override
+                public void execute(final Workspace workspace, final View view, final Location at) {
+                    replaceElementViews(specification, view);
+                }
+            });
+        }
+    }
+
+    private void replaceElementViews(final ViewSpecification specification, final View view) {
+        elementSpecification = specification;
+        removeAllSubviews(view);
+        getViewAxes().getAxis(ConfigurationAxis.class).setElementSpecification(specification);
+        invalidateContent();
+    }
+
+    private void removeAllSubviews(final View view) {
+        final View[] subviews = view.getSubviews();
+        for (final View subview : subviews) {
+            view.removeView(subview);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableFieldBorder.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableFieldBorder.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableFieldBorder.java
new file mode 100644
index 0000000..96cd86b
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableFieldBorder.java
@@ -0,0 +1,154 @@
+/*
+ *  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.configurable;
+
+import java.util.Enumeration;
+
+import org.apache.isis.viewer.dnd.drawing.Canvas;
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.SubviewDecorator;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.UserAction;
+import org.apache.isis.viewer.dnd.view.UserActionSet;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewAxis;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.ViewState;
+import org.apache.isis.viewer.dnd.view.Workspace;
+import org.apache.isis.viewer.dnd.view.axis.LabelAxis;
+import org.apache.isis.viewer.dnd.view.base.AbstractBorder;
+import org.apache.isis.viewer.dnd.view.base.BlankView;
+import org.apache.isis.viewer.dnd.view.border.LabelBorder;
+import org.apache.isis.viewer.dnd.view.option.ReplaceViewOption;
+import org.apache.isis.viewer.dnd.view.option.UserActionAbstract;
+
+public class ConfigurableFieldBorder extends AbstractBorder {
+    public static final class Factory implements SubviewDecorator {
+        @Override
+        public ViewAxis createAxis(final Content content) {
+            return null;
+        }
+
+        @Override
+        public View decorate(final Axes axes, final View view) {
+            return new ConfigurableFieldBorder(view);
+        }
+    }
+
+    private static final int BORDER = 10;
+
+    protected ConfigurableFieldBorder(final View view) {
+        super(view);
+        right = BORDER;
+    }
+
+    @Override
+    public void viewMenuOptions(final UserActionSet menuOptions) {
+        super.viewMenuOptions(menuOptions);
+
+        menuOptions.add(new UserActionAbstract("Hide") {
+            @Override
+            public void execute(final Workspace workspace, final View view, final Location at) {
+                final View parent = wrappedView.getParent();
+                wrappedView = new BlankView(getContent());
+                wrappedView.setParent(parent);
+                wrappedView.setView(ConfigurableFieldBorder.this);
+                invalidateLayout();
+            }
+
+        });
+
+        menuOptions.add(new UserActionAbstract("Show label") {
+            @Override
+            public void execute(final Workspace workspace, final View view, final Location at) {
+                if (wrappedView instanceof LabelBorder) {
+                    wrappedView = ((LabelBorder) wrappedView).getWrapped();
+                } else {
+                    wrappedView = LabelBorder.createFieldLabelBorder(view.getParent().getViewAxes().getAxis(LabelAxis.class), wrappedView);
+                }
+                wrappedView.setView(ConfigurableFieldBorder.this);
+                getView().invalidateLayout();
+            }
+        });
+
+        replaceOptions(Toolkit.getViewFactory().availableViews(new ViewRequirement(getContent(), ViewRequirement.OPEN | ViewRequirement.CLOSED | ViewRequirement.SUBVIEW)), menuOptions); // openSubviews(content,
+                                                                                                                                                                                          // this),
+                                                                                                                                                                                          // options);
+
+    }
+
+    // TODO copied from AbstractView
+    protected void replaceOptions(final Enumeration possibleViews, final UserActionSet options) {
+        if (possibleViews.hasMoreElements()) {
+            final UserActionSet suboptions = options.addNewActionSet("Replace with");
+            while (possibleViews.hasMoreElements()) {
+                final ViewSpecification specification = (ViewSpecification) possibleViews.nextElement();
+
+                if (specification != getSpecification()) {
+                    final UserAction viewAs = new ReplaceViewOption(specification) {
+                        @Override
+                        protected void replace(final View view, final View withReplacement) {
+                            final View parent = wrappedView.getParent();
+                            wrappedView = LabelBorder.createFieldLabelBorder(view.getParent().getViewAxes().getAxis(LabelAxis.class), withReplacement);
+                            wrappedView.setParent(parent);
+                            wrappedView.setView(ConfigurableFieldBorder.this);
+                            invalidateLayout();
+                        }
+                    };
+                    suboptions.add(viewAs);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void draw(final Canvas canvas) {
+        super.draw(canvas);
+
+        final ViewState state = getState();
+        if (state.isViewIdentified()) {
+            final Size s = getSize();
+            final int xExtent = s.getWidth();
+            if (state.isViewIdentified()) {
+                canvas.drawSolidRectangle(xExtent - BORDER + 1, top, BORDER - 2, s.getHeight() - 2 * top, Toolkit.getColor(ColorsAndFonts.COLOR_SECONDARY3));
+            }
+        }
+    }
+
+    @Override
+    public void entered() {
+        getState().setViewIdentified();
+        wrappedView.entered();
+        markDamaged();
+    }
+
+    @Override
+    public void exited() {
+        getState().clearViewIdentified();
+        wrappedView.exited();
+        markDamaged();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableObjectViewSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableObjectViewSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableObjectViewSpecification.java
new file mode 100644
index 0000000..18e5f51
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurableObjectViewSpecification.java
@@ -0,0 +1,61 @@
+/*
+ *  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.configurable;
+
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.base.Layout;
+import org.apache.isis.viewer.dnd.view.border.IconBorder;
+import org.apache.isis.viewer.dnd.view.composite.CompositeViewSpecification;
+import org.apache.isis.viewer.dnd.view.composite.FieldLabelsDecorator;
+import org.apache.isis.viewer.dnd.view.composite.GridLayout;
+import org.apache.isis.viewer.dnd.view.composite.GridLayoutControlBorder;
+import org.apache.isis.viewer.dnd.view.composite.ObjectFieldBuilder;
+import org.apache.isis.viewer.dnd.view.composite.StandardFields;
+
+public class ConfigurableObjectViewSpecification extends CompositeViewSpecification {
+
+    public ConfigurableObjectViewSpecification() {
+        builder = new ObjectFieldBuilder(new StandardFields());
+        addSubviewDecorator(new FieldLabelsDecorator());
+        addSubviewDecorator(new ConfigurableFieldBorder.Factory());
+        addViewDecorator(new GridLayoutControlBorder.Factory());
+        addViewDecorator(new IconBorder.Factory());
+    }
+
+    @Override
+    public boolean canDisplay(final ViewRequirement requirement) {
+        return requirement.isObject() && requirement.isOpen() && requirement.isExpandable() && requirement.isDesign();
+    }
+
+    @Override
+    public String getName() {
+        return "Configurable (experimental)";
+    }
+
+    /*
+     * protected View decorateView(View view) { return new IconBorder(view); }
+     */
+    @Override
+    public Layout createLayout(final Content content, final Axes axes) {
+        return new GridLayout();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurationAxis.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurationAxis.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurationAxis.java
new file mode 100644
index 0000000..53744d0
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/ConfigurationAxis.java
@@ -0,0 +1,35 @@
+/*
+ *  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.configurable;
+
+import org.apache.isis.viewer.dnd.view.ViewAxis;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+
+public class ConfigurationAxis implements ViewAxis {
+    private ViewSpecification elementSpecification;
+
+    public void setElementSpecification(final ViewSpecification elementSpecification) {
+        this.elementSpecification = elementSpecification;
+    }
+
+    public ViewSpecification getElementSpecification() {
+        return elementSpecification;
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/FieldLayoutRequirement.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/FieldLayoutRequirement.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/FieldLayoutRequirement.java
new file mode 100644
index 0000000..81e4969
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/FieldLayoutRequirement.java
@@ -0,0 +1,38 @@
+/*
+ *  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.configurable;
+
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+
+public class FieldLayoutRequirement {
+    private View view;
+
+    private boolean visible;
+    private int columnSpan;
+    private int rowSpan;
+
+    private ViewSpecification spec;
+    private boolean showLabel;
+    private boolean mergeWithNext;
+
+    private boolean allowGrowing;
+    private boolean allowScrolling;
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/GridListSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/GridListSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/GridListSpecification.java
new file mode 100644
index 0000000..768e81b
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/GridListSpecification.java
@@ -0,0 +1,82 @@
+/*
+ *  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.configurable;
+
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.GlobalViewFactory;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewFactory;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.base.Layout;
+import org.apache.isis.viewer.dnd.view.composite.CollectionElementBuilder;
+import org.apache.isis.viewer.dnd.view.composite.CompositeViewSpecification;
+import org.apache.isis.viewer.dnd.view.composite.GridLayout;
+import org.apache.isis.viewer.dnd.view.composite.GridLayoutControlBorder;
+
+public class GridListSpecification extends CompositeViewSpecification implements ViewFactory {
+
+    protected static class ElementFactory implements ViewFactory {
+        @Override
+        public View createView(final Content content, final Axes axes, final int sequence) {
+            final GlobalViewFactory factory = Toolkit.getViewFactory();
+
+            final ViewSpecification elementSpecification = axes.getAxis(ConfigurationAxis.class).getElementSpecification();
+            if (elementSpecification == null) {
+                final int defaultRequirement = ViewRequirement.CLOSED | ViewRequirement.SUBVIEW;
+                final ViewRequirement viewRequirement = new ViewRequirement(content, defaultRequirement);
+                return factory.createView(viewRequirement);
+            } else {
+                return elementSpecification.createView(content, axes, sequence);
+            }
+        }
+    }
+
+    public GridListSpecification() {
+        final ElementFactory factory = new ElementFactory();
+        builder = new CollectionElementBuilder(factory);
+        // TODO allow to be switched on so that user can change the view for a
+        // single element. This type of
+        // view used for an element would not be stored.
+        if (false) {
+            addSubviewDecorator(new ConfigurableFieldBorder.Factory());
+        }
+
+        addViewDecorator(new ConfigurableCompositeViewBorder.Factory(factory));
+        addViewDecorator(new GridLayoutControlBorder.Factory());
+    }
+
+    @Override
+    public boolean canDisplay(final ViewRequirement requirement) {
+        return requirement.isCollection() && requirement.isOpen() && !requirement.isSubview() && requirement.isDesign();
+    }
+
+    @Override
+    public String getName() {
+        return "Grid List";
+    }
+
+    @Override
+    public Layout createLayout(final Content content, final Axes axes) {
+        return new GridLayout();
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectField.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectField.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectField.java
new file mode 100644
index 0000000..468dc1c
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectField.java
@@ -0,0 +1,51 @@
+/*
+ *  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.configurable;
+
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.userprofile.Options;
+import org.apache.isis.core.runtime.userprofile.OptionsClient;
+
+public class NewObjectField implements OptionsClient {
+
+    private final ObjectAssociation field;
+
+    public NewObjectField(final ObjectAssociation field) {
+        this.field = field;
+    }
+
+    public boolean includeLabel() {
+        return true;
+    }
+
+    public ObjectAssociation getField() {
+        return field;
+    }
+
+    @Override
+    public void loadOptions(final Options viewOptions) {
+    }
+
+    @Override
+    public void saveOptions(final Options viewOptions) {
+        viewOptions.addOption("field", field.getId());
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectView.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectView.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectView.java
new file mode 100644
index 0000000..20a3975
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewObjectView.java
@@ -0,0 +1,113 @@
+/*
+ *  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.configurable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.core.metamodel.adapter.ObjectAdapter;
+import org.apache.isis.core.metamodel.spec.feature.ObjectAssociation;
+import org.apache.isis.core.runtime.userprofile.Options;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.axis.LabelAxis;
+import org.apache.isis.viewer.dnd.view.border.LabelBorder;
+import org.apache.isis.viewer.dnd.view.composite.CompositeView;
+import org.apache.isis.viewer.dnd.view.composite.StackLayout;
+import org.apache.isis.viewer.dnd.view.content.FieldContent;
+
+public class NewObjectView extends CompositeView {
+    StackLayout layout = new StackLayout();
+    LabelAxis labelAxis = new LabelAxis();
+    List<NewObjectField> fields = new ArrayList<NewObjectField>();
+
+    public NewObjectView(final Content content, final ViewSpecification specification) {
+        super(content, specification);
+    }
+
+    void addField(final NewObjectField field) {
+        fields.add(field);
+        addFieldView(field);
+        invalidateContent();
+    }
+
+    @Override
+    protected void buildView() {
+        if (getSubviews().length == 0) {
+            final ObjectAdapter object = getContent().getAdapter();
+            final List<ObjectAssociation> associations = getContent().getSpecification().getAssociations();
+
+            final ObjectAssociation field = associations.get(0);
+
+            addFieldView(object, field);
+            addFieldView(object, associations.get(2));
+        }
+    }
+
+    private void addFieldView(final ObjectAdapter object, final ObjectAssociation field) {
+        final FieldContent fieldContent = (FieldContent) Toolkit.getContentFactory().createFieldContent(field, object);
+        final ViewRequirement requirement = new ViewRequirement(fieldContent, ViewRequirement.CLOSED | ViewRequirement.SUBVIEW);
+        View fieldView = Toolkit.getViewFactory().createView(requirement);
+
+        fieldView = LabelBorder.createFieldLabelBorder(labelAxis, fieldView);
+
+        addView(fieldView);
+    }
+
+    private void addFieldView(final NewObjectField field) {
+        final ObjectAdapter object = getContent().getAdapter();
+        final FieldContent fieldContent = (FieldContent) Toolkit.getContentFactory().createFieldContent(field.getField(), object);
+        final ViewRequirement requirement = new ViewRequirement(fieldContent, ViewRequirement.CLOSED | ViewRequirement.SUBVIEW);
+        View fieldView = Toolkit.getViewFactory().createView(requirement);
+        if (field.includeLabel()) {
+            fieldView = LabelBorder.createFieldLabelBorder(labelAxis, fieldView);
+        }
+        addView(fieldView);
+    }
+
+    @Override
+    protected void doLayout(final Size maximumSize) {
+        layout.layout(this, maximumSize);
+    }
+
+    @Override
+    protected Size requiredSize(final Size availableSpace) {
+        return layout.getRequiredSize(this);
+    }
+
+    @Override
+    public void loadOptions(final Options viewOptions) {
+        final Options options = viewOptions.getOptions("fields");
+        // options.options()
+
+    }
+
+    @Override
+    public void saveOptions(final Options viewOptions) {
+        for (final NewObjectField field : fields) {
+            field.saveOptions(viewOptions.getOptions("fields"));
+        }
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewViewSpecification.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewViewSpecification.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewViewSpecification.java
new file mode 100644
index 0000000..0329c80
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/NewViewSpecification.java
@@ -0,0 +1,82 @@
+/*
+ *  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.configurable;
+
+import org.apache.isis.viewer.dnd.drawing.ColorsAndFonts;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.base.Layout;
+import org.apache.isis.viewer.dnd.view.border.IconBorder;
+import org.apache.isis.viewer.dnd.view.composite.StackLayout;
+
+public class NewViewSpecification implements ViewSpecification {
+
+    protected Layout createLayout(final Content content, final Axes axes) {
+        return new StackLayout();
+    }
+
+    @Override
+    public boolean canDisplay(final ViewRequirement requirement) {
+        return requirement.isObject() && requirement.isOpen();
+    }
+
+    @Override
+    public String getName() {
+        return "Object View";
+    }
+
+    @Override
+    public boolean isAligned() {
+        return false;
+    }
+
+    @Override
+    public boolean isOpen() {
+        return false;
+    }
+
+    @Override
+    public boolean isReplaceable() {
+        return false;
+    }
+
+    @Override
+    public boolean isResizeable() {
+        return false;
+    }
+
+    @Override
+    public boolean isSubView() {
+        return false;
+    }
+
+    @Override
+    public View createView(final Content content, final Axes axes, final int sequence) {
+        final NewObjectView view = new NewObjectView(content, this);
+        View view2 = new IconBorder(view, Toolkit.getText(ColorsAndFonts.TEXT_TITLE));
+        view2 = new ViewDesignBorder(view2, view);
+        return view2;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/Panel.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/Panel.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/Panel.java
new file mode 100644
index 0000000..d18ce22
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/Panel.java
@@ -0,0 +1,203 @@
+/*
+ *  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.configurable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.View;
+
+public class Panel {
+
+    private static enum Orientation {
+        Undefined, Horizontal, Vertical
+    };
+
+    private static interface Content {
+        public Size getRequiredSize(Size availableSpace);
+
+        public void setLocation(Location location);
+
+        public void setSize(Size size);
+
+        public void layout(Size maximumSize);
+
+        public void debug(DebugBuilder debug);
+    }
+
+    private static class ViewContent implements Content {
+        private final View view;
+
+        public ViewContent(final View view) {
+            this.view = view;
+        }
+
+        @Override
+        public Size getRequiredSize(final Size availableSpace) {
+            return view.getRequiredSize(availableSpace);
+        }
+
+        @Override
+        public void layout(final Size maximumSize) {
+            view.layout();
+        }
+
+        @Override
+        public void setLocation(final Location location) {
+            view.setLocation(location);
+        }
+
+        @Override
+        public void setSize(final Size size) {
+            view.setSize(size);
+        }
+
+        @Override
+        public void debug(final DebugBuilder debug) {
+            debug.appendln(view.toString());
+        }
+    }
+
+    private static class PanelContent implements Content {
+        private final Panel panel;
+        private Location location;
+
+        public PanelContent(final Panel panel) {
+            this.panel = panel;
+        }
+
+        @Override
+        public Size getRequiredSize(final Size availableSpace) {
+            return panel.getRequiredSize(availableSpace);
+        }
+
+        @Override
+        public void layout(final Size maximumSize) {
+            panel.layout(location, maximumSize);
+        }
+
+        @Override
+        public void setLocation(final Location location) {
+            this.location = location;
+        }
+
+        @Override
+        public void setSize(final Size size) {
+        }
+
+        @Override
+        public void debug(final DebugBuilder debug) {
+            panel.debug(debug);
+        }
+    }
+
+    private List<Content> contents = new ArrayList<Content>();
+    private Orientation orientation;
+
+    public void debug(final DebugBuilder debug) {
+        debug.appendln("orientation", orientation);
+        debug.appendln("size", getRequiredSize(Size.createMax()));
+        debug.indent();
+        for (final Content content : contents) {
+            content.debug(debug);
+        }
+        debug.unindent();
+    }
+
+    public void addView(final View view, final PanelView.Position position) {
+        if (contents.isEmpty() || position == null) {
+            addToContents(view, false);
+        } else if (position == PanelView.Position.East || position == PanelView.Position.West) {
+            if (orientation == Orientation.Undefined) {
+                orientation = Orientation.Horizontal;
+            }
+            if (orientation == Orientation.Horizontal) {
+                addToContents(view, position == PanelView.Position.West);
+            } else {
+                replaceViewsWithPanel(view, position == PanelView.Position.West);
+            }
+        } else if (position == PanelView.Position.South || position == PanelView.Position.North) {
+            if (orientation == Orientation.Undefined) {
+                orientation = Orientation.Vertical;
+            }
+            if (orientation == Orientation.Horizontal) {
+                replaceViewsWithPanel(view, position == PanelView.Position.North);
+            } else {
+                addToContents(view, position == PanelView.Position.North);
+            }
+        }
+    }
+
+    private void addToContents(final View view, final boolean atBeginning) {
+        if (atBeginning) {
+            contents.add(0, new ViewContent(view));
+        } else {
+            contents.add(new ViewContent(view));
+        }
+    }
+
+    private void replaceViewsWithPanel(final View view, final boolean atBeginning) {
+        final Panel panel = new Panel();
+        panel.contents = contents;
+        contents = new ArrayList<Content>();
+        contents.add(new PanelContent(panel));
+        addToContents(view, atBeginning);
+        panel.orientation = orientation;
+        orientation = orientation == Orientation.Horizontal ? Orientation.Vertical : Orientation.Horizontal;
+    }
+
+    public void layout(final Size maximumSize) {
+        final Location location = new Location();
+        layout(location, maximumSize);
+    }
+
+    private void layout(final Location location, final Size maximumSize) {
+        for (final Content content : contents) {
+            content.setLocation(new Location(location));
+            final Size requiredSize = content.getRequiredSize(maximumSize);
+            content.setSize(requiredSize);
+            content.layout(maximumSize);
+            if (orientation == Orientation.Horizontal) {
+                location.add(requiredSize.getWidth(), 0);
+            } else {
+                location.add(0, requiredSize.getHeight());
+            }
+        }
+    }
+
+    public Size getRequiredSize(final Size availableSpace) {
+        final Size size = new Size();
+        for (final Content content : contents) {
+            final Size requiredSize = content.getRequiredSize(availableSpace);
+            if (orientation == Orientation.Horizontal) {
+                size.extendWidth(requiredSize.getWidth());
+                size.ensureHeight(requiredSize.getHeight());
+            } else {
+                size.extendHeight(requiredSize.getHeight());
+                size.ensureWidth(requiredSize.getWidth());
+            }
+        }
+        return size;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/isis/blob/255ef514/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/PanelView.java
----------------------------------------------------------------------
diff --git a/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/PanelView.java b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/PanelView.java
new file mode 100644
index 0000000..60d5de8
--- /dev/null
+++ b/component/viewer/dnd/src/main/java/org/apache/isis/viewer/dnd/configurable/PanelView.java
@@ -0,0 +1,113 @@
+/*
+ *  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.configurable;
+
+import org.apache.isis.core.commons.debug.DebugBuilder;
+import org.apache.isis.viewer.dnd.drawing.Location;
+import org.apache.isis.viewer.dnd.drawing.Size;
+import org.apache.isis.viewer.dnd.view.Axes;
+import org.apache.isis.viewer.dnd.view.Content;
+import org.apache.isis.viewer.dnd.view.Toolkit;
+import org.apache.isis.viewer.dnd.view.View;
+import org.apache.isis.viewer.dnd.view.ViewDrag;
+import org.apache.isis.viewer.dnd.view.ViewRequirement;
+import org.apache.isis.viewer.dnd.view.ViewSpecification;
+import org.apache.isis.viewer.dnd.view.composite.CompositeView;
+
+public class PanelView extends CompositeView {
+    public static enum Position {
+        North, South, East, West
+    };
+
+    private final Panel panel = new Panel();
+    private ViewSpecification initialViewSpecification;;
+
+    @Override
+    public void debug(final DebugBuilder debug) {
+        super.debug(debug);
+        debug.appendln("Panel");
+        debug.indent();
+        panel.debug(debug);
+        debug.unindent();
+    }
+
+    public void setInitialViewSpecification(final ViewSpecification initialViewSpecification) {
+        this.initialViewSpecification = initialViewSpecification;
+    }
+
+    public PanelView(final Content content, final ViewSpecification specification) {
+        super(content, specification);
+    }
+
+    @Override
+    protected void buildView() {
+        // addView(getContent(), initialViewSpecification, null);
+        final View newView = initialViewSpecification.createView(getContent(), new Axes(), 0);
+        panel.addView(newView, null);
+        addView(newView);
+    }
+
+    @Override
+    protected void doLayout(final Size maximumSize) {
+        panel.layout(maximumSize);
+    }
+
+    @Override
+    public Size requiredSize(final Size availableSpace) {
+        return panel.getRequiredSize(availableSpace);
+    }
+
+    @Override
+    public void drop(final ViewDrag drag) {
+        if (drag.getSourceView() == getView() || !contains(drag.getSourceView())) {
+            super.drop(drag);
+        } else {
+            final Location dropAt = drag.getLocation();
+            dropAt.subtract(getLocation());
+            final int x = dropAt.getX();
+            final int y = dropAt.getY();
+            final int borderWdth = 45;
+            final int left = getSize().getWidth() - borderWdth;
+            final int bottom = getSize().getHeight() - borderWdth;
+            if (y < borderWdth) {
+                addView(drag.getSourceView().getContent(), Position.North);
+            } else if (y > bottom) {
+                addView(drag.getSourceView().getContent(), Position.South);
+            } else if (x < borderWdth) {
+                addView(drag.getSourceView().getContent(), Position.West);
+            } else if (x > left) {
+                addView(drag.getSourceView().getContent(), Position.East);
+            }
+        }
+    }
+
+    public void addView(final Content content, final Position position) {
+        final ViewRequirement requirement = new ViewRequirement(content, ViewRequirement.OPEN | ViewRequirement.SUBVIEW);
+        final ViewSpecification viewSpecification = Toolkit.getViewFactory().availableViews(requirement).nextElement();
+        addView(content, viewSpecification, position);
+    }
+
+    public void addView(final Content content, final ViewSpecification specification, final Position position) {
+        final View newView = specification.createView(content, new Axes(), 0);
+        // newView = new LineBorder(newView);
+        panel.addView(newView, position);
+        addView(newView);
+    }
+}