Announcement Announcement Module
Collapse
No announcement yet.
master/detail + hibernate Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • master/detail + hibernate

    Dear All,

    I am just learning sprinch rich. I've managed to do a master detaile form and it's working fine.

    q1. How do I get it to work with hibernate, I have everything set-up but how can I get it to update my records in the db ? How do I catch update events? from the master table.

    q2. Is there anyway to display detail form in another view? I've managed to do something similar by attaching myown TableSelectionListener and firing lifecycleEvent.selected and the catching this LifecycleApplicationEvent in another view. Is there a better way ? If there is, which classes should I declare as spring beans in my context xml file ?

    Many thanks to everybody for help.
    Look forward to your replys.

    Alex.

  • #2
    I orginally used master/details but turned away because I need to hack to much into it so I could call my business layer (which calls hibernate) where I needed to.

    Here's my solution, but it's far from perfect:

    Code:
    /**
     * @author Geoffrey De Smet
     */
    public abstract class BasicCrudTableView<P extends Persistable> extends CrudTableView<P> {
    
        private BasicCrudService<P> basicCrudService;
    
        public void setBasicCrudService(BasicCrudService<P> basicCrudService) {
            this.basicCrudService = basicCrudService;
        }
    
        public void afterPropertiesSet() {
            Assert.notNull(basicCrudService);
            super.afterPropertiesSet();
        }
    
        public List<P> find() {
            return basicCrudService.find();
        }
    
        public P prepareNew() {
            return basicCrudService.prepareNew();
        }
    
        public void saveOrUpdate(P p) {
            basicCrudService.saveOrUpdate(p);
        }
    
        public void delete(P p) {
            basicCrudService.delete(p);
        }
    
    }
    Code:
    /**
     * @author Geoffrey De Smet
     */
    public class TreeNodeForm extends AbstractForm {
    
        private List<Form> childFormList = new ArrayList<Form>();
    
        /**
         * TODO remove the requirement of a FormModel
         */
        public TreeNodeForm(FormModel formModel, String id) {
            super(formModel, id);
        }
    
        public List<Form> getChildFormList() {
            return childFormList;
        }
    
        public void setChildFormList(List<Form> childFormList) {
            this.childFormList = childFormList;
        }
    
        public void addChildForm(Form form) {
            childFormList.add(form);
        }
    
    
        protected JComponent createFormControl() {
            return getComponentFactory().createPanel();
        }
    
    }
    Code:
        <bean id="gggView"
                class="org.springframework.richclient.application.support.DefaultViewDescriptor">
            <property name="viewClass">
                <value>ggg.GggView</value>
            </property>
            <property name="viewProperties">
                <map>
                    <entry key="basicCrudService" value-ref="gggService" />
                    <entry key="columnPropertyNames">
                        <list>
                            <value>name</value>
                            <value>beginDate</value>
                            <value>endDate</value>
                        </list>
                    </entry>
                    <entry key="filterColumnPropertyNames">
                        <list>
                            <value>name</value>
                        </list>
                    </entry>
                </map>
            </property>
        </bean>

    Comment


    • #3
      Code:
      /**
       * @author Geoffrey De Smet
       */
      public abstract class CrudTableView<P extends Persistable> extends AbstractView implements InitializingBean {
      
          private static final String NEW_COMMAND_ID = "newCommand";
      
          protected final transient Log logger = LogFactory.getLog(getClass());
      
          private String[] columnPropertyNames;
          private String[] filterColumnPropertyNames = null;
      
          protected JTable table;
          protected GlazedTableModel glazedTableModel;
      
          private EventList baseList;
          private SortedList sortedList;
          private FilterList filterList;
      
          protected ActionCommand newCommand;
          protected ActionCommand editCommand;
          protected ActionCommand deleteCommand;
      
          public void setColumnPropertyNames(String[] columnPropertyNames) {
              this.columnPropertyNames = columnPropertyNames;
          }
      
          public void setFilterColumnPropertyNames(String[] filterColumnPropertyNames) {
              this.filterColumnPropertyNames = filterColumnPropertyNames;
          }
      
          public void afterPropertiesSet() {
              Assert.notNull(columnPropertyNames);
              initBaseSortedList();
              initExecutors();
          }
      
          private void initBaseSortedList() {
              if (baseList == null) {
                  baseList = new BasicEventList();
              }
              sortedList = new SortedList(baseList);
              if (filterColumnPropertyNames != null) {
                  filterList = new FilterList(sortedList);
              }
          }
      
          protected void initExecutors() {
              newCommand = new ActionCommand(getId() + "." + NEW_COMMAND_ID) {
                  public void doExecuteCommand() {
                      newPersistable();
                  }
              };
              editCommand = new ActionCommand(getId() + "." + GlobalCommandIds.PROPERTIES) {
                  public void doExecuteCommand() {
                      editPersistable();
                  }
              };
              deleteCommand = new ActionCommand(getId() + "." + GlobalCommandIds.DELETE) {
                  public void doExecuteCommand() {
                      deletePersistable();
                  }
              };
          }
      
      
          /**
           * @TODO this method doesn't get called for wrapped views
           */
          protected void registerLocalCommandExecutors(PageComponentContext context) {
              context.register(NEW_COMMAND_ID, newCommand);
              context.register(GlobalCommandIds.PROPERTIES, editCommand);
              context.register(GlobalCommandIds.DELETE, deleteCommand);
          }
      
          private EventList getFinalList() {
              return (filterList == null) ? sortedList : filterList;
          }
      
          protected JComponent createControl() {
              refreshBaseList();
              JPanel viewPanel = getComponentFactory().createPanel(new BorderLayout());
              if (filterColumnPropertyNames != null) {
                  viewPanel.add(createFilterPanel(), BorderLayout.NORTH);
              }
              JScrollPane tableScrollPane = getComponentFactory().createScrollPane(createTable());
              viewPanel.add(tableScrollPane, BorderLayout.CENTER);
              viewPanel.add(createButtonBar(), BorderLayout.SOUTH);
              initSelectionGuards();
              return viewPanel;
          }
      
          protected JComponent createButtonBar() {
              CommandGroup commandGroup = CommandGroup.createCommandGroup(null, new ActionCommand[]{
                      newCommand, editCommand, deleteCommand
              }, getCommandConfigurer());
      
              JComponent buttonBar = commandGroup.createButtonBar();
              GuiStandardUtils.attachDialogBorder(buttonBar);
              return buttonBar;
          }

      Comment


      • #4
        Code:
            protected JPanel createFilterPanel() {
                TableLayoutBuilder layoutBuilder = new TableLayoutBuilder();
        
                // TODO Move refreshbutton to the toolbar
                JButton refreshButton = getComponentFactory().createButton("refreshButton.label");
                refreshButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        refreshBaseList();
                    }
                });
                layoutBuilder.cell(refreshButton, "colSpec=fill:default:none");
                layoutBuilder.gapCol("fill:default:grow");
        
                final String FILTER_LABEL_KEY = "filter.label";
                JLabel filterLabel = getComponentFactory().createLabel(
                        new String[]{getId() + "." + FILTER_LABEL_KEY, FILTER_LABEL_KEY});
                layoutBuilder.cell(filterLabel, "colSpec=fill:default:none");
                layoutBuilder.gapCol();
        
                final JTextField filterField = getComponentFactory().createTextField();
                final String FILTER_CAPTION_KEY = "filter.caption";
                filterField.setToolTipText(getMessage(new String[]{getId() + "." + FILTER_CAPTION_KEY, FILTER_CAPTION_KEY}));
                TextFilterator filterator = GlazedLists.textFilterator(filterColumnPropertyNames);
                MatcherEditor filterMatcherEditor = new TextComponentMatcherEditor(filterField, filterator);
                filterList.setMatcherEditor(filterMatcherEditor);
                layoutBuilder.cell(filterField, "colSpec=fill:default:grow");
                layoutBuilder.gapCol();
                filterLabel.setLabelFor(filterField);
        
                JButton clearFilterButton = getComponentFactory().createButton("clearFilterButton.label");
                clearFilterButton.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        filterField.setText("");
                    }
                });
                layoutBuilder.cell(clearFilterButton, "colSpec=fill:default:none");
        
                JPanel filterPanel = layoutBuilder.getPanel();
                filterPanel.setBorder(GuiStandardUtils.createEvenlySpacedBorder(UIConstants.ONE_SPACE));
                return filterPanel;
            }
        Last edited by ge0ffrey; Sep 11th, 2006, 06:50 AM.

        Comment


        • #5
          Thanks ge0ffrey, that was a fast reply. I will give it a go! It seems that code is incomplete though, it would be very nice of you to add the bottom bit that is missing from your last post :-) Thanks again!

          Comment


          • #6
            Code:
                protected JTable createTable() {
                    glazedTableModel = new GlazedTableModel(getFinalList(),
                            columnPropertyNames, getId()) {
                        protected boolean isEditable(Object row, int column) {
                            return false;
                        }
                    };
                    table = getComponentFactory().createTable(glazedTableModel);
            
                    EventSelectionModel selectionModel = new EventSelectionModel(getFinalList());
                    selectionModel.addListSelectionListener(
                            new ListSelectionListenerSupport() {
                                protected void onNoSelection() {
            //                        getStatusBar().setMessage("");
                                }
            
                                protected void onSingleSelection(int i) {
            //                        Project project = (Project) eventSelectionModel.getSelected().get(0);
            //                        String statusBarMessage = getMessage(VIEW_ID + ".singleSelection.statusBarMessage",
            //                                new Object[]{project.getCode()});
            //                        getStatusBar().setMessage(statusBarMessage);
                                }
            
                                protected void onMultiSelection(int[] ints) {
            //                        String statusBarMessage = getMessage(VIEW_ID + ".multiSelection.statusBarMessage");
            //                        getStatusBar().setMessage(statusBarMessage);
                                }
            
                                public void valueChanged(ListSelectionEvent e) {
                                    // updateStatusBar();
                                }
                            });
                    table.setSelectionModel(selectionModel);
                    table.setSelectionMode(EventSelectionModel.SINGLE_SELECTION);
            
                    TableComparatorChooser tableSorter = new TableComparatorChooser(table, sortedList, true);
                    tableSorter.clearComparator();
                    tableSorter.appendComparator(0, 0, false);
            
                    table.addMouseListener(new MouseAdapter() {
                        public void mousePressed(MouseEvent e) {
                            // If the user right clicks on a row other than the selection,
                            // then move the selection to the current row
                            int rowUnderMouse = table.rowAtPoint(e.getPoint());
                            if (e.getButton() == MouseEvent.BUTTON3 && !table.isRowSelected(rowUnderMouse)) {
                                // Select the row under the mouse
                                if (rowUnderMouse != -1) {
                                    table.getSelectionModel().setSelectionInterval(rowUnderMouse, rowUnderMouse);
                                }
                            }
                        }
            
                        public void mouseClicked(MouseEvent e) {
                            // Handle double click
                            if (e.getClickCount() == 2
                                    && e.getButton() == MouseEvent.BUTTON1
                                    && editCommand.isEnabled()) {
                                editCommand.execute();
                            }
                        }
                    });
            //        table.addMouseListener(new PopupMenuMouseListener() {
            //            protected JPopupMenu getPopupMenu() {
            //                return createPopupContextMenu();
            //            }
            //        });
            
                    return table;
                }
            
                protected void initSelectionGuards() {
                    ValueModel selectionHolder = getSelectionHolder();
                    new ListSingleSelectionGuard(selectionHolder, editCommand);
                    new ListSingleSelectionGuard(selectionHolder, deleteCommand);
                }
            
                protected ValueModel getSelectionHolder() {
                    return new ListSelectionValueModelAdapter(table.getSelectionModel());
                }
            
                private P getSelectedPersistable() {
                    int row = table.getSelectedRow();
                    P p;
                    if (row < 0) {
                        p = null;
                    } else {
                        p = (P) glazedTableModel.getElementAt(row);
                    }
                    return p;
                }
            
                /**
                 * Refreshes all persitables without removing unremoved persitables.
                 * This is important for the list selection.
                 */
                protected void refreshBaseList() {
                    List<? extends Persistable> persistableList = find();
                    // Don't just clear the baseList, instead do a smart replace
                    baseList.retainAll(persistableList); // remove all removed
                    for (Persistable persistable : persistableList) {
                        if (baseList.contains(persistable)) {
                            baseList.set(baseList.indexOf(persistable), persistable); // update all updated
                        } else {
                            baseList.add(persistable); // add all added
                        }
                    }
                }
            
                protected void newPersistable() {
                    P p = prepareNew();
                    newOrEditPersistable(p);
                }
            
                protected void editPersistable() {
                    P p = getSelectedPersistable();
                    newOrEditPersistable(p);
                }
            
                /**
                 * @TODO Duplicate code with:
                 * be.kahosl.thot.swingui.project.relation.RelationForm.newOrganization()
                 * be.kahosl.thot.swingui.semestermission.task.TaskListForm.newOrEditTask()
                 */
                protected void newOrEditPersistable(final P p) {
                    String dialogId = getId() + ".dialog";
                    String title = getMessage(dialogId + ".title", new Object[]{p});
                    final TreeCompositeDialogPage treeCompositeDialogPage = new TreeCompositeDialogPage(dialogId);
                    treeCompositeDialogPage.setTitle(title);
                    final HierarchicalFormModel formModel = FormModelHelper.createCompoundFormModel(p);
                    List<Form> formList = createForms(formModel);
                    addForms(treeCompositeDialogPage, treeCompositeDialogPage, formList);
                    TitledPageApplicationDialog dialog = new TitledPageApplicationDialog(treeCompositeDialogPage,
                            getActiveWindow().getControl()) {
                        protected boolean onFinish() {
                            formModel.commit();
                            saveOrUpdate(p);
                            return true;
                        }
                    };
                    dialog.setTitle(title);
                    try {
                        dialog.showDialog();
                    } finally {
                        // Force a refresh, even if an exception occured
                        refreshBaseList();
                    }
                }
            
                private void addForms(TreeCompositeDialogPage treeCompositeDialogPage, DialogPage parentDialogPage,
                        List<Form> formList) {
                    for (Form form : formList) {
                        DialogPage dialogPage = (treeCompositeDialogPage == parentDialogPage)
                                ? treeCompositeDialogPage.addForm(form)
                                : treeCompositeDialogPage.addForm(parentDialogPage, form);
                        if (form instanceof TreeNodeForm) {
                            TreeNodeForm treeNodeForm = (TreeNodeForm) form;
                            List<Form> childFormList = treeNodeForm.getChildFormList();
                            addForms(treeCompositeDialogPage, dialogPage, childFormList);
                        }
                    }
                }
            
                protected void deletePersistable() {
                    final P persistable = getSelectedPersistable();
                    String title = getMessage(getId() + ".confirmDelete.title");
                    String message = getMessage(getId() + ".confirmDelete.message", new Object[]{persistable});
                    ConfirmationDialog dialog = new ConfirmationDialog(title, message) {
                        protected void onConfirm() {
                            delete(persistable);
                            getApplicationContext().publishEvent(
                                    new LifecycleApplicationEvent(LifecycleApplicationEvent.DELETED, persistable));
                        }
                    };
                    try {
                        dialog.showDialog();
                    } finally {
                        // Force a refresh, even if an exception occured
                        this.refreshBaseList();
                    }
                }
            
                public abstract List<P> find();
            
                public abstract P prepareNew();
            
                public abstract void saveOrUpdate(P p);
            
                public abstract void delete(P p);
            
                /**
                 * Most cases will overwrite this with a method that returns a List of normal Forms.,
                 * but sometimes a TreeNodeForm will be used which wraps a list of child forms.
                 */
                protected abstract List<Form> createForms(HierarchicalFormModel formModel);
            
            }
            Last edited by ge0ffrey; Sep 11th, 2006, 08:38 AM.

            Comment


            • #7
              But again... It's far from perfect and it's based on Larry's simple example's code.
              This code abuses generics (simple example doesn't).
              I wouldn't really recommend it, but it might give you an idea on how to do things...

              Code:
              public class FooView extends BasicCrudTableView<Foo> {
              
                  protected List<Form> createForms(HierarchicalFormModel formModel) {
                      List<Form> formList = new ArrayList<Form>();
                      formList.add(new FooGeneralForm(FormModelHelper.createChildPageFormModel(formModel)));
                      return formList;
                  }
              
              }

              Comment

              Working...
              X