Commits

Kevin Poalses committed fde3680

NEW: Added visual entity table view builders

  • Participants
  • Parent commits d425b59
  • Branches editing

Comments (0)

Files changed (14)

File src/main/java/net/poalsoft/dossier/contacts/ui/view/AddressTableView.java

-/*
- * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1) Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2) Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package net.poalsoft.dossier.contacts.ui.view;
-
-import javafx.collections.ObservableList;
-import javafx.scene.control.TableColumn;
-import javafx.scene.control.TableView;
-import javafx.scene.control.cell.PropertyValueFactory;
-import net.poalsoft.dossier.contacts.base.AddressType;
-import net.poalsoft.dossier.contacts.base.TelephoneNumberType;
-import net.poalsoft.dossier.contacts.ui.model.VisualAddress;
-import net.poalsoft.dossier.contacts.ui.model.VisualTelephoneNumber;
-
-import java.util.Set;
-
-/**
- * A simple address table view.
- *
- * @author Kevin Poalses
- */
-public class AddressTableView extends TableView<VisualAddress> {
-
-    public AddressTableView(ObservableList<VisualAddress> visualTelephoneNumbers) {
-        this();
-        setItems(visualTelephoneNumbers);
-    }
-
-    public AddressTableView() {
-
-        TableColumn<VisualAddress, String> nameCol = new TableColumn<>("Name");
-        nameCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, String>("name"));
-        getColumns().add(nameCol);
-
-        TableColumn<VisualAddress, String> extendedAddressCol = new TableColumn<>("Extended");
-        extendedAddressCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, String>("extendedAddress"));
-        getColumns().add(extendedAddressCol);
-
-        TableColumn<VisualAddress, String> streetAddressCol = new TableColumn<>("Street");
-        streetAddressCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, String>("streetAddress"));
-        getColumns().add(streetAddressCol);
-
-        TableColumn<VisualAddress, String> localityCol = new TableColumn<>("Locality");
-        localityCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, String>("locality"));
-        getColumns().add(localityCol);
-
-        TableColumn<VisualAddress, String> regionCol = new TableColumn<>("Region");
-        regionCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, String>("region"));
-        getColumns().add(regionCol);
-
-        TableColumn<VisualAddress, String> postalCodeCol = new TableColumn<>("Postal Code");
-        postalCodeCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, String>("postalCode"));
-        getColumns().add(postalCodeCol);
-
-        TableColumn<VisualAddress, String> countryCol = new TableColumn<>("Country");
-        countryCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, String>("country"));
-        getColumns().add(countryCol);
-
-        TableColumn<VisualAddress, Set<AddressType>> typesCol = new TableColumn<>("Types");
-        typesCol.setCellValueFactory(new PropertyValueFactory<VisualAddress, Set<AddressType>>("addressTypes"));
-        getColumns().add(typesCol);
-
-        setPrefWidth(1000);
-    }
-
-}

File src/main/java/net/poalsoft/dossier/contacts/ui/view/EmailAddressTableView.java

-/*
- * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1) Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2) Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package net.poalsoft.dossier.contacts.ui.view;
-
-import javafx.beans.value.ObservableValue;
-import javafx.collections.ObservableList;
-import javafx.scene.control.TableColumn;
-import javafx.scene.control.TableView;
-import javafx.scene.control.cell.PropertyValueFactory;
-import javafx.util.Callback;
-import net.poalsoft.dossier.contacts.base.EmailContentFormat;
-import net.poalsoft.dossier.contacts.ui.model.VisualEmailAddress;
-
-import java.net.URI;
-
-/**
- * A simple email address view.
- *
- * @author Kevin Poalses
- */
-public class EmailAddressTableView extends TableView<VisualEmailAddress> {
-
-    public EmailAddressTableView(ObservableList<VisualEmailAddress> visualTelephoneNumbers) {
-        this();
-        setItems(visualTelephoneNumbers);
-    }
-
-    public EmailAddressTableView() {
-        TableColumn<VisualEmailAddress, String> nameCol = new TableColumn<>("Name");
-        nameCol.setCellValueFactory(new PropertyValueFactory<VisualEmailAddress, String>("name"));
-        TableColumn<VisualEmailAddress, EmailContentFormat> formatCol = new TableColumn<>("Content Format");
-        formatCol.setCellValueFactory(
-                new PropertyValueFactory<VisualEmailAddress, EmailContentFormat>("emailContentFormat"));
-        TableColumn<VisualEmailAddress, URI> uriCol = new TableColumn<>("URI");
-        uriCol.setCellValueFactory(
-                new Callback<TableColumn.CellDataFeatures<VisualEmailAddress, URI>, ObservableValue<URI>>() {
-                    @Override
-                    public ObservableValue<URI> call(TableColumn.CellDataFeatures<VisualEmailAddress, URI> visualEmailAddressURICellDataFeatures) {
-                        return visualEmailAddressURICellDataFeatures.getValue()
-                                                                    .emailURIProperty();
-                    }
-                });
-        getColumns().addAll(nameCol, formatCol, uriCol);
-        setPrefWidth(550);
-    }
-
-
-}

