Chapter 5 v.4

Chapter 5

We gonna create/modify this files on this chapter:

File 1: [From scratch]


(SearchView.java)


File 2: [Modify]
----------

(AddressBookApplication.java)


File 3: [Modify]
----------

(PersonList.java)


File 4: [Modify]
----------

(NavigationTree.java)


File 5: [Modify]
----------

(PersonForm.java)


File 6: [From scratch]


(SearchFilter.java)

/////////////////////////////////////////////////////////////////////
STEP BY STEP
/////////////////////////////////////////////////////////////////////\

Step 1:

(SearchView.java)

[color=#ff00f6]
package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
import com.vaadin.ui.Panel;

public class SearchView extends Panel {
     public SearchView(final AddressBookApplication app) {
         setCaption("Search contacts");
         setSizeFull();
     }
 }
[/color]

Step 2:

(AddressBookApplication.java)

[color=#0008ff]
// Lazyly created ui references
    private ListView listView = null;
[/color]
    [color=#ff00f6]
private SearchView searchView = null;
[/color]
    [color=#0008ff]
private PersonList personList = null;
    private PersonForm personForm = null;
    private HelpWindow helpWindow = null;
    private SharingOptions sharingOptions = null;
[/color]

Step2.1:

(AddressBookApplication.java)


    [color=#0008ff]
private ListView getListView() {
        if (listView == null) {
            personList = new PersonList(this);
            personForm = new PersonForm(this);
            listView = new ListView(personList, personForm);
        }
        return listView;
    }
[/color]

    [color=#ff00f6]
private SearchView getSearchView() {
         if (searchView == null) {
             searchView = new SearchView(this);
         }
         return searchView;
     }
[/color]

[color=#0008ff]
    private HelpWindow getHelpWindow() {
        if (helpWindow == null) {
            helpWindow = new HelpWindow();
        }
        return helpWindow;
    }
[/color]

Step 3:

(AddressBookApplication.java)


    [color=#0008ff]
private HorizontalLayout createToolbar() {
        HorizontalLayout lo = new HorizontalLayout();
        lo.addComponent(newContact);
        lo.addComponent(search);
        lo.addComponent(share);
        lo.addComponent(help);
[/color]

        [color=#ff00f6]
search.addListener((
[/color][color=#ff00f6]
ClickListener) this);
[/color]
[color=#0008ff]
        share.addListener((ClickListener) this);
        help.addListener((ClickListener) this);
        newContact.addListener((ClickListener) this);

        return lo;
    }
[/color]

Step 4:

(AddressBookApplication.java)

[color=#0008ff]

    public PersonContainer getDataSource() {
        return dataSource;
    }


[/color]
    [color=#ff00f6]
public void buttonClick(ClickEvent event) {
        final Button source = event.getButton();

        if (source == search) {
            showSearchView();
    }
[/color]
[color=#0008ff]

}
[/color]

Step 5:

(AddressBookApplication.java)


[color=#0008ff]
    public void buttonClick(ClickEvent event) {
        final Button source = event.getButton();

        if (source == search) {
            showSearchView();
    }
[/color]
[color=#ff00f6]
    private void showSearchView() {
        setMainComponent(getSearchView());
    }
[/color]

[color=#0008ff]
}
[/color]

Step 6:

(PersonList.java)


[color=#0008ff]

public class PersonList extends Table {
    public PersonList(AddressBookApplication app) {
        setSizeFull();
        setContainerDataSource(app.getDataSource());

        setVisibleColumns(PersonContainer.NATURAL_COL_ORDER);
        setColumnHeaders(PersonContainer.COL_HEADERS_ENGLISH);

[/color]
[color=#ff00f6]

         /*
          * Make table selectable, react immediatedly to user events, and pass events to the
          * controller (our main application)
          */
         setSelectable(true);
         setImmediate(true);
         addListener((Property.ValueChangeListener) app);
         /* We don't want to allow users to de-select a row */
         setNullSelectionAllowed(false);
[/color]
[color=#0008ff]

    }

}


[/color]

Step 7:

(AddressBookApplication.java)


[color=#0008ff]

    private void showSearchView() {
        setMainComponent(getSearchView());
    }

[/color]
[color=#ff00f6]

    public void valueChange(ValueChangeEvent event) {
         Property property = event.getProperty();
         if (property == personList) {
             Item item = personList.getItem(personList.getValue());
             if (item != personForm.getItemDataSource()) {
                 personForm.setItemDataSource(item);
            }
         }
     }
[/color]
[color=#0008ff]

}

[/color]

Step 8:

(NavigationTree.java)

[color=#0008ff]
package com.vaadin.demo.tutorial.addressbook.ui;
[/color]

[color=#ff00f6]
import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
[/color]
[color=#0008ff]
import com.vaadin.ui.Tree;

public class NavigationTree extends Tree {
     public static final Object SHOW_ALL = "Show all";
     public static final Object SEARCH = "Search";

    public NavigationTree(
[/color][color=#ff00f6]
AddressBookApplication app
[/color][color=#0008ff]
) {
         addItem(SHOW_ALL);
         addItem(SEARCH);
[/color]

        [color=#ff00f6]
/*
          * We want items to be selectable but do not want the user to be able to
          * de-select an item.
          */
         setSelectable(true);
         setNullSelectionAllowed(false);

        // Make application handle item click events
         addListener((ItemClickListener) app);
[/color]
[color=#0008ff]

    }
 }
[/color]

Step 9:

(AddressBookApplication.java)


[color=#0008ff]

    public void valueChange(ValueChangeEvent event) {
         Property property = event.getProperty();
         if (property == personList) {
             Item item = personList.getItem(personList.getValue());
             if (item != personForm.getItemDataSource()) {
                 personForm.setItemDataSource(item);
            }
         }
     }

[/color]
[color=#ff00f6]

    public void itemClick(ItemClickEvent event) {
         if(event.getSource() == tree) {
             Object itemId = event.getItemId();
             if (itemId != null) {
                 if (NavigationTree.SHOW_ALL.equals(itemId)) {
                     showListView();
                 } else if (NavigationTree.SEARCH.equals(itemId)) {
                     showSearchView();
                 }
             }
         }
     }

[/color]
[color=#0008ff]

 }
[/color]

Step 9_1:

(PersonForm.java)


ERASE

[color=#0010fc]
package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;

public class PersonForm extends Form {

	private Button save = new Button("Save");
	private Button cancel = new Button("Cancel");

	public PersonForm() {
[/color]
		[color=#ff0000]
addField("First Name", new TextField("First Name"));
		addField("Last Name", new TextField("Last Name"));
[/color]
		[color=#0010fc]
HorizontalLayout footer = new HorizontalLayout();
		footer.setSpacing(true);
		footer.addComponent(save);
		footer.addComponent(cancel);
		setFooter(footer);
	}

}
[/color]

Step 10:

(PersonForm.java)

[color=#0008ff]
package com.vaadin.demo.tutorial.addressbook.ui;
[/color]

[color=#ff00f6]
import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
[/color]
[color=#0008ff]
import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
[/color][color=#ff00f6]

import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
[/color]

[color=#0008ff]
 public class PersonForm extends Form
[/color][color=#ff00f6]
 implements ClickListener 
[/color][color=#0008ff]
{

    private Button save = new Button("Save"
[/color][color=#ff00f6]
, (ClickListener) this
[/color][color=#0008ff]
);
     private Button cancel = new Button("Cancel"
[/color][color=#ff00f6]
, (ClickListener) this
[/color][color=#0008ff]
);
[/color]
    [color=#ff00f6]
 private Button edit = new Button("Edit", (ClickListener) this);
     private AddressBookApplication app;
[/color]

    [color=#0008ff]
public PersonForm(
[/color][color=#ff00f6]
AddressBookApplication app
[/color][color=#0008ff]
) {
[/color]
         [color=#ff00f6]
this.app = app;

        // Enable buffering so that commit() must be called for the form
         // before input is written to the data. (Form input is not written
         // immediately through to the underlying object.)
         setWriteThrough(false);
[/color]
        
        [color=#0008ff]
 HorizontalLayout footer = new HorizontalLayout();
         footer.setSpacing(true);
         footer.addComponent(save);
         footer.addComponent(cancel);
[/color]
         [color=#ff00f6]
footer.addComponent(edit);
         footer.setVisible(false);
[/color]
         
         [color=#0008ff]
setFooter(footer);
     }
[/color]
    
     [color=#ff00f6]
public void buttonClick(ClickEvent event) {
       
    }
[/color]

[color=#0008ff]
}
[/color]

Step 11:

(PersonForm.java)


[color=#0008ff]
   public void buttonClick(ClickEvent event) {
[/color]
         [color=#ff00f6]
Button source = event.getButton();

        if (source == save) {
             /* If the given input is not valid there is no point in continuing */
             if (!isValid()) {
                 return;
             }
             commit();
             setReadOnly(true);
         } else if (source == cancel) {
             discard();
             setReadOnly(true);
         } else if (source == edit) {
             setReadOnly(false);
         }
[/color]
     [color=#0008ff]
}
[/color]

Step 12:

(PersonForm.java)


[color=#0008ff]

     public void buttonClick(ClickEvent event) {
         Button source = event.getButton();

        if (source == save) {
             /* If the given input is not valid there is no point in continuing */
             if (!isValid()) {
                 return;
             }
             commit();
             setReadOnly(true);
         } else if (source == cancel) {
             discard();
             setReadOnly(true);
         } else if (source == edit) {
             setReadOnly(false);
         }
     }

[/color]
[color=#ff00f6]
     @Override
     public void setItemDataSource(Item newDataSource) {
         if (newDataSource != null) {
             List<Object> orderedProperties = Arrays
                     .asList(PersonContainer.NATURAL_COL_ORDER);
             super.setItemDataSource(newDataSource, orderedProperties);

            setReadOnly(true);
             getFooter().setVisible(true);
         } else {
             super.setItemDataSource(null);
             getFooter().setVisible(false);
         }
     }

    @Override
     public void setReadOnly(boolean readOnly) {
         super.setReadOnly(readOnly);
         save.setVisible(!readOnly);
         cancel.setVisible(!readOnly);
         edit.setVisible(readOnly);
     }
[/color]

[color=#0008ff]
}
[/color]

Step 13:

(AddressBookApplication.java)


[color=#0008ff]

    public void itemClick(ItemClickEvent event) {
         if(event.getSource() == tree) {
             Object itemId = event.getItemId();
             if (itemId != null) {
                 if (NavigationTree.SHOW_ALL.equals(itemId)) {
                     showListView();
                 } else if (NavigationTree.SEARCH.equals(itemId)) {
                     showSearchView();
                 }
             }
         }
     }

[/color]
[color=#ff00f6]

    private void addNewContanct() {
         showListView();
         personForm.addContact();
     }

[/color]
[color=#0008ff]

}

[/color]

Step 14:

(PersonForm.java)

[color=#0008ff]

public class PersonForm extends Form implements ClickListener {

    private Button save = new Button("Save", (ClickListener) this);
    private Button cancel = new Button("Cancel", (ClickListener) this);
    private Button edit = new Button("Edit", (ClickListener) this);
    private AddressBookApplication app;
[/color][color=#ff00c6]

    private boolean newContactMode = false;
    private Person newPerson = null;
[/color][color=#0008ff]


    public PersonForm(AddressBookApplication app) {
         this.app = app;

         // Enable buffering so that commit() must be called for the form
         // before input is written to the data. (Form input is not written
         // immediately through to the underlying object.)
         setWriteThrough(false);
        
         HorizontalLayout footer = new HorizontalLayout();
         footer.setSpacing(true);
         footer.addComponent(save);
         footer.addComponent(cancel);
         footer.addComponent(edit);
         footer.setVisible(false);
         
         setFooter(footer);
     }
[/color]

Step 15:

(PersonForm.java)


[color=#0008ff]

    @Override
    public void setReadOnly(boolean readOnly) {
        super.setReadOnly(readOnly);
        save.setVisible(!readOnly);
        cancel.setVisible(!readOnly);
        edit.setVisible(readOnly);
    }

[/color]
[color=#ff00f6]

    public void addContact() {
         // Create a temporary item for the form
         newPerson = new Person();
         setItemDataSource(new BeanItem(newPerson));
         newContactMode = true;
         setReadOnly(false);
     }
[/color]
[color=#0008ff]

}

[/color]

Step 16:

(PersonForm.java)

[color=#0008ff]
public void buttonClick(ClickEvent event) {
         Button source = event.getButton();

        if (source == save) {
             /* If the given input is not valid there is no point in continuing */
             if (!isValid()) {
                 return;
             }

            commit();
[/color]
            [color=#ff00f6]
 if (newContactMode) {
                 /* We need to add the new person to the container */
                 Item addedItem = app.getDataSource().addItem(newPerson);
                 /*
                  * We must update the form to use the Item from our datasource
                  * as we are now in edit mode
                  */
                 setItemDataSource(addedItem);

                newContactMode = false;
             }
[/color]
             [color=#0008ff]
setReadOnly(true);
         } else if (source == cancel) {
[/color]
            [color=#ff00f6]
 if (newContactMode) {
                 newContactMode = false;
                 setItemDataSource(null);
             } else {
[/color]
                 [color=#0008ff]
discard();
[/color]
             [color=#ff00f6]
}
[/color]
             [color=#0008ff]
setReadOnly(true);
         } else if (source == edit) {
             setReadOnly(false);
         }
     }
[/color]

Step 17:

(PersonForm.java)

[color=#0008ff]

    @Override
    public void setItemDataSource(Item newDataSource) {
[/color]
            [color=#ff00f6]
newContactMode = false;
[/color][color=#0008ff]

        if (newDataSource != null) {
            List<Object> orderedProperties = Arrays
                    .asList(PersonContainer.NATURAL_COL_ORDER);
            super.setItemDataSource(newDataSource, orderedProperties);

            setReadOnly(true);
            getFooter().setVisible(true);
        } else {
            super.setItemDataSource(null);
            getFooter().setVisible(false);
        }
    }

[/color]

Step 17_1:

(PersonForm.java)

[color=#ff00f6]

import java.util.Arrays;
import java.util.List;

import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
[/color][color=#0010fc]

import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
[/color][color=#ff00f6]

import com.vaadin.demo.tutorial.addressbook.data.Person;
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
[/color][color=#0010fc]

import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
[/color]

Step 18:

(SearchView.java)

[color=#0008ff]
package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
[/color]
[color=#ff00f6]
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.NativeSelect;
[/color]
[color=#0008ff]
import com.vaadin.ui.Panel;
[/color]
[color=#ff00f6]
import com.vaadin.ui.TextField;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
[/color]

[color=#0008ff]
public class SearchView extends Panel {
[/color]

    [color=#ff00f6]
private TextField tf;
     private NativeSelect fieldToSearch;
     private CheckBox saveSearch;
     private TextField searchName;
     private AddressBookApplication app;
[/color]

    [color=#0008ff]
public SearchView(final AddressBookApplication app) {
[/color]
         [color=#ff00f6]
this.app = app;
[/color]
        
         [color=#0008ff]
setCaption("Search contacts");
         setSizeFull();
[/color]

        [color=#ff00f6]
/* Use a FormLayout as main layout for this Panel */
         FormLayout formLayout = new FormLayout();
         setContent(formLayout);

        /* Create UI components */
         tf = new TextField("Search term");
         fieldToSearch = new NativeSelect("Field to search");
         saveSearch = new CheckBox("Save search");
         searchName = new TextField("Search name");
         Button search = new Button("Search");

        /* Initialize fieldToSearch */
         for (int i = 0; i < PersonContainer.NATURAL_COL_ORDER.length; i++) {
             fieldToSearch.addItem(PersonContainer.NATURAL_COL_ORDER[i]
);
             fieldToSearch.setItemCaption(PersonContainer.NATURAL_COL_ORDER[i]
,
                     PersonContainer.COL_HEADERS_ENGLISH[i]
);
         }

        fieldToSearch.setValue("lastName");
         fieldToSearch.setNullSelectionAllowed(false);

        /* Initialize save checkbox */
         saveSearch.setValue(true);

        /* Add all the created components to the form */
         addComponent(tf);
         addComponent(fieldToSearch);
         addComponent(saveSearch);
         addComponent(searchName);
         addComponent(search);
[/color]
     [color=#0008ff]
}
}
[/color]

Step 19:

(SearchView.java)


[color=#0008ff]

        fieldToSearch.setValue("lastName");
        fieldToSearch.setNullSelectionAllowed(false);

        /* Initialize save checkbox */
        saveSearch.setValue(true);
[/color][color=#ff00f6]

        saveSearch.setImmediate(true);
        saveSearch.addListener(new ClickListener() {
            public void buttonClick(ClickEvent event) {
                searchName.setVisible(event.getButton().booleanValue());
            }
        });

[/color]
[color=#0008ff]

        /* Add all the created components to the form */
         addComponent(tf);
         addComponent(fieldToSearch);
         addComponent(saveSearch);
         addComponent(searchName);
         addComponent(search);
     }
}

[/color]

Step 20:

(SearchFilter.java)

[color=#ff00f6]
package com.vaadin.demo.tutorial.addressbook.data;

import java.io.Serializable;

public class SearchFilter implements Serializable {
 
      private final String term;
      private final Object propertyId;
      private String searchName;
 
      public SearchFilter(Object propertyId, String searchTerm, String name) {
            this.propertyId = propertyId;
            this.term = searchTerm;
            this.searchName = name;
      }
 
      // + getters
}
[/color]

Step 21:

(SearchView.java)


[color=#0008ff]

        /* Initialize save checkbox */
        saveSearch.setValue(true);
        saveSearch.setImmediate(true);
        saveSearch.addListener(new ClickListener() {
            public void buttonClick(ClickEvent event) {
                searchName.setVisible(event.getButton().booleanValue());
            }
        });

[/color][color=#ff00f6]

        search.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                performSearch();
            }

        });

[/color][color=#0008ff]

        /* Add all the created components to the form */
        addComponent(tf);
        addComponent(fieldToSearch);
        addComponent(saveSearch);
        addComponent(searchName);
        addComponent(search);
    }

[/color]

Step 22:

(SearchView.java)


[color=#0008ff]

        /* Add all the created components to the form */
        addComponent(tf);
        addComponent(fieldToSearch);
        addComponent(saveSearch);
        addComponent(searchName);
        addComponent(search);
    }
[/color]
[color=#ff00f6]

    private void performSearch() {
        String searchTerm = (String) tf.getValue();
        SearchFilter searchFilter = new SearchFilter(fieldToSearch.getValue(),
                searchTerm, (String) searchName.getValue());
        if (saveSearch.booleanValue()) {
            app.saveSearch(searchFilter);
        }
        app.search(searchFilter);
    }
[/color]
[color=#0008ff]

}
[/color]

Step 23:

(AddressBookApplication.java)


[color=#0008ff]

    private void addNewContanct() {
         showListView();
         personForm.addContact();
     }
[/color]
[color=#ff00f6]

    public void search(SearchFilter searchFilter) {
        // clear previous filters
        getDataSource().removeAllContainerFilters();
        // filter contacts with given filter
        getDataSource().addContainerFilter(searchFilter.getPropertyId(),
                searchFilter.getTerm(), true, false);
        showListView();

    }
[/color]
[color=#0008ff]

}
[/color]

Step 24:

(AddressBookApplication.java)


[color=#0008ff]

    public void itemClick(ItemClickEvent event) {
        if (event.getSource() == tree) {
            Object itemId = event.getItemId();
            if (itemId != null) {
                if (NavigationTree.SHOW_ALL.equals(itemId)) {
[/color][color=#ff00f6]

                    // clear previous filters
                    getDataSource().removeAllContainerFilters();
[/color][color=#0008ff]

                    showListView();
                } else if (NavigationTree.SEARCH.equals(itemId)) {
                    showSearchView();
[/color][color=#ff00f6]

                } else if (itemId instanceof SearchFilter) {
                    search((SearchFilter) itemId);
[/color][color=#0008ff]

                }
            }
        }
}
[/color]

Step 25:

(AddressBookApplication.java)


[color=#0008ff]

    public void search(SearchFilter searchFilter) {
        // clear previous filters
        getDataSource().removeAllContainerFilters();
        // filter contacts with given filter
        getDataSource().addContainerFilter(searchFilter.getPropertyId(),
                searchFilter.getTerm(), true, false);
        showListView();

    }
[/color]
[color=#ff00f6]

    public void saveSearch(SearchFilter searchFilter) {
        tree.addItem(searchFilter);
        tree.setParent(searchFilter, NavigationTree.SEARCH);
        // mark the saved search as a leaf (cannot have children)
        tree.setChildrenAllowed(searchFilter, false);
        // make sure "Search" is expanded
        tree.expandItem(NavigationTree.SEARCH);
        // select the saved search
        tree.setValue(searchFilter);
    }
[/color]
[color=#0008ff]

}

[/color]

Step 25_1:

(AddressBookApplication.java)


[color=#0010fc]
import com.vaadin.Application;
[/color]
[color=#ff00f6]
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
[/color]
[color=#0010fc]
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
[/color]
[color=#ff00f6]
import com.vaadin.demo.tutorial.addressbook.data.SearchFilter;
[/color]
[color=#0010fc]
import com.vaadin.demo.tutorial.addressbook.ui.HelpWindow;
import com.vaadin.demo.tutorial.addressbook.ui.ListView;
import com.vaadin.demo.tutorial.addressbook.ui.NavigationTree;
import com.vaadin.demo.tutorial.addressbook.ui.PersonForm;
import com.vaadin.demo.tutorial.addressbook.ui.PersonList;
[/color]
[color=#ff00f6]
import com.vaadin.demo.tutorial.addressbook.ui.SearchView;
[/color]
[color=#0010fc]
import com.vaadin.demo.tutorial.addressbook.ui.SharingOptions;
[/color]
[color=#ff00f6]
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
[/color]
[color=#0010fc]
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
[/color]
[color=#ff00f6]
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
[/color]

Step 25_2:

(AddressBookApplication.java)

[color=#0010fc]

public class AddressBookApplication extends Application
[/color][color=#ff00f6]
 implements
        ClickListener, ValueChangeListener, ItemClickListener 
[/color][color=#0010fc]
{

    private NavigationTree tree = new NavigationTree(
[/color][color=#ff00f6]
this
[/color][color=#0010fc]
);

    private Button newContact = new Button("Add contact");
    private Button search = new Button("Search");
    private Button share = new Button("Share");
    private Button help = new Button("Help");
    private SplitPanel horizontalSplit = new SplitPanel(
            SplitPanel.ORIENTATION_HORIZONTAL);
[/color]

Step 25_3:

(AddressBookApplication.java)

[color=#0010fc]

private HorizontalLayout createToolbar() {
        HorizontalLayout lo = new HorizontalLayout();
        lo.addComponent(newContact);
        lo.addComponent(search);
        lo.addComponent(share);
        lo.addComponent(help);

        search.addListener((ClickListener) this);
[/color][color=#ff00f6]

        share.addListener((ClickListener) this);
        help.addListener((ClickListener) this);
        newContact.addListener((ClickListener) this);
[/color][color=#0010fc]


        return lo;
    }
[/color]

Step 25_4:

(AddressBookApplication.java)

[color=#0010fc]

    public void buttonClick(ClickEvent event) {
        final Button source = event.getButton();

        if (source == search) {
            showSearchView();
[/color][color=#ff00f6]

        } else if (source == help) {
            showHelpWindow();
        } else if (source == share) {
            showShareWindow();
        } else if (source == newContact) {
            addNewContanct();
        }
[/color][color=#0010fc]

    }

[/color]

Step 25_5:

(AddressBookApplication.java)

[color=#0010fc]

public void buttonClick(ClickEvent event) {
        final Button source = event.getButton();

        if (source == search) {
            showSearchView();
        } else if (source == help) {
            showHelpWindow();
        } else if (source == share) {
            showShareWindow();
        } else if (source == newContact) {
            addNewContanct();
        }
    }
[/color][color=#ff00f6]


    private void showHelpWindow() {
        getMainWindow().addWindow(getHelpWindow());
    }

    private void showShareWindow() {
        getMainWindow().addWindow(getSharingOptions());
    }

    private void showListView() {
        setMainComponent(getListView());
    }
[/color][color=#0010fc]


    private void showSearchView() {
        setMainComponent(getSearchView());
    }

[/color]

Step 26:

(SearchFilter.java)


[color=#0008ff]

    public SearchFilter(Object propertyId, String searchTerm, String name) {
        this.propertyId = propertyId;
        this.term = searchTerm;
        this.searchName = name;
    }
[/color]
[color=#ff00f6]

    @Override
    public String toString() {
        return getSearchName();
    }
[/color]
[color=#0008ff]

}

[/color]

Step 26_1:

(AddressBookApplication.java)

[color=#0010fc]

public SearchFilter(Object propertyId, String searchTerm, String name) {
        this.propertyId = propertyId;
        this.term = searchTerm;
        this.searchName = name;
    }
[/color][color=#ff00f6]


    /**
     * @return the term
     */
    public String getTerm() {
        return term;
    }

    /**
     * @return the propertyId
     */
    public Object getPropertyId() {
        return propertyId;
    }

    /**
     * @return the name of the search
     */
    public String getSearchName() {
        return searchName;
    }
[/color][color=#0010fc]


    @Override
    public String toString() {
        return getSearchName();
    }


[/color]

/////////////////////////////////////////////////////////////////////
FINISHED CODE
/////////////////////////////////////////////////////////////////////\

File 1:

(SearchView.java)


package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
import com.vaadin.demo.tutorial.addressbook.data.SearchFilter;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.FormLayout;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;

public class SearchView extends Panel {

    private TextField tf;
    private NativeSelect fieldToSearch;
    private CheckBox saveSearch;
    private TextField searchName;
    private AddressBookApplication app;

    public SearchView(final AddressBookApplication app) {
        this.app = app;

        setCaption("Search contacts");
        setSizeFull();

        /* Use a FormLayout as main layout for this Panel */
        FormLayout formLayout = new FormLayout();
        setContent(formLayout);

        /* Create UI components */
        tf = new TextField("Search term");
        fieldToSearch = new NativeSelect("Field to search");
        saveSearch = new CheckBox("Save search");
        searchName = new TextField("Search name");
        Button search = new Button("Search");

        /* Initialize fieldToSearch */
        for (int i = 0; i < PersonContainer.NATURAL_COL_ORDER.length; i++) {
            fieldToSearch.addItem(PersonContainer.NATURAL_COL_ORDER);
            fieldToSearch.setItemCaption(PersonContainer.NATURAL_COL_ORDER,
                    PersonContainer.COL_HEADERS_ENGLISH);
        }

        fieldToSearch.setValue("lastName");
        fieldToSearch.setNullSelectionAllowed(false);

        /* Initialize save checkbox */
        saveSearch.setValue(true);
        saveSearch.setImmediate(true);
        saveSearch.addListener(new ClickListener() {
            public void buttonClick(ClickEvent event) {
                searchName.setVisible(event.getButton().booleanValue());
            }
        });

        search.addListener(new Button.ClickListener() {
            public void buttonClick(ClickEvent event) {
                performSearch();
            }

        });

        /* Add all the created components to the form */
        addComponent(tf);
        addComponent(fieldToSearch);
        addComponent(saveSearch);
        addComponent(searchName);
        addComponent(search);
    }

    private void performSearch() {
        String searchTerm = (String) tf.getValue();
        SearchFilter searchFilter = new SearchFilter(fieldToSearch.getValue(),
                searchTerm, (String) searchName.getValue());
        if (saveSearch.booleanValue()) {
            app.saveSearch(searchFilter);
        }
        app.search(searchFilter);
    }

}

File 2:

(AddressBookApplication.java)


package com.vaadin.demo.tutorial.addressbook;

import com.vaadin.Application;
import com.vaadin.data.Item;
import com.vaadin.data.Property;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
import com.vaadin.demo.tutorial.addressbook.data.SearchFilter;
import com.vaadin.demo.tutorial.addressbook.ui.HelpWindow;
import com.vaadin.demo.tutorial.addressbook.ui.ListView;
import com.vaadin.demo.tutorial.addressbook.ui.NavigationTree;
import com.vaadin.demo.tutorial.addressbook.ui.PersonForm;
import com.vaadin.demo.tutorial.addressbook.ui.PersonList;
import com.vaadin.demo.tutorial.addressbook.ui.SearchView;
import com.vaadin.demo.tutorial.addressbook.ui.SharingOptions;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;

public class AddressBookApplication extends Application implements
        ClickListener, ValueChangeListener, ItemClickListener {

    private NavigationTree tree = new NavigationTree(this);

    private Button newContact = new Button("Add contact");
    private Button search = new Button("Search");
    private Button share = new Button("Share");
    private Button help = new Button("Help");
    private SplitPanel horizontalSplit = new SplitPanel(
            SplitPanel.ORIENTATION_HORIZONTAL);

    // Lazyly created ui references
    private ListView listView = null;
    private SearchView searchView = null;
    private PersonList personList = null;
    private PersonForm personForm = null;
    private HelpWindow helpWindow = null;
    private SharingOptions sharingOptions = null;

    private PersonContainer dataSource = PersonContainer.createWithTestData();

    @Override
    public void init() {
        buildMainLayout();
        setMainComponent(getListView());
    }

    private void buildMainLayout() {
        setMainWindow(new Window("Address Book Demo application"));

        VerticalLayout layout = new VerticalLayout();
        layout.setSizeFull();

        layout.addComponent(createToolbar());
        layout.addComponent(horizontalSplit);
        layout.setExpandRatio(horizontalSplit, 1);

        horizontalSplit.setSplitPosition(200, SplitPanel.UNITS_PIXELS);
        horizontalSplit.setFirstComponent(tree);

        getMainWindow().setContent(layout);
    }

    private HorizontalLayout createToolbar() {
        HorizontalLayout lo = new HorizontalLayout();
        lo.addComponent(newContact);
        lo.addComponent(search);
        lo.addComponent(share);
        lo.addComponent(help);

        search.addListener((ClickListener) this);
        share.addListener((ClickListener) this);
        help.addListener((ClickListener) this);
        newContact.addListener((ClickListener) this);

        return lo;
    }

    private void setMainComponent(Component c) {
        horizontalSplit.setSecondComponent(c);
    }

    /*
     * View getters exist so we can lazily generate the views, resulting in
     * faster application startup time.
     */
    private ListView getListView() {
        if (listView == null) {
            personList = new PersonList(this);
            personForm = new PersonForm(this);
            listView = new ListView(personList, personForm);
        }
        return listView;
    }

    private SearchView getSearchView() {
        if (searchView == null) {
            searchView = new SearchView(this);
        }
        return searchView;
    }

    private HelpWindow getHelpWindow() {
        if (helpWindow == null) {
            helpWindow = new HelpWindow();
        }
        return helpWindow;
    }

    private SharingOptions getSharingOptions() {
        if (sharingOptions == null) {
            sharingOptions = new SharingOptions();
        }
        return sharingOptions;
    }

    public PersonContainer getDataSource() {
        return dataSource;
    }

    public void buttonClick(ClickEvent event) {
        final Button source = event.getButton();

        if (source == search) {
            showSearchView();
        } else if (source == help) {
            showHelpWindow();
        } else if (source == share) {
            showShareWindow();
        } else if (source == newContact) {
            addNewContanct();
        }
    }

    private void showHelpWindow() {
        getMainWindow().addWindow(getHelpWindow());
    }

    private void showShareWindow() {
        getMainWindow().addWindow(getSharingOptions());
    }

    private void showListView() {
        setMainComponent(getListView());
    }

    private void showSearchView() {
        setMainComponent(getSearchView());
    }

    public void valueChange(ValueChangeEvent event) {
        Property property = event.getProperty();
        if (property == personList) {
            Item item = personList.getItem(personList.getValue());
            if (item != personForm.getItemDataSource()) {
                personForm.setItemDataSource(item);
            }
        }
    }

    public void itemClick(ItemClickEvent event) {
        if (event.getSource() == tree) {
            Object itemId = event.getItemId();
            if (itemId != null) {
                if (NavigationTree.SHOW_ALL.equals(itemId)) {
                        // clear previous filters
                        getDataSource().removeAllContainerFilters();
                    showListView();
                } else if (NavigationTree.SEARCH.equals(itemId)) {
                    showSearchView();
                } else if (itemId instanceof SearchFilter) {
                    search((SearchFilter) itemId);
                }
            }
        }
    }

    private void addNewContanct() {
        showListView();
        personForm.addContact();
    }

    public void search(SearchFilter searchFilter) {
        // clear previous filters
        getDataSource().removeAllContainerFilters();
        // filter contacts with given filter
        getDataSource().addContainerFilter(searchFilter.getPropertyId(),
                searchFilter.getTerm(), true, false);
        showListView();

    }

    public void saveSearch(SearchFilter searchFilter) {
        tree.addItem(searchFilter);
        tree.setParent(searchFilter, NavigationTree.SEARCH);
        // mark the saved search as a leaf (cannot have children)
        tree.setChildrenAllowed(searchFilter, false);
        // make sure "Search" is expanded
        tree.expandItem(NavigationTree.SEARCH);
        // select the saved search
        tree.setValue(searchFilter);
    }

}

File 3:

(PersonList.java)


package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
import com.vaadin.ui.Table;

public class PersonList extends Table {
    public PersonList(AddressBookApplication app) {
        setSizeFull();
        setContainerDataSource(app.getDataSource());

        setVisibleColumns(PersonContainer.NATURAL_COL_ORDER);
        setColumnHeaders(PersonContainer.COL_HEADERS_ENGLISH);

        /*
         * Make table selectable, react immediatedly to user events, and pass
         * events to the controller (our main application)
         */
        setSelectable(true);
        setImmediate(true);
        addListener((ValueChangeListener) app);
        /* We don't want to allow users to de-select a row */
        setNullSelectionAllowed(false);

    }

}

File 4:

(NavigationTree.java)


package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.ui.Tree;

public class NavigationTree extends Tree {
    public static final Object SHOW_ALL = "Show all";
    public static final Object SEARCH = "Search";

    public NavigationTree(AddressBookApplication app) {
        addItem(SHOW_ALL);
        addItem(SEARCH);

        /*
         * We want items to be selectable but do not want the user to be able to
         * de-select an item.
         */
        setSelectable(true);
        setNullSelectionAllowed(false);

        // Make application handle item click events
        addListener((ItemClickListener) app);

    }
}

File 5:

(PersonForm.java)


package com.vaadin.demo.tutorial.addressbook.ui;

import java.util.Arrays;
import java.util.List;

import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
import com.vaadin.demo.tutorial.addressbook.data.Person;
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;

public class PersonForm extends Form implements ClickListener {

    private Button save = new Button("Save", (ClickListener) this);
    private Button cancel = new Button("Cancel", (ClickListener) this);
    private Button edit = new Button("Edit", (ClickListener) this);
    private AddressBookApplication app;
    private boolean newContactMode = false;
    private Person newPerson = null;

    public PersonForm(AddressBookApplication app) {
        this.app = app;

        /*
         * Enable buffering so that commit() must be called for the form before
         * input is written to the data. (Form input is not written immediately
         * through to the underlying object.)
         */
        setWriteThrough(false);

        HorizontalLayout footer = new HorizontalLayout();
        footer.setSpacing(true);
        footer.addComponent(save);
        footer.addComponent(cancel);
        footer.addComponent(edit);
        footer.setVisible(false);

        setFooter(footer);
    }

    public void buttonClick(ClickEvent event) {
        Button source = event.getButton();

        if (source == save) {
            /* If the given input is not valid there is no point in continuing */
            if (!isValid()) {
                return;
            }

            commit();
            if (newContactMode) {
                /* We need to add the new person to the container */
                Item addedItem = app.getDataSource().addItem(newPerson);
                /*
                 * We must update the form to use the Item from our datasource
                 * as we are now in edit mode (no longer in add mode)
                 */
                setItemDataSource(addedItem);

                newContactMode = false;
            }
            setReadOnly(true);
        } else if (source == cancel) {
            if (newContactMode) {
                newContactMode = false;
                /* Clear the form and make it invisible */
                setItemDataSource(null);
            } else {
                discard();
            }
            setReadOnly(true);
        } else if (source == edit) {
            setReadOnly(false);
        }
    }

    @Override
    public void setItemDataSource(Item newDataSource) {
            newContactMode = false;
        if (newDataSource != null) {
            List<Object> orderedProperties = Arrays
                    .asList(PersonContainer.NATURAL_COL_ORDER);
            super.setItemDataSource(newDataSource, orderedProperties);

            setReadOnly(true);
            getFooter().setVisible(true);
        } else {
            super.setItemDataSource(null);
            getFooter().setVisible(false);
        }
    }

    @Override
    public void setReadOnly(boolean readOnly) {
        super.setReadOnly(readOnly);
        save.setVisible(!readOnly);
        cancel.setVisible(!readOnly);
        edit.setVisible(readOnly);
    }

    public void addContact() {
        // Create a temporary item for the form
        newPerson = new Person();
        setItemDataSource(new BeanItem(newPerson));
                newContactMode = true;
        setReadOnly(false);
    }

}

File 6:

(SearchFilter.java)


package com.vaadin.demo.tutorial.addressbook.data;

import java.io.Serializable;

public class SearchFilter implements Serializable {

    private final String term;
    private final Object propertyId;
    private String searchName;

    public SearchFilter(Object propertyId, String searchTerm, String name) {
        this.propertyId = propertyId;
        this.term = searchTerm;
        this.searchName = name;
    }

    /**
     * @return the term
     */
    public String getTerm() {
        return term;
    }

    /**
     * @return the propertyId
     */
    public Object getPropertyId() {
        return propertyId;
    }

    /**
     * @return the name of the search
     */
    public String getSearchName() {
        return searchName;
    }

    @Override
    public String toString() {
        return getSearchName();
    }

}

/////////////////////////////////////////////////////////////////////
START CODE SOURCE
/////////////////////////////////////////////////////////////////////\

File 2:

(AddressBookApplication.java)

[color=#0010fc]
package com.vaadin.demo.tutorial.addressbook;

import com.vaadin.Application;
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
import com.vaadin.demo.tutorial.addressbook.ui.HelpWindow;
import com.vaadin.demo.tutorial.addressbook.ui.ListView;
import com.vaadin.demo.tutorial.addressbook.ui.NavigationTree;
import com.vaadin.demo.tutorial.addressbook.ui.PersonForm;
import com.vaadin.demo.tutorial.addressbook.ui.PersonList;
import com.vaadin.demo.tutorial.addressbook.ui.SharingOptions;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.SplitPanel;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class AddressBookApplication extends Application {

	private NavigationTree tree = new NavigationTree();

	private Button newContact = new Button("Add contact");
	private Button search = new Button("Search");
	private Button share = new Button("Share");
	private Button help = new Button("Help");
	private SplitPanel horizontalSplit = new SplitPanel(
			SplitPanel.ORIENTATION_HORIZONTAL);

	// Lazyly created ui references
	private ListView listView = null;
	private PersonList personList = null;
	private PersonForm personForm = null;
	private HelpWindow helpWindow = null;
	private SharingOptions sharingOptions = null;

	private PersonContainer dataSource = PersonContainer.createWithTestData();

	@Override
	public void init() {
		buildMainLayout();
		setMainComponent(getListView());
	}

	private void buildMainLayout() {
		setMainWindow(new Window("Address Book Demo application"));

		VerticalLayout layout = new VerticalLayout();
		layout.setSizeFull();

		layout.addComponent(createToolbar());
		layout.addComponent(horizontalSplit);
		layout.setExpandRatio(horizontalSplit, 1);

		horizontalSplit.setSplitPosition(200, SplitPanel.UNITS_PIXELS);
		horizontalSplit.setFirstComponent(tree);

		getMainWindow().setContent(layout);
	}

	private HorizontalLayout createToolbar() {
		HorizontalLayout lo = new HorizontalLayout();
		lo.addComponent(newContact);
		lo.addComponent(search);
		lo.addComponent(share);
		lo.addComponent(help);

		return lo;
	}

	private void setMainComponent(Component c) {
		horizontalSplit.setSecondComponent(c);
	}

	/*
	 * View getters exist so we can lazily generate the views, resulting in
	 * faster application startup time.
	 */
	private ListView getListView() {
		if (listView == null) {
			personList = new PersonList(this);
			personForm = new PersonForm();
			listView = new ListView(personList, personForm);
		}
		return listView;
	}

	private HelpWindow getHelpWindow() {
		if (helpWindow == null) {
			helpWindow = new HelpWindow();
		}
		return helpWindow;
	}

	private SharingOptions getSharingOptions() {
		if (sharingOptions == null) {
			sharingOptions = new SharingOptions();
		}
		return sharingOptions;
	}

	public PersonContainer getDataSource() {
		return dataSource;
	}

}

[/color]

File 3:

(PersonList.java)

[color=#0010fc]
package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.demo.tutorial.addressbook.AddressBookApplication;
import com.vaadin.demo.tutorial.addressbook.data.PersonContainer;
import com.vaadin.ui.Table;

public class PersonList extends Table {
	public PersonList(AddressBookApplication app) {
		setSizeFull();
		setContainerDataSource(app.getDataSource());

		setVisibleColumns(PersonContainer.NATURAL_COL_ORDER);
		setColumnHeaders(PersonContainer.COL_HEADERS_ENGLISH);
	}

}
[/color]

File 4:

(NavigationTree.java)

[color=#0010fc]
package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.ui.Tree;

public class NavigationTree extends Tree {
	public static final Object SHOW_ALL = "Show all";
	public static final Object SEARCH = "Search";

	public NavigationTree() {
		addItem(SHOW_ALL);
		addItem(SEARCH);
	}
}
[/color]

File 5:

(PersonForm.java)

[color=#0010fc]
package com.vaadin.demo.tutorial.addressbook.ui;

import com.vaadin.ui.Button;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;

public class PersonForm extends Form {

	private Button save = new Button("Save");
	private Button cancel = new Button("Cancel");

	public PersonForm() {
[/color]
		[color=#ff0000]
addField("First Name", new TextField("First Name"));
		addField("Last Name", new TextField("Last Name"));
[/color]
		[color=#0010fc]
HorizontalLayout footer = new HorizontalLayout();
		footer.setSpacing(true);
		footer.addComponent(save);
		footer.addComponent(cancel);
		setFooter(footer);
	}

}
[/color]