Friday, March 11, 2016

Spring Rich Client

I couldn't find a start-to-finish Spring Rich Client tut. So I created this. I may have borrowed the source code from some other blog. I had trouble with messages.properties. Make sure to provide it in the appropriate package as opposed to default classpath If it didn't work, try creating a folder under src called resources and place the file in that folder. But this didn't work for me, so be aware.
Spring Rich Client

Create Eclipse Project UsrMgmtSpring

Default package has UserMgmApp.java
Com.test.dataprovider has

CustomerDataStore.java
Message.properties

Com.test.editor has
CustomerTable.java

Com.test.form has
CustomerForm.java

Com.test.model has
Address.java
Customer.java
CustomerPropertiesDialog.java

Com.test.views has
CustomerView.java
Folder ctx has
Appbundle.xml
Commands.xml
Dzone-beans.xml

Make sure you have the latest Spring jars

Source Code

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.richclient.application.ApplicationLauncher;

public class UserMgmApp{

 private static final Log logger = LogFactory.getLog(UserMgmApp.class);

 public static void main(String[] args) {

  String rootDirectoryForContext = "/ctx";
  String contextPath = rootDirectoryForContext + "/appbundle.xml";

  try {
   new ApplicationLauncher(null, new String[] {contextPath});
  }
  catch (RuntimeException e) {
   logger.error("RuntimeException during startup", e);
  }
 }
}



package com.test.dataprovider;

import java.util.HashSet;

import com.test.model.Address;
import com.test.model.Customer;

public class CustomerDataStore {

    private static int nextId = 1;

    private HashSet customers = new HashSet();

    public CustomerDataStore() {
        loadData();
    }

    public Customer[] getAllCustomers() {
        return (Customer[]) customers.toArray(new Customer[0]);
    }

    private void loadData() {
        customers.add(makeCustomer(
                "Larry", "Streepy", true, "123 Some St.", "New York", "NY", "10010"));
        customers.add(makeCustomer(
                "Keith", "Donald", false, "456 WebFlow Rd.", "Cooltown", "NY", "10001"));
        customers.add(makeCustomer(
                "Steve", "Brothers", true, "10921 The Other Street", "Denver", "CO", "81234-2121"));
        customers.add(makeCustomer(
                "Carlos", "Mencia", false, "4321 Comedy Central", "Hollywood", "CA", "91020"));
        customers.add(makeCustomer(
                "Jim", "Jones", true, "1001 Another Place", "Dallas", "TX", "71212"));
        customers.add(makeCustomer(
                "Jenny", "Jones", false, "1001 Another Place", "Dallas", "TX", "75201"));
        customers.add(makeCustomer(
                "Greg", "Jones", false, "9 Some Other Place", "Chicago", "IL", "60601"));
    }

    private Customer makeCustomer(
            String first, String last, boolean married, String street, 
            String city, String state, String zip) {

        Customer customer = new Customer();
        customer.setId(nextId++);
        customer.setFirstName(first);
        customer.setLastName(last);
        customer.setLastName(last);
        customer.setMarried(married);

        Address address = customer.getAddress();
        address.setStreet(street);
        address.setCity(city);
        address.setState(state);
        address.setZip(zip);

        return customer;

    }
}



Message.properties

#Menu
userManagementMenu.label = User Management
userManagementMenu.caption = User Management
#Menu

#MenuItems
userCommand.label = Users
userGroupCommand.label = User Groups
#MenuItems

#The above definitions go into a property file. Note that userManagementMenu, userCommand, userGroupCommandLabel are the bean identifiers we have defined in commands.xml file. Have a look at the following declaration,

#User
userDataEditor.id.header = Id
userDataEditor.name.header = Name
userDataEditor.dateOfBirth.header = Date of Birth
userDataEditor.userGroup.header = User Group

userDataEditor.title = Users
userDataEditor.description = List of users

userView.title = Users
userView.label = Users

userForm.id.label = Id
userForm.name.label = Name
userForm.dateOfBirth.label = Date of Birth
userForm.userGroup.label = User Group

