package org.springframework.richclient.samples.simple.ui; import java.awt.BorderLayout; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.ObjectFactory; import org.springframework.binding.value.ValueModel; import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.richclient.application.PageComponentContext; import org.springframework.richclient.application.event.LifecycleApplicationEvent; import org.springframework.richclient.application.support.AbstractView; import org.springframework.richclient.command.CommandGroup; import org.springframework.richclient.command.support.AbstractActionCommandExecutor; import org.springframework.richclient.command.support.GlobalCommandIds; import org.springframework.richclient.dialog.ConfirmationDialog; import org.springframework.richclient.list.ListSelectionValueModelAdapter; import org.springframework.richclient.list.ListSingleSelectionGuard; import org.springframework.util.Assert; import west.pharmacie.dto.Fournisseur; import west.pharmacie.session.FournisseurSessionAble; import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.FilterList; import ca.odell.glazedlists.GlazedLists; import ca.odell.glazedlists.TextFilterator; import ca.odell.glazedlists.swing.TextComponentMatcherEditor; public class FournisseurView extends AbstractView implements InitializingBean, ApplicationListener { private final Log _logger = LogFactory.getLog(getClass()); /** * The ObjectFactory for creating instances of our fournisseur table. Initialized in the * context. */ private ObjectFactory fournisseurTableFactory; /** The object table holding our fournisseurs. */ private FournisseurTable fournisseurTable; /** The data store holding all our fournisseurs. */ private FournisseurSessionAble fournisseurSession; /** This is the entry field for the name/address filter. */ private JTextField txtFilter = new JTextField(); /** The executor to handle the "properties" command. */ private PropertiesExecutor propertiesExecutor = new PropertiesExecutor(); /** The executor to handle the "delete" command. */ private DeleteExecutor deleteExecutor = new DeleteExecutor(); /** The group Id for the popup menu. */ private static final String POPUP_COMMAND_ID = "fournisseurViewPopupMenu"; /** * Default constructor. */ public FournisseurView() { } /** * This method is called automatically after this bean has had all its properties set * by the bean factory. This happens because this class implements the * {@link InitializingBean} interface. * * @throws Exception */ public void afterPropertiesSet() throws Exception { // Verify that we have been properly configured Assert.state(getFournisseurTableFactory() != null, "fournisseurTableFactory must be set"); } /** * Create the control for this view. This method is called by the platform in order to * obtain the control to add to the surrounding window and page. * * @return component holding this view */ protected JComponent createControl() { prepareTable(); // Start by preparing the main table JPanel view = new JPanel(new BorderLayout()); JScrollPane sp = getComponentFactory().createScrollPane(fournisseurTable.getTable()); // Now the filter controls JPanel filterPanel = new JPanel (new BorderLayout()); JLabel lblFilter = getComponentFactory().createLabel("raisonSocialeFilter.label"); filterPanel.add(lblFilter, BorderLayout.WEST); String tip = getMessage("raisonSocialeFilter.caption"); txtFilter.setToolTipText(tip); filterPanel.add(txtFilter, BorderLayout.CENTER); filterPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); view.add(sp, BorderLayout.CENTER); view.add(filterPanel, BorderLayout.NORTH); return view; } /** * Register the local command executors to be associated with named commands. This is * called by the platform prior to making the view visible. */ protected void registerLocalCommandExecutors( PageComponentContext context ) { context.register(GlobalCommandIds.PROPERTIES, propertiesExecutor); context.register(GlobalCommandIds.DELETE, deleteExecutor); } /** * @return the fournisseurTableFactory */ public ObjectFactory getFournisseurTableFactory() { return fournisseurTableFactory; } public void setFournisseurTableFactory( ObjectFactory fournisseurTableFactory ) { this.fournisseurTableFactory = fournisseurTableFactory; } /** * Prepare the table holding all the Contact objects. This table provides pretty much * all the functional operations within this view. Prior to calling this method the * {@link #setContactTable(FournisseurTable)} will have already been called as part of the * context bean creation. */ private void prepareTable() { // Get the table instance from our factory try { fournisseurTable = (FournisseurTable) getFournisseurTableFactory().getObject(); } catch( Exception e ) { _logger.error("Failed to generate new fournisseurTable", e); throw new RuntimeException("Failed to generate new fournisseurTable", e); } // Make a double click invoke the properties dialog and plugin the // context menu fournisseurTable.setDoubleClickHandler(propertiesExecutor); // Get the popup menu definition from the command manager (as defined in // the commands-context.xml file). CommandGroup popup = getWindowCommandManager().getCommandGroup(POPUP_COMMAND_ID); fournisseurTable.setPopupCommandGroup(popup); EventList baseList = fournisseurTable.getBaseEventList(); TextFilterator filterator = GlazedLists.textFilterator(new String[] {"raisonSociale"}); FilterList filterList = new FilterList(baseList, new TextComponentMatcherEditor(txtFilter, filterator)); // Install the fully constructed (layered) list into the table fournisseurTable.setFinalEventList(filterList); // Register to get notified when the filtered list changes fournisseurTable.setStatusBar(getStatusBar()); ValueModel selectionHolder = new ListSelectionValueModelAdapter(fournisseurTable.getSelectionModel()); new ListSingleSelectionGuard(selectionHolder, deleteExecutor); new ListSingleSelectionGuard(selectionHolder, propertiesExecutor); } /** * Handle an application event. This will notify us of object adds, deletes, and * modifications. Our object table takes care of updating itself, so we don't have * anything to do. * * @param e event to process */ public void onApplicationEvent( ApplicationEvent e ) { if( _logger.isInfoEnabled() ) { _logger.info("Got event: " + e); } } /** * Private inner class to handle the properties form display. */ private class PropertiesExecutor extends AbstractActionCommandExecutor { /** * Execute this command. */ public void execute() { Fournisseur fournisseur = fournisseurTable.getSelectedFournisseur()[0]; // Get the dialog from the application context since it is a managed bean FournisseurPropertiesDialog dlg = (FournisseurPropertiesDialog) getApplicationContext().getBean( "fournisseurPropertiesDialog"); // Tell it what object to edit and execute the command dlg.setFournisseur(fournisseur); dlg.execute(); } } /** * Private class to handle the delete command. Note that due to the configuration * above, this executor is only enabled when exactly one fournisseur is selected in the * table. Thus, we don't have to protect against being executed with an incorrect * state. */ private class DeleteExecutor extends AbstractActionCommandExecutor { /** * Execute this command. */ public void execute() { // We know exactly one fournisseur will be selected at this time because // of the guards put in place in prepareTable. final Fournisseur fournisseur = fournisseurTable.getSelectedFournisseur()[0]; // Query the user to be sure they want to do this String title = getMessage("fournisseur.confirmDelete.title"); String message = getMessage("fournisseur.confirmDelete.message"); ConfirmationDialog dlg = new ConfirmationDialog(title, message) { protected void onConfirm() { // Delete the object from the persistent store. fournisseurSession.deleteFournisseur(fournisseur); // And notify the rest of the application of the change getApplicationContext().publishEvent( new LifecycleApplicationEvent(LifecycleApplicationEvent.DELETED, fournisseur)); } }; dlg.showDialog(); } } /** * @return the fournisseurSession */ public FournisseurSessionAble getFournisseurSession() { return fournisseurSession; } /** * @param fournisseurSession the fournisseurSession to set */ public void setFournisseurSession(FournisseurSessionAble fournisseurSession) { this.fournisseurSession = fournisseurSession; } }