Hello Vaadin Lovers! -_-
This is the structure of this threat:
[b]
1 - My Goal
2 - Step by Step
3 -
QUESTIONS
[/b]
(for “Advanced Users” if they have time to explain us “why” or if they can apport some source where it explains this questions.)
4 - Original Source where we start from.
(You can also download the project from
HERE
)
1 - Goal for this threat.
Step 1: Only when I put right username and password.
Step 2: I get permision to see “AddresBookApplication”.
2 - Step by Step
Step 1:
We go to this link and search after the source of this example.
Authentification Source
Step 2:
We copy this source inside the link before.
[color=#f600ff]
private Layout buildLoginForm() {
FormLayout layout = new FormLayout();
// Create a label which we can use to give feedback to the user
final Label feedbackLabel = new Label();
// Create input fields for username and password
final TextField usernameField = new TextField("Username");
final TextField passwordField = new TextField("Password");
passwordField.setSecret(true);
// Add the login button
Button login = new Button(Lang.getMessage("Login"),
new ClickListener() {
private static final long serialVersionUID = -5577423546946890721L;
public void buttonClick(ClickEvent event) {
// Try to log in the user when the button is clicked
String username = (String) usernameField.getValue();
String password = (String) passwordField.getValue();
try {
AuthenticationUtil.authenticate(username, password);
// User is now logged in, now change the view or do
// whatever is needed after a login.
} catch (InvalidCredentialsException e) {
feedbackLabel
.setValue("Either username or password was wrong");
} catch (AccountLockedException e) {
feedbackLabel
.setValue("The given account has been locked");
}
}
});
layout.addComponent(feedbackLabel);
layout.addComponent(usernameField);
layout.addComponent(passwordField);
layout.addComponent(login);
return layout;
}
[/color]
Step 3:
And we paste it right here
(Blue color original Source)
(Pink color the pasted source)
File 1:
AddressBookApplication.Java
[color=#0000ff]
package com.vaadin.demo.tutorial.addressbook;
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.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.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
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;
import com.vaadin.ui.Window.Notification;
@SuppressWarnings("serial")
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"));
setTheme("contacts");
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);
search.setIcon(new ThemeResource("icons/32/folder-add.png"));
share.setIcon(new ThemeResource("icons/32/users.png"));
help.setIcon(new ThemeResource("icons/32/help.png"));
newContact.setIcon(new ThemeResource("icons/32/document-add.png"));
lo.setMargin(true);
lo.setSpacing(true);
lo.setStyleName("toolbar");
lo.setWidth("100%");
Embedded em = new Embedded("", new ThemeResource("images/logo.png"));
lo.addComponent(em);
lo.setComponentAlignment(em, Alignment.MIDDLE_RIGHT);
lo.setExpandRatio(em, 1);
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();
getMainWindow().showNotification(
"Searched for " + searchFilter.getPropertyId() + "=*"
+ searchFilter.getTerm() + "*, found "
+ getDataSource().size() + " item(s).",
Notification.TYPE_TRAY_NOTIFICATION);
}
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=#f600ff]
private Layout buildLoginForm() {
FormLayout layout = new FormLayout();
// Create a label which we can use to give feedback to the user
final Label feedbackLabel = new Label();
// Create input fields for username and password
final TextField usernameField = new TextField("Username");
final TextField passwordField = new TextField("Password");
passwordField.setSecret(true);
// Add the login button
Button login = new Button(Lang.getMessage("Login"),
new ClickListener() {
private static final long serialVersionUID = -5577423546946890721L;
public void buttonClick(ClickEvent event) {
// Try to log in the user when the button is clicked
String username = (String) usernameField.getValue();
String password = (String) passwordField.getValue();
try {
AuthenticationUtil.authenticate(username, password);
// User is now logged in, now change the view or do
// whatever is needed after a login.
} catch (InvalidCredentialsException e) {
feedbackLabel
.setValue("Either username or password was wrong");
} catch (AccountLockedException e) {
feedbackLabel
.setValue("The given account has been locked");
}
}
});
layout.addComponent(feedbackLabel);
layout.addComponent(usernameField);
layout.addComponent(passwordField);
layout.addComponent(login);
return layout;
}
[/color]
[color=#0000ff]
}
[/color]
Step 4:
Now we run it on the server.
Step 5:
And this is the result we get back!
3 -
Questions
Question 1: How can I say to the application. STOP!! First the Authentification and after run the Template!
Question 2: We don´t want to make a Advanced “User Admin Manager”. Where can i put Username: Test Password: 1234
4 -
Original Files
File 1:
AddressBookApplication.Java
File 2:
Person.java
File 3:
PersonContainer.java
File 4:
SearchFiler.java
File 5:
HelpWindow.java
File 6:
ListView.java
File 7:
NavigationTree.java
File 8:
PersonForm.java
File 9:
PersonList.java
File 10:
SearchView.java
File 11:
SharingOptions.java
File 12:
Styles.css
[color=#0000ff]
File 1:
AddressBookApplication.Java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook;
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.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.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.Embedded;
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;
import com.vaadin.ui.Window.Notification;
@SuppressWarnings("serial")
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"));
setTheme("contacts");
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);
search.setIcon(new ThemeResource("icons/32/folder-add.png"));
share.setIcon(new ThemeResource("icons/32/users.png"));
help.setIcon(new ThemeResource("icons/32/help.png"));
newContact.setIcon(new ThemeResource("icons/32/document-add.png"));
lo.setMargin(true);
lo.setSpacing(true);
lo.setStyleName("toolbar");
lo.setWidth("100%");
Embedded em = new Embedded("", new ThemeResource("images/logo.png"));
lo.addComponent(em);
lo.setComponentAlignment(em, Alignment.MIDDLE_RIGHT);
lo.setExpandRatio(em, 1);
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();
getMainWindow().showNotification(
"Searched for " + searchFilter.getPropertyId() + "=*"
+ searchFilter.getTerm() + "*, found "
+ getDataSource().size() + " item(s).",
Notification.TYPE_TRAY_NOTIFICATION);
}
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 2:
Person.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.data;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Person implements Serializable {
private String firstName = "";
private String lastName = "";
private String email = "";
private String phoneNumber = "";
private String streetAddress = "";
private Integer postalCode = null;
private String city = "";
/**
* @return the firstName
*/
public String getFirstName() {
return firstName;
}
/**
* @param firstName
* the firstName to set
*/
public void setFirstName(String firstName) {
this.firstName = firstName;
}
/**
* @return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* @param lastName
* the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
/**
* @return the email
*/
public String getEmail() {
return email;
}
/**
* @param email
* the email to set
*/
public void setEmail(String email) {
this.email = email;
}
/**
* @return the phoneNumber
*/
public String getPhoneNumber() {
return phoneNumber;
}
/**
* @param phoneNumber
* the phoneNumber to set
*/
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
/**
* @return the streetAddress
*/
public String getStreetAddress() {
return streetAddress;
}
/**
* @param streetAddress
* the streetAddress to set
*/
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
/**
* @return the postalCode
*/
public Integer getPostalCode() {
return postalCode;
}
/**
* @param postalCode
* the postalCode to set
*/
public void setPostalCode(Integer postalCode) {
this.postalCode = postalCode;
}
/**
* @return the city
*/
public String getCity() {
return city;
}
/**
* @param city
* the city to set
*/
public void setCity(String city) {
this.city = city;
}
}
File 3:
PersonContainer.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.data;
import java.io.Serializable;
import java.util.Random;
import com.vaadin.data.util.BeanItemContainer;
@SuppressWarnings("serial")
public class PersonContainer extends BeanItemContainer<Person> implements
Serializable {
/**
* Natural property order for Person bean. Used in tables and forms.
*/
public static final Object[] NATURAL_COL_ORDER = new Object[]
{
"firstName", "lastName", "email", "phoneNumber", "streetAddress",
"postalCode", "city" };
/**
* "Human readable" captions for properties in same order as in
* NATURAL_COL_ORDER.
*/
public static final String[] COL_HEADERS_ENGLISH = new String[]
{
"First name", "Last name", "Email", "Phone number",
"Street Address", "Postal Code", "City" };
public PersonContainer() throws InstantiationException,
IllegalAccessException {
super(Person.class);
}
public static PersonContainer createWithTestData() {
final String[] fnames = { "Peter", "Alice", "Joshua", "Mike", "Olivia",
"Nina", "Alex", "Rita", "Dan", "Umberto", "Henrik", "Rene",
"Lisa", "Marge" };
final String[] lnames = { "Smith", "Gordon", "Simpson", "Brown",
"Clavel", "Simons", "Verne", "Scott", "Allison", "Gates",
"Rowling", "Barks", "Ross", "Schneider", "Tate" };
final String cities[] = { "Amsterdam", "Berlin", "Helsinki",
"Hong Kong", "London", "Luxemburg", "New York", "Oslo",
"Paris", "Rome", "Stockholm", "Tokyo", "Turku" };
final String streets[] = { "4215 Blandit Av.", "452-8121 Sem Ave",
"279-4475 Tellus Road", "4062 Libero. Av.", "7081 Pede. Ave",
"6800 Aliquet St.", "P.O. Box 298, 9401 Mauris St.",
"161-7279 Augue Ave", "P.O. Box 496, 1390 Sagittis. Rd.",
"448-8295 Mi Avenue", "6419 Non Av.",
"659-2538 Elementum Street", "2205 Quis St.",
"252-5213 Tincidunt St.", "P.O. Box 175, 4049 Adipiscing Rd.",
"3217 Nam Ave", "P.O. Box 859, 7661 Auctor St.",
"2873 Nonummy Av.", "7342 Mi, Avenue",
"539-3914 Dignissim. Rd.", "539-3675 Magna Avenue",
"Ap #357-5640 Pharetra Avenue", "416-2983 Posuere Rd.",
"141-1287 Adipiscing Avenue", "Ap #781-3145 Gravida St.",
"6897 Suscipit Rd.", "8336 Purus Avenue", "2603 Bibendum. Av.",
"2870 Vestibulum St.", "Ap #722 Aenean Avenue",
"446-968 Augue Ave", "1141 Ultricies Street",
"Ap #992-5769 Nunc Street", "6690 Porttitor Avenue",
"Ap #105-1700 Risus Street",
"P.O. Box 532, 3225 Lacus. Avenue", "736 Metus Street",
"414-1417 Fringilla Street", "Ap #183-928 Scelerisque Road",
"561-9262 Iaculis Avenue" };
PersonContainer c = null;
Random r = new Random(0);
try {
c = new PersonContainer();
for (int i = 0; i < 100; i++) {
Person p = new Person();
p.setFirstName(fnames[r.nextInt(fnames.length)]
);
p.setLastName(lnames[r.nextInt(lnames.length)]
);
p.setCity(cities[r.nextInt(cities.length)]
);
p.setEmail(p.getFirstName().toLowerCase() + "."
+ p.getLastName().toLowerCase() + "@vaadin.com");
p.setPhoneNumber("+358 02 555 " + r.nextInt(10) + r.nextInt(10)
+ r.nextInt(10) + r.nextInt(10));
int n = r.nextInt(100000);
if (n < 10000) {
n += 10000;
}
p.setPostalCode(n);
p.setStreetAddress(streets[r.nextInt(streets.length)]
);
c.addItem(p);
}
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return c;
}
}
File 4:
SearchFiler.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.data;
import java.io.Serializable;
@SuppressWarnings("serial")
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();
}
}
File 5:
HelpWindow.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.ui;
import com.vaadin.ui.Label;
import com.vaadin.ui.Window;
@SuppressWarnings("serial")
public class HelpWindow extends Window {
private static final String HELP_HTML_SNIPPET = "This is "
+ "an application built during <strong><a href=\""
+ "http://dev.vaadin.com/\">Vaadin</a></strong> "
+ "tutorial. Hopefully it doesn't need any real help.";
public HelpWindow() {
setCaption("Address Book help");
addComponent(new Label(HELP_HTML_SNIPPET, Label.CONTENT_XHTML));
}
}
File 6:
ListView.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.ui;
import com.vaadin.ui.SplitPanel;
@SuppressWarnings("serial")
public class ListView extends SplitPanel {
public ListView(PersonList personList, PersonForm personForm) {
addStyleName("view");
setFirstComponent(personList);
setSecondComponent(personForm);
setSplitPosition(40);
}
}
File 7:
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;
@SuppressWarnings("serial")
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);
setChildrenAllowed(SHOW_ALL, false);
/*
* 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 8:
PersonForm.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.ui;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanItem;
import com.vaadin.data.validator.EmailValidator;
import com.vaadin.data.validator.RegexpValidator;
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.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.TextField;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
@SuppressWarnings("serial")
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 final ComboBox cities = new ComboBox("City");
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);
/* Allow the user to enter new cities */
cities.setNewItemsAllowed(true);
/* We do not want to use null values */
cities.setNullSelectionAllowed(false);
/* Add an empty city used for selecting no city */
cities.addItem("");
/* Populate cities select using the cities in the data container */
PersonContainer ds = app.getDataSource();
for (Iterator<Person> it = ds.getItemIds().iterator(); it.hasNext();) {
String city = (it.next()).getCity();
cities.addItem(city);
}
/*
* Field factory for overriding how the component for city selection is
* created
*/
setFormFieldFactory(new DefaultFieldFactory() {
@Override
public Field createField(Item item, Object propertyId,
Component uiContext) {
if (propertyId.equals("city")) {
cities.setWidth("200px");
return cities;
}
Field field = super.createField(item, propertyId, uiContext);
if (propertyId.equals("postalCode")) {
TextField tf = (TextField) field;
/*
* We do not want to display "null" to the user when the
* field is empty
*/
tf.setNullRepresentation("");
/* Add a validator for postalCode and make it required */
tf
.addValidator(new RegexpValidator("[1-9]
[0-9]
{4}",
"Postal code must be a five digit number and cannot start with a zero."));
tf.setRequired(true);
} else if (propertyId.equals("email")) {
/* Add a validator for email and make it required */
field.addValidator(new EmailValidator(
"Email must contain '@' and have full domain."));
field.setRequired(true);
}
field.setWidth("200px");
return field;
}
});
}
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 9:
PersonList.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.ui;
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.terminal.ExternalResource;
import com.vaadin.ui.Component;
import com.vaadin.ui.Link;
import com.vaadin.ui.Table;
@SuppressWarnings("serial")
public class PersonList extends Table {
public PersonList(AddressBookApplication app) {
setSizeFull();
setContainerDataSource(app.getDataSource());
setVisibleColumns(PersonContainer.NATURAL_COL_ORDER);
setColumnHeaders(PersonContainer.COL_HEADERS_ENGLISH);
setColumnCollapsingAllowed(true);
setColumnReorderingAllowed(true);
/*
* 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);
// customize email column to have mailto: links using column generator
addGeneratedColumn("email", new ColumnGenerator() {
public Component generateCell(Table source, Object itemId,
Object columnId) {
Person p = (Person) itemId;
Link l = new Link();
l.setResource(new ExternalResource("mailto:" + p.getEmail()));
l.setCaption(p.getEmail());
return l;
}
});
}
}
File 10:
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;
import com.vaadin.ui.Window.Notification;
@SuppressWarnings("serial")
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;
addStyleName("view");
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[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);
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();
if (searchTerm == null || searchTerm.equals("")) {
getWindow().showNotification("Search term cannot be empty!",
Notification.TYPE_WARNING_MESSAGE);
return;
}
SearchFilter searchFilter = new SearchFilter(fieldToSearch.getValue(),
searchTerm, (String) searchName.getValue());
if (saveSearch.booleanValue()) {
if (searchName.getValue() == null
|| searchName.getValue().equals("")) {
getWindow().showNotification(
"Please enter a name for your search!",
Notification.TYPE_WARNING_MESSAGE);
return;
}
app.saveSearch(searchFilter);
}
app.search(searchFilter);
}
}
File 11:
SharingOptions.java
////////////////////////////////////////////////////////////////////////////////////////\
package com.vaadin.demo.tutorial.addressbook.ui;
import com.vaadin.ui.Button;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.Label;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
@SuppressWarnings("serial")
public class SharingOptions extends Window {
public SharingOptions() {
/*
* Make the window modal, which will disable all other components while
* it is visible
*/
setModal(true);
/* Make the sub window 50% the size of the browser window */
setWidth("50%");
/*
* Center the window both horizontally and vertically in the browser
* window
*/
center();
setCaption("Sharing options");
addComponent(new Label(
"With these setting you can modify contact sharing "
+ "options. (non-functional, example of modal dialog)"));
addComponent(new CheckBox("Gmail"));
addComponent(new CheckBox(".Mac"));
Button close = new Button("OK");
close.addListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
SharingOptions.this.close();
}
});
addComponent(close);
}
}
File 12:
Styles.css
////////////////////////////////////////////////////////////////////////////////////////\
@import url(../runo/styles.css);
/* Using the old default theme (runo) as the basis for now */
/* Add some padding to the tree */
.v-tree {
padding-top: 8px;
padding-left: 4px;
}
.toolbar .v-button {
display: block;
width: 65px;
height: 55px;
background: transparent;
border: none;
text-align: center;
}
.toolbar .v-button img {
display: block;
margin-left: auto;
margin-right: auto;
margin-bottom: 5px;
}
.toolbar .v-button span {
font-size: x-small;
text-shadow: #fafafa 1px 1px 0;
}
.v-app {
background: #d0e2ec;
font-family: "Lucida Grande", Helvetica, Arial, sans-serif;
color: #222;
}
.toolbar {
background: #ccc url(images/gradient.png) repeat-x bottom left;
}
.v-panel-caption-view {
color: #004b98;
}
.view {
background: white;
}
/* Theme table to look bit lighter */
.v-table-header-wrap {
height: 20px;
border: none;
border-bottom: 1px solid #555;
background: transparent url(images/table-header-bg.png) repeat-x;
}
.v-table-caption-container {
font-size: 11px;
color: #000;
font-weight: bold;
text-shadow: #fff 0 1px 0;
padding-top: 1px;
}
.v-table-body {
border: none;
}
.v-table-row-odd {
background: #f1f5fa;
}
.v-table-row:hover {
background: #fff;
}
.v-table-row-odd:hover {
background: #f1f5fa;
}
.v-table .v-selected {
background: #3d80df;
}
.v-table-cell-content {
padding: 2px 6px 2px 3px;
line-height: normal;
font-size: 85%;
}
[/color]