Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Newbie - Making simple Login/Authentication for "AddressBook" Tutorial?
Hello Vaadin Lovers! -_-
This is the structure of this threat:
1 - My Goal 2 - Step by Step 3 - QUESTIONS (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
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%;
}