userFilterForm.nameContains.label = Name contains
#User
#UserGroup
userGroupDataEditor.id.header = Id
userGroupDataEditor.name.header = Name
userGroupDataEditor.description.header = Description

userGroupDataEditor.title = User Groups
userGroupDataEditor.description = List of User groups

userGroupView.title = User Groups
userGroupView.label = User Groups

userGroupForm.id.label = Id
userGroupForm.name.label = Name
userGroupForm.description.label = Description

userGroupFilterForm.nameContains.label = Name contains
#UserGroup

userCommand.label=User
userGroupCommand.label=User Group


firstName.label=First Name
lastName.label=Last Name
address.street.label=Street
address.city.label=City
address.state.label=State
address.zip.label=Zip

customerProperties.edit.title=Edit Contact: {0} {1}

customer.title=Customer Information
customer.description=Enter the details of the customer below.


married.label=Married?



package com.test.editor;

import javax.swing.JTable;
import javax.swing.table.TableColumnModel;

import org.springframework.richclient.table.support.AbstractObjectTable;

import com.test.dataprovider.CustomerDataStore;
import com.test.model.Customer;

public class CustomerTable extends AbstractObjectTable {

    private CustomerDataStore dataStore;

    public CustomerTable(CustomerDataStore dataStore) {
        super("customers", new String[]{
            "lastName", 
            "firstName", 
            "address.street", 
            "address.city", 
            "address.state", 
            "address.zip"});
        this.dataStore = dataStore;
    }

    @Override
    protected void configureTable(JTable table) {
        TableColumnModel tcm = table.getColumnModel();
        tcm.getColumn(0).setPreferredWidth(100);
        tcm.getColumn(1).setPreferredWidth(100);
        tcm.getColumn(2).setPreferredWidth(200);
        tcm.getColumn(3).setPreferredWidth(50);
        tcm.getColumn(4).setPreferredWidth(10);
        tcm.getColumn(5).setPreferredWidth(50);
    }

    @Override
    protected Object[] getDefaultInitialData() {
        return dataStore.getAllCustomers();
    }

    public Customer[] getSelectedCustomers() {
        int[] selected = getTable().getSelectedRows();
        Customer[] customer = new Customer[selected.length];
        for (int i = 0; i < selected.length; i++) {
            customer[i] = (Customer) getTableModel().getElementAt(selected[i]);
        }
        return customer;
    }

    public Customer getSelectedCustomer() {
        return (Customer) getSelectedCustomers()[0];
    }
}




package com.test.form;

import javax.swing.JComponent;
import javax.swing.JTextField;

import org.springframework.richclient.form.AbstractForm;
import org.springframework.richclient.form.builder.TableFormBuilder;

import com.test.model.Customer;

public class CustomerForm extends AbstractForm {

    private JComponent firstNameField;

    public CustomerForm(Customer customer) {
        super(customer);
        setId("customer");
    }

    @Override
    protected JComponent createFormControl() {
        TableFormBuilder formBuilder = new TableFormBuilder(getBindingFactory());
        formBuilder.setLabelAttributes("colGrId=label colSpec=right:pref");
        formBuilder.addSeparator("General");
        formBuilder.row();
        firstNameField = formBuilder.add("firstName")[1];
        formBuilder.add("lastName");
        formBuilder.row();
        formBuilder.add("married");
        formBuilder.row();
        formBuilder.addSeparator("Address");
        formBuilder.row();
        formBuilder.add("address.street");
        formBuilder.row();
        formBuilder.add("address.city", "colSpan=1 align=left");
        formBuilder.row();
        formBuilder.add("address.state", "colSpan=1 align=left");
        formBuilder.row();

        JComponent zipField = formBuilder.add("address.zip", "colSpan=1 align=left")[1];
        ((JTextField) zipField).setColumns(8);
        formBuilder.row();

        return formBuilder.getForm();
    }

    public boolean requestFocusInWindow() {
        return firstNameField.requestFocusInWindow();
    }
    
}



package com.test.model;

public class Address {

