se.streamsource.streamflow.client.ui.workspace.cases.contacts.ContactView.java Source code

Java tutorial

Introduction

Here is the source code for se.streamsource.streamflow.client.ui.workspace.cases.contacts.ContactView.java

Source

/**
 *
 * Copyright 2009-2014 Jayway Products AB
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package se.streamsource.streamflow.client.ui.workspace.cases.contacts;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.factories.Borders;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import org.jdesktop.application.Action;
import org.jdesktop.application.ApplicationContext;
import org.jdesktop.swingx.util.WindowUtils;
import org.qi4j.api.injection.scope.Service;
import org.qi4j.api.injection.scope.Structure;
import org.qi4j.api.property.Property;
import org.qi4j.api.structure.Module;
import org.qi4j.api.value.ValueBuilder;
import org.restlet.resource.ResourceException;
import se.streamsource.streamflow.api.workspace.cases.contact.ContactAddressDTO;
import se.streamsource.streamflow.api.workspace.cases.contact.ContactDTO;
import se.streamsource.streamflow.api.workspace.cases.contact.ContactEmailDTO;
import se.streamsource.streamflow.api.workspace.cases.contact.ContactPhoneDTO;
import se.streamsource.streamflow.api.workspace.cases.contact.ContactPreference;
import se.streamsource.streamflow.api.workspace.cases.contact.ContactsDTO;
import se.streamsource.streamflow.client.ui.workspace.WorkspaceResources;
import se.streamsource.streamflow.client.ui.workspace.cases.CaseResources;
import se.streamsource.streamflow.client.util.CommandTask;
import se.streamsource.streamflow.client.util.StateBinder;
import se.streamsource.streamflow.client.util.StreamflowButton;
import se.streamsource.streamflow.client.util.ValueBinder;
import se.streamsource.streamflow.client.util.dialog.DialogService;
import se.streamsource.streamflow.client.util.i18n;

import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import static se.streamsource.streamflow.client.util.BindingFormBuilder.Fields.*;

/**
 * JAVADOC
 */
public class ContactView extends JPanel implements Observer {
    @Service
    DialogService dialogs;

    @Structure
    Module module;

    private StateBinder contactBinder;
    private StateBinder phoneNumberBinder;
    private StateBinder emailBinder;
    private StateBinder addressBinder;

    ContactModel model;

    private CardLayout layout = new CardLayout();
    public JPanel form;
    private JTextField defaultFocusField;
    private JTextField addressField;
    private StreetAddressSuggestTextField suggestAddress;
    private JTextField zipField = (JTextField) TEXTFIELD.newField();
    private JTextField cityField = (JTextField) TEXTFIELD.newField();
    private JTextField regionField = (JTextField) TEXTFIELD.newField();
    private JTextField countryField = (JTextField) TEXTFIELD.newField();
    private JTextField phoneField = (JTextField) TEXTFIELD.newField();
    private JTextField emailField = (JTextField) TEXTFIELD.newField();
    private JTextField contactIdField = (JTextField) TEXTFIELD.newField();
    private JTextField companyField = (JTextField) TEXTFIELD.newField();
    private JComboBox contactPreferenceField = (JComboBox) COMBOBOX.newField();
    // do this out of the state binder otherwise the translation is hard
    private JLabel contactPreferenceLabel = new JLabel();

    private ApplicationContext context;
    private JPanel lookupPanel;
    private ValueBinder viewBinder;
    private ValueBinder phoneViewBinder;
    private ValueBinder addressViewBinder;
    private ValueBinder emailViewBinder;

    private StreetAddressSuggestModel suggestModel;