File src/main/java/net/poalsoft/dossier/contacts/ui/view/TelephoneNumberTableView.java

-/*
- * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * 1) Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2) Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-package net.poalsoft.dossier.contacts.ui.view;
-
-import javafx.collections.ObservableList;
-import javafx.scene.control.TableColumn;
-import javafx.scene.control.TableView;
-import javafx.scene.control.cell.PropertyValueFactory;
-import net.poalsoft.dossier.contacts.base.TelephoneNumberType;
-import net.poalsoft.dossier.contacts.ui.model.VisualTelephoneNumber;
-
-import java.util.Set;
-
-/**
- * A simple telephone number view.
- *
- * @author Kevin Poalses
- */
-public class TelephoneNumberTableView extends TableView<VisualTelephoneNumber> {
-
-    public TelephoneNumberTableView(ObservableList<VisualTelephoneNumber> visualTelephoneNumbers) {
-        this();
-        setItems(visualTelephoneNumbers);
-    }
-
-    public TelephoneNumberTableView() {
-        TableColumn<VisualTelephoneNumber, String> nameCol = new TableColumn<>("Name");
-        nameCol.setCellValueFactory(new PropertyValueFactory<VisualTelephoneNumber, String>("name"));
-        TableColumn<VisualTelephoneNumber, String> numberCol = new TableColumn<>("Number");
-        numberCol.setCellValueFactory(new PropertyValueFactory<VisualTelephoneNumber, String>("diallingString"));
-        TableColumn<VisualTelephoneNumber, Set<TelephoneNumberType>> typesCol = new TableColumn<>("Types");
-        typesCol.setCellValueFactory(new PropertyValueFactory<VisualTelephoneNumber, Set<TelephoneNumberType>>("telephoneNumberTypes"));
-        getColumns().addAll(nameCol, numberCol, typesCol);
-        setPrefWidth(550);
-    }
-
-
-
-}

File src/main/java/net/poalsoft/dossier/contacts/ui/view/VisualEntityTableViewBuilder.java

     VisualEntityTableViewBuilder<VisualEntity> reset();
 
     /**
+     * Sets the initial table items.
+     *
+     * @param items Table items
+     * @return Reference to self for fluent programming
+     */
+    VisualEntityTableViewBuilder<VisualEntity> withItems(ObservableList<VisualEntity> items);
+
+    /**
      * Creates the default columns.
      *
      * @return Reference to self for fluent programming
     VisualEntityTableViewBuilder<VisualEntity> withDefaultColumns();
 
     /**
-     * Sets the initial table items.
+     * Creates any non-essential columns.
      *
-     * @param items Table items
      * @return Reference to self for fluent programming
      */
-    VisualEntityTableViewBuilder<VisualEntity> withItems(ObservableList<VisualEntity> items);
+    VisualEntityTableViewBuilder<VisualEntity> withExtraColumns();
+
+    /**
+     * Sets the default preferred width.
+     *
+     * @return Reference to self for fluent programming
+     */
+    VisualEntityTableViewBuilder<VisualEntity> withDefaultPreferredWidth();
+
+    /**
+     * Sets the preferred width.
+     *
+     * @param preferredWidth Preferred table width
+     * @return Reference to self for fluent programming
+     */
+    VisualEntityTableViewBuilder<VisualEntity> withPreferredWidth(double preferredWidth);
 }

File src/main/java/net/poalsoft/dossier/contacts/ui/view/internal/AbstractVisualContactTableViewBuilder.java