    private String street;
    private String city;
    private String state;
    private String zip;

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }
    
}



package com.test.model;

import java.util.Date;

 public class Customer {

  private int id;
     private String firstName;
     private String lastName;
     private Address address;
     private boolean married;

     public boolean getMarried() {
         return married;
     }

     public void setMarried(boolean married) {
         this.married = married;
     }
     public Customer() {
         setAddress(new Address());
     }

     public int getId() {
         return id;
     }

     public void setId(int id) {
         this.id = id;
     }

     public Address getAddress() {
         return address;
     }

     public void setAddress(Address address) {
         this.address = address;
     }

     public String getFirstName() {
         return firstName;
     }

     public void setFirstName(String firstName) {
         this.firstName = firstName;
     }

     public String getLastName() {
         return lastName;
     }

     public void setLastName(String lastName) {
         this.lastName = lastName;
     }
}




package com.test.model;

import org.springframework.richclient.dialog.FormBackedDialogPage;
import org.springframework.richclient.dialog.TitledPageApplicationDialog;
import org.springframework.richclient.form.Form;

import com.test.form.CustomerForm;

public class CustomerPropertiesDialog extends TitledPageApplicationDialog {

    private Form form;

    public CustomerPropertiesDialog(Customer Customer) {
        form = new CustomerForm(Customer);
        setDialogPage(new FormBackedDialogPage(form));
    }

    @Override
    protected void onAboutToShow() {
        Customer Customer = (Customer) form.getFormModel().getFormObject();
        String title = 
                getMessage(
                "customerProperties.edit.title", 
                new Object[]{
                    Customer.getFirstName(),
                    Customer.getLastName()
                });
        setTitle(title);
    }

    @Override
    protected boolean onFinish() {
        form.getFormModel().commit();
        return true;
    }

    @Override
    protected void onCancel() {
        super.onCancel();
    }
    
}




package com.test.views;

import java.awt.BorderLayout;

import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import org.springframework.binding.value.ValueModel;
import org.springframework.richclient.application.PageComponentContext;
import org.springframework.richclient.application.support.AbstractView;
import org.springframework.richclient.command.ActionCommand;
import org.springframework.richclient.command.CommandGroup;
import org.springframework.richclient.command.GuardedActionCommandExecutor;
import org.springframework.richclient.command.support.AbstractActionCommandExecutor;
import org.springframework.richclient.command.support.GlobalCommandIds;
import org.springframework.richclient.list.ListSelectionValueModelAdapter;
import org.springframework.richclient.list.ListSingleSelectionGuard;

import com.test.dataprovider.CustomerDataStore;
import com.test.editor.CustomerTable;
import com.test.model.CustomerPropertiesDialog;

public class CustomerView extends AbstractView {

    private CustomerTable customerTable;
    private CustomerDataStore customerDataStore;

    private GuardedActionCommandExecutor propertiesExecutor = new PropertiesExecutor();

    protected CustomerDataStore getCustomerDataStore() {
        return customerDataStore;
    }

    public void setCustomerDataStore(CustomerDataStore customerDataStore) {
        this.customerDataStore = customerDataStore;
    }

    @Override
    protected void registerLocalCommandExecutors(PageComponentContext context) {
        context.register(GlobalCommandIds.PROPERTIES, propertiesExecutor);
    }

    @Override
    protected JComponent createControl() {
        
        customerTable = new customerTableFactory().createCustomerTable();
        customerTable.setDoubleClickHandler(propertiesExecutor);
        JPanel view = new JPanel(new BorderLayout());
        JScrollPane sp = getComponentFactory().createScrollPane(customerTable.getControl());
        view.add(sp, BorderLayout.CENTER);
        return view;
        
    }

    private class customerTableFactory {

        public CustomerTable createCustomerTable() {

            CustomerTable customerTable = new CustomerTable(customerDataStore);

            CommandGroup popup = new CommandGroup();
            popup.add((ActionCommand) getWindowCommandManager().getCommand(GlobalCommandIds.PROPERTIES, ActionCommand.class));
            customerTable.setPopupCommandGroup(popup);

            ValueModel selectionHolder = new ListSelectionValueModelAdapter(customerTable.getSelectionModel());
            new ListSingleSelectionGuard(selectionHolder, propertiesExecutor);

            return customerTable;
            
        }
        
    }
    