    public ContactView(@Service ApplicationContext appContext, @Structure Module module) {
        setLayout(layout);

        context = appContext;
        setActionMap(context.getActionMap(this));

        add(new JLabel(), "EMPTY");

        DefaultComboBoxModel contactPreferenceModel = new DefaultComboBoxModel();
        for (ContactPreference preference : ContactPreference.values()) {
            contactPreferenceModel.addElement(preference);
        }
        contactPreferenceField.setModel(contactPreferenceModel);
        contactPreferenceField.setSelectedIndex(0);
        contactPreferenceField.setRenderer(new ListCellRenderer() {
            public Component getListCellRendererComponent(JList jList, Object o, int i, boolean b, boolean b1) {
                JLabel comp = new JLabel("null");
                if (o instanceof ContactPreference) {
                    if (((ContactPreference) o) == ContactPreference.none) {
                        comp = new JLabel(" ");
                    } else {
                        comp = new JLabel(i18n.text(WorkspaceResources.valueOf(((ContactPreference) o).name())));
                    }
                }
                comp.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 0));
                return comp;
            }
        });

        viewBinder = module.objectBuilderFactory().newObject(ValueBinder.class);
        phoneViewBinder = module.objectBuilderFactory().newObject(ValueBinder.class);
        addressViewBinder = module.objectBuilderFactory().newObject(ValueBinder.class);
        emailViewBinder = module.objectBuilderFactory().newObject(ValueBinder.class);

        suggestModel = new StreetAddressSuggestModel();
        suggestAddress = new StreetAddressSuggestTextField(suggestModel, cityField, addressViewBinder);
        addressField = suggestAddress.getTextField();

        // Edit panel
        {
            FormLayout formLayout = new FormLayout("right:70dlu, 5dlu, 150dlu:grow",
                    "pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, 5dlu, top:70dlu:grow, pref, pref");
            this.setBorder(Borders.createEmptyBorder("2dlu, 2dlu, 2dlu, 2dlu"));

            form = new JPanel();
            JScrollPane scrollPane = new JScrollPane(form);
            scrollPane.getVerticalScrollBar().setUnitIncrement(30);
            scrollPane.setBorder(BorderFactory.createEmptyBorder());
            DefaultFormBuilder builder = new DefaultFormBuilder(formLayout, form);

            contactBinder = module.objectBuilderFactory().newObject(StateBinder.class);
            contactBinder.setResourceMap(context.getResourceMap(getClass()));
            ContactDTO template = contactBinder.bindingTemplate(ContactDTO.class);

            phoneNumberBinder = module.objectBuilderFactory().newObject(StateBinder.class);
            phoneNumberBinder.setResourceMap(context.getResourceMap(getClass()));
            ContactPhoneDTO phoneTemplate = phoneNumberBinder.bindingTemplate(ContactPhoneDTO.class);

            addressBinder = module.objectBuilderFactory().newObject(StateBinder.class);
            addressBinder.setResourceMap(context.getResourceMap(getClass()));
            ContactAddressDTO addressTemplate = addressBinder.bindingTemplate(ContactAddressDTO.class);

            emailBinder = module.objectBuilderFactory().newObject(StateBinder.class);
            emailBinder.setResourceMap(context.getResourceMap(getClass()));
            ContactEmailDTO emailTemplate = emailBinder.bindingTemplate(ContactEmailDTO.class);

            builder.add(new StreamflowButton(getActionMap().get("view")));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.name_label));
            builder.nextColumn(2);
            builder.add(contactBinder.bind(defaultFocusField = (JTextField) TEXTFIELD.newField(), template.name()));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.phone_label));
            builder.nextColumn(2);
            builder.add(phoneNumberBinder.bind(phoneField, phoneTemplate.phoneNumber()));
            builder.nextLine();

            builder.add(createLabel(WorkspaceResources.address_label));
            builder.nextColumn(2);
            builder.add(suggestAddress);
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.zip_label));
            builder.nextColumn(2);
            builder.add(addressBinder.bind(zipField, addressTemplate.zipCode()));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.city_label));
            builder.nextColumn(2);
            builder.add(addressBinder.bind(cityField, addressTemplate.city()));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.region_label));
            builder.nextColumn(2);
            builder.add(addressBinder.bind(regionField, addressTemplate.region()));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.country_label));
            builder.nextColumn(2);
            builder.add(addressBinder.bind(countryField, addressTemplate.country()));
            builder.nextLine();

            builder.add(createLabel(WorkspaceResources.email_label));
            builder.nextColumn(2);
            builder.add(emailBinder.bind(emailField, emailTemplate.emailAddress()));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.contact_id_label));
            builder.nextColumn(2);
            builder.add(contactBinder.bind(contactIdField, template.contactId()));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.company_label));
            builder.nextColumn(2);
            builder.add(contactBinder.bind(companyField, template.company()));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.contact_preference_label));
            builder.nextColumn(2);
            builder.add(contactBinder.bind(contactPreferenceField, template.contactPreference()),
                    new CellConstraints(3, 12, 1, 1, CellConstraints.LEFT, CellConstraints.TOP,
                            new Insets(5, 0, 0, 0)));
            builder.nextLine(2);
            builder.add(createLabel(WorkspaceResources.note_label));
            builder.nextColumn(2);
            builder.add(contactBinder.bind(TEXTAREA.newField(), template.note()));

            builder.nextLine(2);
            builder.nextColumn(2);
            lookupPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
            lookupPanel.add(new StreamflowButton(getActionMap().get("lookupContact")));
            builder.add(lookupPanel);

            contactBinder.addObserver(this);
            phoneNumberBinder.addObserver(this);
            addressBinder.addObserver(this);
            emailBinder.addObserver(this);
            add(scrollPane, "EDIT");
        }

        // View panel
        {
            FormLayout formLayout = new FormLayout("right:70dlu, 5dlu, 150dlu:grow",
                    "pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, pref, 5dlu, top:70dlu:grow, pref, pref");
            this.setBorder(Borders.createEmptyBorder("2dlu, 2dlu, 2dlu, 2dlu"));

            form = new JPanel();
            JScrollPane scrollPane = new JScrollPane(form);
            scrollPane.getVerticalScrollBar().setUnitIncrement(30);
            scrollPane.setBorder(BorderFactory.createEmptyBorder());
            DefaultFormBuilder builder = new DefaultFormBuilder(formLayout, form);

            builder.add(new StreamflowButton(getActionMap().get("edit")));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.name_label));
            builder.nextColumn(2);
            builder.add(viewBinder.bind("name", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.phone_label));
            builder.nextColumn(2);
            builder.add(phoneViewBinder.bind("phoneNumber", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();

            builder.add(createLabel(WorkspaceResources.address_label));
            builder.nextColumn(2);
            builder.add(addressViewBinder.bind("address", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.zip_label));
            builder.nextColumn(2);
            builder.add(addressViewBinder.bind("zipCode", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.city_label));
            builder.nextColumn(2);
            builder.add(addressViewBinder.bind("city", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.region_label));
            builder.nextColumn(2);
            builder.add(addressViewBinder.bind("region", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.country_label));
            builder.nextColumn(2);
            builder.add(addressViewBinder.bind("country", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();

            builder.add(createLabel(WorkspaceResources.email_label));
            builder.nextColumn(2);
            builder.add(emailViewBinder.bind("emailAddress", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.contact_id_label));
            builder.nextColumn(2);
            builder.add(viewBinder.bind("contactId", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.company_label));
            builder.nextColumn(2);
            builder.add(viewBinder.bind("company", visibleIfNotEmpty(new JLabel("!"))));
            builder.nextLine();
            builder.add(createLabel(WorkspaceResources.contact_preference_label));
            builder.nextColumn(2);
            builder.add(contactPreferenceLabel);

            builder.nextLine(2);
            builder.add(createLabel(WorkspaceResources.note_label));
            builder.nextColumn(2);
            builder.add(viewBinder.bind("note", visibleIfNotEmpty(new JLabel("!"))));

            add(scrollPane, "VIEW");
        }
    }

    private JLabel createLabel(Enum key) {
        JLabel label = new JLabel(i18n.text(key));
        label.setForeground(Color.gray);
        return label;
    }

    public void setModel(ContactModel model) {
        this.model = model;
        if (model != null) {
            updateFromModel(model);

            javax.swing.Action action = getActionMap().get("lookupContact");
            action.setEnabled(model.isContactLookupEnabled());
            lookupPanel.setVisible(action.isEnabled());

            // TODO do a better way of checking if the contact is empty
            if (model.getContact().toJSON().equals(
                    "{\"addresses\":[{\"address\":\"\",\"city\":\"\",\"contactType\":\"HOME\",\"country\":\"\",\"region\":\"\",\"zipCode\":\"\"}],\"company\":\"\",\"contactId\":\"\",\"contactPreference\":\"none\",\"emailAddresses\":[{\"contactType\":\"HOME\",\"emailAddress\":\"\"}],\"isCompany\":false,\"name\":\"\",\"note\":\"\",\"phoneNumbers\":[{\"contactType\":\"HOME\",\"phoneNumber\":\"\"}],\"picture\":\"\"}")) {
                layout.show(this, "EDIT");
            } else {
                layout.show(this, "VIEW");
            }

        } else {
            layout.show(this, "EMPTY");
        }
    }

    public void updateFromModel(ContactModel model) {
        handleContactPreference();

        suggestModel.setContactModel(model);
        contactBinder.updateWith(model.getContact());
        phoneNumberBinder.updateWith(model.getPhoneNumber());
        addressBinder.updateWith(model.getAddress());
        suggestAddress.getTextField()
                .setText(model.getAddress().address() != null ? model.getAddress().address().get() : "");
        emailBinder.updateWith(model.getEmailAddress());

        viewBinder.update(model.getContact());
        phoneViewBinder.update(model.getPhoneNumber());
        addressViewBinder.update(model.getAddress());
        emailViewBinder.update(model.getEmailAddress());
    }

    public void update(Observable observable, Object arg) {
        final Property property = (Property) arg;
        new CommandTask() {
            @Override
            public void command() throws Exception {
                String propertyName = property.qualifiedName().name();
                if (propertyName.equals("name")) {
                    model.changeName((String) property.get());
                } else if (propertyName.equals("note")) {
                    model.changeNote((String) property.get());
                } else if (propertyName.equals("company")) {
                    model.changeCompany((String) property.get());
                } else if (propertyName.equals("phoneNumber")) {
                    model.changePhoneNumber((String) property.get());
                } else if (propertyName.equals("address")) {
                    model.changeAddress((String) property.get());
                } else if (propertyName.equals("zipCode")) {
                    model.changeZipCode((String) property.get());
                } else if (propertyName.equals("city")) {
                    model.changeCity((String) property.get());
                } else if (propertyName.equals("region")) {
                    model.changeRegion((String) property.get());
                } else if (propertyName.equals("country")) {
                    model.changeCountry((String) property.get());
                } else if (propertyName.equals("emailAddress")) {
                    model.changeEmailAddress((String) property.get());
                } else if (propertyName.equals("contactId")) {
                    model.changeContactId((String) property.get());
                } else if (propertyName.equals("contactPreference")) {
                    if (property.get() instanceof ContactPreference) {
                        model.changeContactPreference((ContactPreference) property.get());
                    } else {
                        model.changeContactPreference(null);
                    }
                }
            }
        }.execute();
    }

    @Action
    public void edit() {
        layout.show(this, "EDIT");
    }

    @Action
    public void view() {
        setModel(model);
        layout.show(this, "VIEW");
    }

    @Action
    public void lookupContact() {
        try {
            ContactDTO query = createContactQuery();

            ContactDTO emptyCriteria = module.valueBuilderFactory().newValueBuilder(ContactDTO.class).newInstance();
            if (emptyCriteria.equals(query)) {
                String msg = i18n.text(CaseResources.could_not_find_search_criteria);
                dialogs.showMessageDialog(this, msg, "Info");

            } else {

                ContactsDTO contacts = model.searchContacts(query);

                if (contacts.contacts().get().isEmpty()) {
                    String msg = i18n.text(CaseResources.could_not_find_contacts);
                    dialogs.showMessageDialog(this, msg, "Info");
                } else {

                    ContactLookupResultDialog dialog = module.objectBuilderFactory()
                            .newObjectBuilder(ContactLookupResultDialog.class).use(contacts.contacts().get())
                            .newInstance();
                    dialogs.showOkCancelHelpDialog(WindowUtils.findWindow(this), dialog,
                            i18n.text(WorkspaceResources.contacts_tab));

                    ContactDTO contactValue = dialog.getSelectedContact();

                    if (contactValue != null) {
                        if (defaultFocusField.getText().equals("") && !contactValue.name().get().equals("")) {
                            model.changeName(contactValue.name().get());
                            defaultFocusField.setText(contactValue.name().get());
                        }

                        for (ContactPhoneDTO contactPhoneDTO : contactValue.phoneNumbers().get()) {
                            if (!contactPhoneDTO.phoneNumber().get().equals("")
                                    && model.getPhoneNumber().phoneNumber().get().equals("")) {
                                model.changePhoneNumber(contactPhoneDTO.phoneNumber().get());
                                phoneField.setText(contactPhoneDTO.phoneNumber().get());
                            }
                        }

                        List<ContactAddressDTO> addressDTOs = contactValue.addresses().get();
                        for (ContactAddressDTO addressDTO : addressDTOs) {
                            if (!addressDTO.address().get().equals("")
                                    && model.getAddress().address().get().equals("")) {
                                model.changeAddress(addressDTO.address().get());
                                addressField.setText(addressDTO.address().get());
                            }
                        }

                        List<ContactEmailDTO> emailDTOs = contactValue.emailAddresses().get();
                        for (ContactEmailDTO emailDTO : emailDTOs) {
                            if (!emailDTO.emailAddress().get().equals("")
                                    && model.getEmailAddress().emailAddress().get().equals("")) {
                                model.changeEmailAddress(emailDTO.emailAddress().get());
                                emailField.setText(emailDTO.emailAddress().get());
                            }
                        }

                        if (contactIdField.getText().equals("") && !contactValue.contactId().get().equals("")) {
                            model.changeContactId(contactValue.contactId().get());
                            contactIdField.setText(contactValue.contactId().get());
                        }

                        if (companyField.getText().equals("") && !contactValue.company().get().equals("")) {
                            model.changeCompany(contactValue.company().get());
                            companyField.setText(contactValue.company().get());
                        }
                    }
                }
            }

        } catch (ResourceException e) {
            e.printStackTrace();
        }
    }

    private ContactDTO createContactQuery() {
        ValueBuilder<ContactDTO> contactBuilder = module.valueBuilderFactory().newValueBuilder(ContactDTO.class);

        if (!defaultFocusField.getText().isEmpty()) {
            contactBuilder.prototype().name().set(defaultFocusField.getText());
        }

        if (!phoneField.getText().isEmpty()) {
            ValueBuilder<ContactPhoneDTO> builder = module.valueBuilderFactory()
                    .newValueBuilder(ContactPhoneDTO.class);
            builder.prototype().phoneNumber().set(phoneField.getText());
            contactBuilder.prototype().phoneNumbers().get().add(builder.newInstance());
        }

        if (!addressField.getText().isEmpty()) {
            ValueBuilder<ContactAddressDTO> builder = module.valueBuilderFactory()
                    .newValueBuilder(ContactAddressDTO.class);
            builder.prototype().address().set(addressField.getText());
            contactBuilder.prototype().addresses().get().add(builder.newInstance());
        }

        if (!emailField.getText().isEmpty()) {
            ValueBuilder<ContactEmailDTO> builder = module.valueBuilderFactory()
                    .newValueBuilder(ContactEmailDTO.class);
            builder.prototype().emailAddress().set(emailField.getText());
            contactBuilder.prototype().emailAddresses().get().add(builder.newInstance());
        }

        if (!contactIdField.getText().isEmpty()) {
            contactBuilder.prototype().contactId().set(contactIdField.getText());
        }

        if (!companyField.getText().isEmpty()) {
            contactBuilder.prototype().contactId().set(contactIdField.getText());
        }
        return contactBuilder.newInstance();
    }

    private void handleContactPreference() {
        ContactPreference val = model.getContact().contactPreference().get();
        if (val == null) {
            model.getContact().contactPreference().set(ContactPreference.none);
            val = model.getContact().contactPreference().get();
        }
        if (val == ContactPreference.none) {
            contactPreferenceLabel.setVisible(false);
        } else {
            contactPreferenceLabel.setVisible(true);
            contactPreferenceLabel.setText(i18n.text(WorkspaceResources.valueOf(val.name())));
        }
        alignSibling(contactPreferenceLabel);
    }

    private JLabel visibleIfNotEmpty(final JLabel label) {
        label.addPropertyChangeListener("text", new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                label.setVisible(!evt.getNewValue().equals(""));
                alignSibling(label);
            }
        });
        return label;
    }

    private void alignSibling(JLabel label) {
        Container container = label.getParent();
        for (int i = 0; i < container.getComponents().length; i++) {
            Component component = container.getComponents()[i];
            if (component == label) {
                JLabel labelForLabel = (JLabel) container.getComponent(i - 1);
                labelForLabel.setVisible(label.isVisible());
            }
        }
    }

    public void setFocusOnName() {
        defaultFocusField.requestFocusInWindow();
    }
}