+/*
+ * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.poalsoft.dossier.contacts.ui.view.internal;
+
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBuilder;
+import javafx.scene.control.cell.PropertyValueFactoryBuilder;
+import net.poalsoft.dossier.contacts.base.Geolocation;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
+
+import javax.annotation.concurrent.ThreadSafe;
+
+/**
+ * An abstract visual contact table view builder.
+ * <p/>
+ * <p>Derived classes <em>must</em> be {@link javax.annotation.concurrent.ThreadSafe}</p>
+ *
+ * @author Kevin Poalses
+ */
+@ThreadSafe
+public abstract class AbstractVisualContactTableViewBuilder<VisualContactEntity> extends
+                                                                                 AbstractVisualEntityTableViewBuilder<VisualContactEntity> {
+
+    public AbstractVisualContactTableViewBuilder() {
+        super();
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualContactEntity> withDefaultColumns() {
+
+        TableColumn<VisualContactEntity, String> displayNameCol =
+                TableColumnBuilder
+                        .<VisualContactEntity, String>create()
+                        .text("Display Name")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualContactEntity, String>create()
+                                                                     .property("derivedDisplayName")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(displayNameCol);
+
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualContactEntity> withExtraColumns() {
+        TableColumn<VisualContactEntity, Geolocation> geolocationCol =
+                TableColumnBuilder
+                        .<VisualContactEntity, Geolocation>create()
+                        .text("Geolocation")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualContactEntity, Geolocation>create()
+                                                                     .property("geolocation")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(geolocationCol);
+
+        return this;
+    }
+}

File src/main/java/net/poalsoft/dossier/contacts/ui/view/internal/AbstractVisualEntityTableViewBuilder.java

+/*
+ * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.poalsoft.dossier.contacts.ui.view.internal;
+
+import javafx.collections.ObservableList;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.control.TableViewBuilder;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
+
+import javax.annotation.concurrent.ThreadSafe;
+import java.util.ArrayList;
+import java.util.Collection;
+
+/**
+ * An abstract visual entity table view builder.
+ * <p/>
+ * <p>Derived classes <em>must</em> be {@link javax.annotation.concurrent.ThreadSafe}</p>
+ *
+ * @author Kevin Poalses
+ */
+@ThreadSafe
+public abstract class AbstractVisualEntityTableViewBuilder<VisualEntity> implements
+                                                                         VisualEntityTableViewBuilder<VisualEntity> {
+
+    public AbstractVisualEntityTableViewBuilder() {
+
+        this.tableViewBuilder = new ThreadLocal<TableViewBuilder<VisualEntity, ?>>() {
+            @Override
+            protected TableViewBuilder<VisualEntity, ?> initialValue() {
+                return TableViewBuilder.create();
+            }
+        };
+        this.defaultTableColumns = new
+                ThreadLocal<Collection<TableColumn<VisualEntity, ?>>>() {
+                    @Override
+                    protected Collection<TableColumn<VisualEntity, ?>> initialValue() {
+                        return new ArrayList<>(INITIAL_TABLE_COLUMNS_CAPACITY);
+                    }
+                };
+        this.extraTableColumns = new
+                ThreadLocal<Collection<TableColumn<VisualEntity, ?>>>() {
+                    @Override
+                    protected Collection<TableColumn<VisualEntity, ?>> initialValue() {
+                        return new ArrayList<>(INITIAL_TABLE_COLUMNS_CAPACITY);
+                    }
+                };
+
+    }
+
+    @Override
+    public TableView<VisualEntity> build() {
+        return this.tableViewBuilder
+                .get()
+                .columns(this.defaultTableColumns
+                                 .get())
+                .build();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p/>
+     * <p>
+     * Subclasses <em>must</em> super call this if they override {@link #reset()}
+     * </p>
+     *
+     * @return Reference to self for fluent programming
+     */
+    @Override
+    public VisualEntityTableViewBuilder<VisualEntity> reset() {
+        this.tableViewBuilder
+                .set(TableViewBuilder.<VisualEntity>create());
+        this.defaultTableColumns
+                .set(new ArrayList<TableColumn<VisualEntity, ?>>(INITIAL_TABLE_COLUMNS_CAPACITY));
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualEntity> withItems(ObservableList<VisualEntity> items) {
+        this.tableViewBuilder
+                .get()
+                .items(items);
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualEntity> withPreferredWidth(double preferredWidth) {
+        this.tableViewBuilder
+                .get()
+                .prefWidth(preferredWidth);
+
+        return this;
+    }
+
+    /**
+     * Add the given table column to the list of default columns.
+     *
+     * @param tableColumn Table column
+     */
+    protected void withDefaultTableColumn(TableColumn<VisualEntity, ?> tableColumn) {
+        this.defaultTableColumns
+                .get()
+                .add(tableColumn);
+    }
+
+    /**
+     * Add the given table column to the list of extra columns.
+     *
+     * @param tableColumn Table column
+     */
+    protected void withExtraTableColumn(TableColumn<VisualEntity, ?> tableColumn) {
+        this.extraTableColumns
+                .get()
+                .add(tableColumn);
+    }
+
+    private final ThreadLocal<Collection<TableColumn<VisualEntity, ?>>> defaultTableColumns;
+
+    private final ThreadLocal<Collection<TableColumn<VisualEntity, ?>>> extraTableColumns;
+
+    private final ThreadLocal<TableViewBuilder<VisualEntity, ?>> tableViewBuilder;
+
+    private static final int INITIAL_TABLE_COLUMNS_CAPACITY = 20;
+}

File src/main/java/net/poalsoft/dossier/contacts/ui/view/internal/VisualAddressTableViewBuilderImpl.java

+/*
+ * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.poalsoft.dossier.contacts.ui.view.internal;
+
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBuilder;
+import javafx.scene.control.cell.PropertyValueFactoryBuilder;
+import net.poalsoft.dossier.contacts.base.AddressType;
+import net.poalsoft.dossier.contacts.ui.model.VisualAddress;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.concurrent.ThreadSafe;
+import java.util.Set;
+
+/**
+ * A builder for creating address table views.
+ *
+ * @author Kevin Poalses
+ */
+@ThreadSafe
+@Component("visualAddressTableViewBuilder")
+@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
+public class VisualAddressTableViewBuilderImpl extends AbstractVisualEntityTableViewBuilder<VisualAddress> {
+
+    public VisualAddressTableViewBuilderImpl() {
+        super();
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualAddress> withDefaultColumns() {
+
+        TableColumn<VisualAddress, String> nameCol =
+                TableColumnBuilder
+                        .<VisualAddress, String>create()
+                        .text("Name")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, String>create()
+                                                                     .property("name")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(nameCol);
+
+        TableColumn<VisualAddress, String> streetAddressCol =
+                TableColumnBuilder
+                        .<VisualAddress, String>create()
+                        .text("Street")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, String>create()
+                                                                     .property("streetAddress")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(streetAddressCol);
+
+        TableColumn<VisualAddress, String> localityCol =
+                TableColumnBuilder
+                        .<VisualAddress, String>create()
+                        .text("Locality")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, String>create()
+                                                                     .property("locality")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(localityCol);
+
+        TableColumn<VisualAddress, String> regionCol =
+                TableColumnBuilder
+                        .<VisualAddress, String>create()
+                        .text("Region")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, String>create()
+                                                                     .property("region")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(regionCol);
+
+        TableColumn<VisualAddress, String> postalCodeCol =
+                TableColumnBuilder
+                        .<VisualAddress, String>create()
+                        .text("Postal Code")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, String>create()
+                                                                     .property("postalCode")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(postalCodeCol);
+
+        TableColumn<VisualAddress, String> countryCol =
+                TableColumnBuilder
+                        .<VisualAddress, String>create()
+                        .text("Country")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, String>create()
+                                                                     .property("country")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(countryCol);
+
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualAddress> withExtraColumns() {
+
+        TableColumn<VisualAddress, Set<AddressType>> typesCol =
+                TableColumnBuilder
+                        .<VisualAddress, Set<AddressType>>create()
+                        .text("Types")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, Set<AddressType>>create()
+                                                                     .property("addressTypes")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(typesCol);
+
+        TableColumn<VisualAddress, String> extendedAddressCol =
+                TableColumnBuilder
+                        .<VisualAddress, String>create()
+                        .text("Extended")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualAddress, String>create()
+                                                                     .property("extendedAddress")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(extendedAddressCol);
+
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualAddress> withDefaultPreferredWidth() {
+        withPreferredWidth(1000);
+
+        return this;
+    }
+
+}

File src/main/java/net/poalsoft/dossier/contacts/ui/view/internal/VisualEmailAddressTableViewBuilderImpl.java

+/*
+ * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.poalsoft.dossier.contacts.ui.view.internal;
+
+import javafx.beans.value.ObservableValue;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBuilder;
+import javafx.scene.control.cell.PropertyValueFactoryBuilder;
+import javafx.util.Callback;
+import net.poalsoft.dossier.contacts.base.EmailContentFormat;
+import net.poalsoft.dossier.contacts.ui.model.VisualEmailAddress;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.concurrent.ThreadSafe;
+import java.net.URI;
+
+/**
+ * A builder for creating email address table views.
+ *
+ * @author Kevin Poalses
+ */
+@ThreadSafe
+@Component("visualEmailAddressTableViewBuilder")
+@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
+public class VisualEmailAddressTableViewBuilderImpl extends AbstractVisualEntityTableViewBuilder<VisualEmailAddress> {
+
+    public VisualEmailAddressTableViewBuilderImpl() {
+        super();
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualEmailAddress> withDefaultColumns() {
+
+        TableColumn<VisualEmailAddress, String> nameCol =
+                TableColumnBuilder
+                        .<VisualEmailAddress, String>create()
+                        .text("Name")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualEmailAddress, String>create()
+                                                                     .property("name")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(nameCol);
+
+        TableColumn<VisualEmailAddress, URI> emailUriCol =
+                TableColumnBuilder
+                        .<VisualEmailAddress, URI>create()
+                        .text("Email")
+                        .cellValueFactory(
+                                new Callback<TableColumn.CellDataFeatures<VisualEmailAddress, URI>, ObservableValue<URI>>() {
+                                    @Override
+                                    public ObservableValue<URI> call(TableColumn.CellDataFeatures<VisualEmailAddress, URI> cellDataFeatures) {
+                                        return cellDataFeatures.getValue()
+                                                               .emailURIProperty();
+                                    }
+                                })
+                        .build();
+        withDefaultTableColumn(emailUriCol);
+
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualEmailAddress> withExtraColumns() {
+        TableColumn<VisualEmailAddress, EmailContentFormat> contentFormatCol =
+                TableColumnBuilder
+                        .<VisualEmailAddress, EmailContentFormat>create()
+                        .text("Content Format")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualEmailAddress, EmailContentFormat>create()
+                                                                     .property("emailContentFormat")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(contentFormatCol);
+
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualEmailAddress> withDefaultPreferredWidth() {
+        withPreferredWidth(800);
+
+        return this;
+    }
+}

File src/main/java/net/poalsoft/dossier/contacts/ui/view/internal/VisualPersonTableViewBuilderImpl.java

 
 package net.poalsoft.dossier.contacts.ui.view.internal;
 
-import javafx.collections.ObservableList;
 import javafx.scene.control.TableColumn;
-import javafx.scene.control.TableView;
-import javafx.scene.control.TableViewBuilder;
-import javafx.scene.control.cell.PropertyValueFactory;
+import javafx.scene.control.TableColumnBuilder;
+import javafx.scene.control.cell.PropertyValueFactoryBuilder;
 import net.poalsoft.dossier.contacts.base.PersonGender;
 import net.poalsoft.dossier.contacts.ui.model.VisualPerson;
 import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
 @ThreadSafe
 @Component("visualPersonTableViewBuilder")
 @Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
-public class VisualPersonTableViewBuilderImpl implements VisualEntityTableViewBuilder<VisualPerson> {
+public class VisualPersonTableViewBuilderImpl extends AbstractVisualContactTableViewBuilder<VisualPerson> {
 
     public VisualPersonTableViewBuilderImpl() {
-        this.tableViewBuilder = new ThreadLocal<TableViewBuilder<VisualPerson, ?>>() {
-            @Override
-            protected TableViewBuilder<VisualPerson, ?> initialValue() {
-                return TableViewBuilder.create();
-            }
-        };
-    }
-
-    @Override
-    public TableView<VisualPerson> build() {
-        return this.tableViewBuilder
-                .get()
-                .build();
-    }
-
-    @Override
-    public VisualEntityTableViewBuilder<VisualPerson> reset() {
-        this.tableViewBuilder
-                .set(TableViewBuilder.<VisualPerson>create());
-        return this;
+        super();
     }
 
     @Override
     public VisualEntityTableViewBuilder<VisualPerson> withDefaultColumns() {
-        TableColumn<VisualPerson, String> displayNameCol = new TableColumn<>("Display Name");
-        displayNameCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, String>("derivedDisplayName"));
 
-        TableColumn<VisualPerson, String> firstNameCol = new TableColumn<>("First Name");
-        firstNameCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, String>("firstName"));
+        super.withDefaultColumns();
 
-        TableColumn<VisualPerson, String> lastNameCol = new TableColumn<>("Last Name");
-        lastNameCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, String>("lastName"));
+        TableColumn<VisualPerson, String> displayNameCol =
+                TableColumnBuilder
+                        .<VisualPerson, String>create()
+                        .text("Display Name")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, String>create()
+                                                                     .property("derivedDisplayName")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(displayNameCol);
 
-        TableColumn<VisualPerson, String> nickNameCol = new TableColumn<>("Nickname");
-        nickNameCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, String>("nickName"));
+        TableColumn<VisualPerson, String> firstNameCol =
+                TableColumnBuilder
+                        .<VisualPerson, String>create()
+                        .text("First Name")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, String>create()
+                                                                     .property("firstName")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(firstNameCol);
 
-        TableColumn<VisualPerson, PersonGender> genderCol = new TableColumn<>("Gender");
-        genderCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, PersonGender>("gender"));
+        TableColumn<VisualPerson, String> lastNameCol =
+                TableColumnBuilder
+                        .<VisualPerson, String>create()
+                        .text("Last Name")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, String>create()
+                                                                     .property("lastName")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(lastNameCol);
 
-        TableColumn<VisualPerson, List<String>> typesCol = new TableColumn<>("Middle names");
-        typesCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, List<String>>("middleNames"));
-
-        TableColumn<VisualPerson, Set<String>> prefixesCol = new TableColumn<>("Prefixes");
-        prefixesCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, Set<String>>("honorificPrefixes"));
-
-        TableColumn<VisualPerson, Set<String>> suffixesCol = new TableColumn<>("Suffixes");
-        prefixesCol.setCellValueFactory(new PropertyValueFactory<VisualPerson, Set<String>>("honorificSuffixes"));
-
-        this.tableViewBuilder
-                .get()
-                .columns(displayNameCol,
-                         firstNameCol,
-                         lastNameCol,
-                         nickNameCol,
-                         genderCol,
-                         typesCol,
-                         prefixesCol,
-                         suffixesCol);
-
-        this.tableViewBuilder
-                .get()
-                .prefWidth(800);
+        TableColumn<VisualPerson, String> nickNameCol =
+                TableColumnBuilder
+                        .<VisualPerson, String>create()
+                        .text("Nickname")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, String>create()
+                                                                     .property("nickName")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(nickNameCol);
 
         return this;
     }
 
     @Override
-    public VisualEntityTableViewBuilder<VisualPerson> withItems(ObservableList<VisualPerson> items) {
-        this.tableViewBuilder
-                .get()
-                .items(items);
+    public VisualEntityTableViewBuilder<VisualPerson> withExtraColumns() {
+
+        super.withExtraColumns();
+
+        TableColumn<VisualPerson, PersonGender> genderCol =
+                TableColumnBuilder
+                        .<VisualPerson, PersonGender>create()
+                        .text("Gender")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, PersonGender>create()
+                                                                     .property("gender")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(genderCol);
+
+        TableColumn<VisualPerson, List<String>> typesCol =
+                TableColumnBuilder
+                        .<VisualPerson, List<String>>create()
+                        .text("Middle Names")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, List<String>>create()
+                                                                     .property("middleNames")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(typesCol);
+
+        TableColumn<VisualPerson, Set<String>> prefixesCol =
+                TableColumnBuilder
+                        .<VisualPerson, Set<String>>create()
+                        .text("Prefixes")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, Set<String>>create()
+                                                                     .property("honorificPrefixes")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(prefixesCol);
+
+        TableColumn<VisualPerson, Set<String>> suffixesCol =
+                TableColumnBuilder
+                        .<VisualPerson, Set<String>>create()
+                        .text("Suffixes")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualPerson, Set<String>>create()
+                                                                     .property("honorificSuffixes")
+                                                                     .build())
+                        .build();
+        withExtraTableColumn(suffixesCol);
+
         return this;
     }
 
-    private final ThreadLocal<TableViewBuilder<VisualPerson, ?>> tableViewBuilder;
+    @Override
+    public VisualEntityTableViewBuilder<VisualPerson> withDefaultPreferredWidth() {
+        return withPreferredWidth(800);
+    }
+
 }

File src/main/java/net/poalsoft/dossier/contacts/ui/view/internal/VisualTelephoneNumberTableViewBuilderImpl.java

+/*
+ * Copyright (c) 2010-2013. Kevin Poalses <kevinp@poalsoft.net>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * 1) Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2) Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package net.poalsoft.dossier.contacts.ui.view.internal;
+
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableColumnBuilder;
+import javafx.scene.control.cell.PropertyValueFactoryBuilder;
+import net.poalsoft.dossier.contacts.base.TelephoneNumberType;
+import net.poalsoft.dossier.contacts.ui.model.VisualTelephoneNumber;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.annotation.Scope;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.concurrent.ThreadSafe;
+import java.util.Set;
+
+/**
+ * A builder for creating TelephoneNumber table views.
+ *
+ * @author Kevin Poalses
+ */
+@ThreadSafe
+@Component("visualTelephoneNumberTableViewBuilder")
+@Scope(value = BeanDefinition.SCOPE_PROTOTYPE)
+public class VisualTelephoneNumberTableViewBuilderImpl extends
+                                                       AbstractVisualEntityTableViewBuilder<VisualTelephoneNumber> {
+
+    public VisualTelephoneNumberTableViewBuilderImpl() {
+        super();
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualTelephoneNumber> withDefaultColumns() {
+
+        TableColumn<VisualTelephoneNumber, String> nameCol =
+                TableColumnBuilder
+                        .<VisualTelephoneNumber, String>create()
+                        .text("Name")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualTelephoneNumber, String>create()
+                                                                     .property("name")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(nameCol);
+
+        TableColumn<VisualTelephoneNumber, String> diallingStringCol =
+                TableColumnBuilder
+                        .<VisualTelephoneNumber, String>create()
+                        .text("Number")
+                        .cellValueFactory(PropertyValueFactoryBuilder.<VisualTelephoneNumber, String>create()
+                                                                     .property("diallingString")
+                                                                     .build())
+                        .build();
+        withDefaultTableColumn(diallingStringCol);
+
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualTelephoneNumber> withExtraColumns() {
+
+        TableColumn<VisualTelephoneNumber, Set<TelephoneNumberType>> typesCol =
+                TableColumnBuilder
+                        .<VisualTelephoneNumber, Set<TelephoneNumberType>>create()
+                        .text("Types")
+                        .cellValueFactory(
+                                PropertyValueFactoryBuilder.<VisualTelephoneNumber, Set<TelephoneNumberType>>create()
+                                                           .property("telephoneNumberTypes")
+                                                           .build())
+                        .build();
+        withExtraTableColumn(typesCol);
+
+        return this;
+    }
+
+    @Override
+    public VisualEntityTableViewBuilder<VisualTelephoneNumber> withDefaultPreferredWidth() {
+        withPreferredWidth(550);
+
+        return this;
+    }
+}

File src/test/java/net/poalsoft/dossier/contacts/ui/demo/ShowAddresses.java

 import javafx.scene.Group;
 import javafx.scene.Scene;
 import javafx.scene.control.Label;
+import javafx.scene.control.TableView;
 import javafx.scene.layout.VBox;
 import javafx.scene.text.Font;
 import javafx.stage.Stage;
 import net.poalsoft.dossier.contacts.ui.ContactsUiConfig;
 import net.poalsoft.dossier.contacts.ui.model.VisualAddress;
 import net.poalsoft.dossier.contacts.ui.model.VisualEntityProxyBuilder;
-import net.poalsoft.dossier.contacts.ui.view.AddressTableView;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
                 visualEntityProxyBuilder = applicationContext.getBean(VisualEntityProxyBuilder.class);
         visualEntityProxyBuilder.withVisualType(VisualAddress.class);
 
-        ObservableList<VisualAddress> telephoneNumberAdapters = FXCollections.observableArrayList();
+        ObservableList<VisualAddress> telephoneNumbers = FXCollections.observableArrayList();
         for (Contact contact : testContactsBuilder.buildTestContacts()) {
             for (Address address : contact.getAddresses()) {
-                telephoneNumberAdapters.add(
+                telephoneNumbers.add(
                         (VisualAddress)
                                 visualEntityProxyBuilder
                                         .withWrappedEntity(address)
             }
         }
 
-        tableView = new AddressTableView(telephoneNumberAdapters);
+        VisualEntityTableViewBuilder<VisualAddress> addressTableViewBuilder =
+                applicationContext.getBean("visualAddressTableViewBuilder", VisualEntityTableViewBuilder.class);
+
+        tableView = addressTableViewBuilder
+                        .withDefaultColumns()
+                        .withDefaultPreferredWidth()
+                        .withItems(telephoneNumbers)
+                        .build();
 
         System.out
               .println("Table view editable? " + tableView.isEditable());
         stage.show();
     }
 
-    private final AddressTableView tableView;
+    private final TableView<VisualAddress> tableView;
 }

File src/test/java/net/poalsoft/dossier/contacts/ui/demo/ShowEmailAddresses.java

 import javafx.scene.Group;
 import javafx.scene.Scene;
 import javafx.scene.control.Label;
+import javafx.scene.control.TableView;
 import javafx.scene.layout.VBox;
 import javafx.scene.text.Font;
 import javafx.stage.Stage;
 import net.poalsoft.dossier.contacts.ui.ContactsUiConfig;
 import net.poalsoft.dossier.contacts.ui.model.VisualEmailAddress;
 import net.poalsoft.dossier.contacts.ui.model.VisualEntityProxyBuilder;
-import net.poalsoft.dossier.contacts.ui.view.EmailAddressTableView;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
 
         }
 
-        tableView = new EmailAddressTableView(emailAddresses);
+        VisualEntityTableViewBuilder<VisualEmailAddress> personTableViewBuilder =
+                applicationContext.getBean("visualEmailAddressTableViewBuilder", VisualEntityTableViewBuilder.class);
+
+        tableView = personTableViewBuilder
+                .withDefaultColumns()
+                .withDefaultPreferredWidth()
+                .withItems(emailAddresses)
+                .build();
 
         System.out
               .println("Table view editable? " + tableView.isEditable());
         stage.show();
     }
 
-    private final EmailAddressTableView tableView;
+    private final TableView<VisualEmailAddress> tableView;
 }

File src/test/java/net/poalsoft/dossier/contacts/ui/demo/ShowPersons.java

                 visualEntityProxyBuilder = applicationContext.getBean(VisualEntityProxyBuilder.class);
         visualEntityProxyBuilder.withVisualType(VisualPerson.class);
 
-        ObservableList<VisualPerson> personAdapters = FXCollections.observableArrayList();
+        ObservableList<VisualPerson> persons = FXCollections.observableArrayList();
         for (Person person : testContactsBuilder.buildTestPersons()) {
-            personAdapters.add(
+            persons.add(
                     (VisualPerson)
                             visualEntityProxyBuilder
                                     .withWrappedEntity(person)
 
         tableView = personTableViewBuilder
                         .withDefaultColumns()
-                        .withItems(personAdapters)
+                        .withDefaultPreferredWidth()
+                        .withItems(persons)
                         .build();
 
         System.out

File src/test/java/net/poalsoft/dossier/contacts/ui/demo/ShowTelephoneNumbers.java

 import javafx.scene.Group;
 import javafx.scene.Scene;
 import javafx.scene.control.Label;
+import javafx.scene.control.TableView;
 import javafx.scene.layout.VBox;
 import javafx.scene.text.Font;
 import javafx.stage.Stage;
 import net.poalsoft.dossier.contacts.ui.ContactsUiConfig;
 import net.poalsoft.dossier.contacts.ui.model.VisualEntityProxyBuilder;
 import net.poalsoft.dossier.contacts.ui.model.VisualTelephoneNumber;
-import net.poalsoft.dossier.contacts.ui.view.TelephoneNumberTableView;
+import net.poalsoft.dossier.contacts.ui.view.VisualEntityTableViewBuilder;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
                 visualEntityProxyBuilder = applicationContext.getBean(VisualEntityProxyBuilder.class);
         visualEntityProxyBuilder.withVisualType(VisualTelephoneNumber.class);
 
-        ObservableList<VisualTelephoneNumber> telephoneNumberAdapters = FXCollections.observableArrayList();
+        ObservableList<VisualTelephoneNumber> telephoneNumbers = FXCollections.observableArrayList();
         for (Contact contact : testContactsBuilder.buildTestContacts()) {
             for (TelephoneNumber telephoneNumber : contact.getTelephoneNumbers()) {
-                telephoneNumberAdapters.add(
+                telephoneNumbers.add(
                         (VisualTelephoneNumber)
                                 visualEntityProxyBuilder
                                         .withWrappedEntity(telephoneNumber)
             }
         }
 
-        tableView = new TelephoneNumberTableView(telephoneNumberAdapters);
+        VisualEntityTableViewBuilder<VisualTelephoneNumber> tableViewBuilder =
+                applicationContext.getBean("visualTelephoneNumberTableViewBuilder", VisualEntityTableViewBuilder.class);
 
+        tableView = tableViewBuilder
+                        .withDefaultColumns()
+                        .withDefaultPreferredWidth()
+                        .withItems(telephoneNumbers)
+                        .build();
         System.out
               .println("Table view editable? " + tableView.isEditable());
     }
         stage.show();
     }
 
-    private final TelephoneNumberTableView tableView;
+    private final TableView<VisualTelephoneNumber> tableView;
 }