    private class PropertiesExecutor extends AbstractActionCommandExecutor {

        @Override
        public void execute() {
            new CustomerPropertiesDialog(customerTable.getSelectedCustomer()).showDialog();
        }

    }

}


Appbundle.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 <bean id="application" class="org.springframework.richclient.application.Application">
 <constructor-arg index="0" ref="applicationDescriptor" />
 <constructor-arg index="1" ref="lifecycleAdvisor" />
 </bean>
 <bean id="lifecycleAdvisor"
 class="org.springframework.richclient.samples.simple.app.SimpleLifecycleAdvisor">
 <property name="windowCommandBarDefinitions"
 value="ctx/commands.xml" />
 <property name="startingPageId" value="customerView" />
 <property name="windowCommandManagerBeanName" value="windowCommandManager" />
 <property name="menubarBeanName" value="menuBar" />
 <property name="toolbarBeanName" value="toolBar" />
 </bean>
 <bean id="initialView"
 class="org.springframework.richclient.application.support.DefaultViewDescriptor">
 <property name="viewClass" value="org.springframework.richclient.samples.simple.ui.InitialView" />
 <property name="viewProperties">
 <map>
 <entry key="firstMessage" value="firstMessage.text" />
 <entry key="descriptionTextPath"
 value="org/springframework/richclient/samples/simple/ui/initialViewText.html" />
 </map>
 </property>
 </bean>
 <bean id="serviceLocator"
 class="org.springframework.richclient.application.ApplicationServicesLocator">
 <property name="applicationServices" ref="applicationServices" />
 </bean>
 <bean id="applicationServices"
 class="org.springframework.richclient.application.support.DefaultApplicationServices" />
 <bean id="applicationEventMulticaster"
 class="org.springframework.context.event.SimpleApplicationEventMulticaster" />
 <bean id="applicationDescriptor"
 class="org.springframework.richclient.application.support.DefaultApplicationDescriptor">
 <property name="version" value="1.0" />
 </bean>
 <bean id="applicationObjectConfigurer" depends-on="serviceLocator"
 class="org.springframework.richclient.application.config.DefaultApplicationObjectConfigurer">
 </bean>
 <bean id="lookAndFeelConfigurer"
 class="org.springframework.richclient.application.config.JGoodiesLooksConfigurer">
 <property name="popupDropShadowEnabled" value="false" />
 <property name="theme">
 <bean class="com.jgoodies.looks.plastic.theme.ExperienceBlue" />
 </property>
 </bean>
 <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
 <property name="basenames">
 <list>
 <value>org.springframework.richclient.samples.simple.ui.messages</value>
 <value>org.springframework.richclient.application.messages</value>
  <value>com.test.dataprovider.messages</value>
 </list>
 </property>
 </bean>
 <bean id="imageResourcesFactory" class="org.springframework.context.support.ResourceMapFactoryBean">
 <property name="locations">
 <list>
 <value>classpath:org/springframework/richclient/image/images.properties</value>
 <value>classpath:org/springframework/richclient/samples/simple/ui/images.properties</value>
 </list>
 </property>
 </bean>
 <bean id="imageSource" class="org.springframework.richclient.image.DefaultImageSource">
 <constructor-arg index="0" ref="imageResourcesFactory" />
 <property name="brokenImageIndicator"
 value="/org/springframework/richclient/images/alert/error_obj.gif" />
 </bean>
 <bean id="formComponentInterceptorFactory"
 class="org.springframework.richclient.form.builder.support.ChainedInterceptorFactory">
 <property name="interceptorFactories">
 <list>
 <bean
 class="org.springframework.richclient.form.builder.support.ColorValidationInterceptorFactory">
 <property name="errorColor" value="255,245,245" />
 </bean>
 <bean class="org.springframework.richclient.form.builder.support.OverlayValidationInterceptorFactory" />
 <bean class="org.springframework.richclient.text.TextComponentPopupInterceptorFactory" />
 <bean class="org.springframework.richclient.list.ComboBoxAutoCompletionInterceptorFactory" />
 </list>
 </property>
 </bean>
 <bean id="rulesSource"
 class="org.springframework.richclient.samples.simple.domain.SimpleValidationRulesSource" />
 <bean id="conversionService"
 class="org.springframework.richclient.application.DefaultConversionServiceFactoryBean">
 <property name="formatterFactory">
 <bean class="org.springframework.richclient.samples.simple.ui.SimpleAppFormatterFactory" />
 </property>
 </bean>
 
  
 <import resource="dzone-beans.xml"/>

</beans>




Commands.xml



<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 <bean id="windowCommandManager"
 class="org.springframework.richclient.application.support.ApplicationWindowCommandManager">
 </bean>
 <bean id="menuBar" class="org.springframework.richclient.command.CommandGroupFactoryBean">
 <property name="members">
 <list>
 <ref bean="fileMenu" />
 <ref bean="windowMenu" />
 <ref bean="helpMenu" />
 <ref bean="userManagementMenu" />  
 </list>
 </property>
 </bean>
 
 <bean id="userManagementMenu" class="org.springframework.richclient.command.CommandGroupFactoryBean" >
  <property name="members">
   <list>
     
    <ref bean="userCommand"/>
     
    <ref bean="userGroupCommand"/>
    
   </list>
  </property>
 </bean>

 <bean id="userCommand" class="org.springframework.richclient.command.support.ShowViewCommand">
   <property name="viewDescriptor" ref="customerView"/>
 </bean>
 
 <bean id="fd1" class="org.springframework.richclient.command.config.CommandFaceDescriptor">
  <constructor-arg index="0" value="there"/>
 </bean>
 
 <bean id="userGroupCommand" class="org.springframework.richclient.command.support.ShowViewCommand">
   <property name="viewDescriptor" ref="customerView"/>
 </bean>
 
 <bean id="fd2" class="org.springframework.richclient.command.config.CommandFaceDescriptor">
  <constructor-arg index="0" value="there"/>
 </bean>
  
 <bean id="toolBar" class="org.springframework.richclient.command.CommandGroupFactoryBean">
 <property name="members">
 <list/>
 </property>
 </bean>
 <bean id="fileMenu" class="org.springframework.richclient.command.CommandGroupFactoryBean">
 <property name="members">
 <list>
 <bean class="org.springframework.richclient.command.support.ExitCommand" />
 </list>
 </property>
 </bean>
 <bean id="windowMenu" class="org.springframework.richclient.command.CommandGroupFactoryBean">
 <property name="members">
 <list>
 <bean class="org.springframework.richclient.command.support.NewWindowCommand" />
 <value>separator</value>
 <bean class="org.springframework.richclient.command.support.ShowViewMenu" />
 </list>
 </property>
 </bean>
 <bean id="helpMenu" class="org.springframework.richclient.command.CommandGroupFactoryBean">
 <property name="members">
 <list>
 <ref bean="helpContentsCommand" />
 <value>separator</value>
 <ref bean="aboutCommand" />
 </list>
 </property>
 </bean>
 <bean id="helpContentsCommand" class="org.springframework.richclient.command.support.HelpContentsCommand">
 <property name="helpSetPath" value="help/simple.hs" />
 </bean>
 <bean id="aboutCommand" class="org.springframework.richclient.command.support.AboutCommand" />
</beans>




Dzone-beans.xml

<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
 <bean id="customerView" class="org.springframework.richclient.application.support.DefaultViewDescriptor">
    <property name="viewClass" value="com.test.views.CustomerView" />
    <property name="viewProperties">
        <map>
            <entry key="customerDataStore" value-ref="customerDataStore" />
        </map>
    </property>
</bean>

<bean id="customerDataStore" class="com.test.dataprovider.CustomerDataStore" />
</beans>




No comments:

Post a Comment