001    package data.stdforms;
002    
003    import resource.util.ResourceManager;
004    import sale.*;
005    import data.*;
006    import data.filters.AbstractStockFilter;
007    import data.filters.CatalogFilter;
008    import data.stdforms.twotableformsheet.*;
009    import data.swing.*;
010    import users.UserManager;
011    import users.swing.UserTableModel;
012    import util.swing.*;
013    
014    import java.awt.Dimension;
015    import java.awt.GridLayout;
016    import java.util.*;
017    
018    import javax.swing.*;
019    import javax.swing.table.TableModel;
020    
021    /**
022     * A FormSheet that will display the contents of two data containers, a source and a destination, and will
023     * allow the user to move items between the two.
024     *
025     * <p>Source and destination are displayed in a tabular form. The data containers that are supported as source
026     * or destination are: {@link Catalog}, {@link Stock}, {@link DataBasket}. There will be two buttons that
027     * allow to move items from the source into the destination table and vice-versa. If at least one of source
028     * and destination is a {@link CountingStock} there will also be an input line where the user can specify how
029     * many items are to be moved. The actual moving will be implemented as sub-process of the process that
030     * displays the FormSheet. The concrete sub-process implementations are provided by {@link MoveStrategy}
031     * strategy objects.</p>
032     *
033     * <p>A quite comprehensive set of <code>create()</code> functions is provided to allow to easily create
034     * TwoTableFormSheets by simply supplying some parameters.</p>
035     *
036     * @author Steffen Zschaler
037     * @version 2.0 20/08/1999
038     * @since v2.0
039     */
040    public class TwoTableFormSheet extends FormSheet {
041    
042        /**
043             * ID for serialization.
044             */
045            private static final long serialVersionUID = 1073218641254871804L;
046    
047            /**
048         * The DataBasket used.
049         */
050        private DataBasket m_db;
051    
052        /**
053         * The source for the left table.
054         */
055        private Object m_leftSource;
056    
057        /**
058         * The source for the right table.
059         */
060        private Object m_rightSource;
061    
062        /**
063         * The left table
064         */
065        private JTable m_leftTable;
066    
067        /**
068         * The left table
069         */
070        private JTable m_rightTable;
071    
072        /**
073         * The strategy used when moving items between source and destination.
074         *
075         * @serial
076         */
077        private MoveStrategy m_ms;
078    
079        /**
080         * The gate at which the FormSheet is displayed.
081         *
082         * @serial
083         */
084        private UIGate m_uigGate;
085    
086        /**
087         * The {@link TableModel} of the left table displayed.
088         */
089        private transient util.swing.AbstractTableModel m_atmLeftModel;
090    
091        /**
092         * The {@link TableModel} of the right table displayed.
093         */
094        private transient util.swing.AbstractTableModel m_atmRightModel;
095    
096        /**
097         * Reference to the currently selected index.
098         *
099         * @serial
100         */
101        private final int[] m_anLeftSelection = new int[] {
102                 -1};
103    
104        /**
105         * Reference to the currently selected index.
106         *
107         * @serial
108         */
109        private final int[] m_anRightSelection = new int[] {
110                 -1};
111        
112        
113    
114        /**
115         * Create a new TwoTableFormSheet. Instead of calling this constructor directly, use one of the many
116         * <code>create()</code> functions provided.
117         *
118         * @param sCaption the caption of the FormSheet.
119         * @param fscc the content creator to be used.
120         * @param uigGate the gate at which to display the FormSheet.
121         * @param ms the strategy to be used when moving items between source and destination.
122         */
123        protected TwoTableFormSheet(String sCaption, FormSheetContentCreator fscc, UIGate uigGate,
124                MoveStrategy ms) {
125            super(sCaption, (JComponent)null, true);
126    
127            m_ms = ms;
128            setGate(uigGate);
129    
130            addContentCreator(fscc);
131        }
132    
133        /**
134         * Get the record currently selected in the left table.
135         *
136         * <p>The actual class of the record depends on the concrete type of TableModel used. See the TableModel's
137         * <code>getRecord()</code> method for details.</p>
138         */
139        public Object getLeftSelectedRecord() {
140            return m_atmLeftModel.getRecord(m_anLeftSelection[0]);
141        }
142    
143        /**
144         * Get the record currently selected in the right table.
145         *
146         * <p>The actual class of the record depends on the concrete type of TableModel used. See the TableModel's
147         * <code>getRecord()</code> method for details.</p>
148         */
149        public Object getRightSelectedRecord() {
150            return m_atmRightModel.getRecord(m_anRightSelection[0]);
151        }
152    
153        /**
154         * Get the currently attached DataBasket.
155         *
156         * @override Never
157         */
158        public DataBasket getDataBasket() {
159            return m_db;
160        }
161    
162        /**
163         * Get the source of the left table.
164         *
165         * @override Never
166         */
167        public Object getLeftTableSource() {
168            return m_leftSource;
169        }
170    
171        /**
172         * Get the source of the right table.
173         *
174         * @override Never
175         */
176        public Object getRightTableSource() {
177            return m_rightSource;
178        }
179        
180        /**
181         * Set the source of the left table.
182         * New source is a {@link data.Catalog}
183         *
184         * @param m_catalogSource the new datasource as Catalog
185         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
186         * 
187         * @override Never
188         */
189        public void setLeftTable(   Catalog m_catalogSource,
190                                                            TableEntryDescriptor ted) {
191            JAbstractTable jat_c = (JAbstractTable) getLeftTable();
192            AbstractTableModel atm = jat_c.getAbstractTableModel();
193            if(atm instanceof CatalogTableModel) {
194                    atm.setData(m_catalogSource);
195            }
196            else {
197                    jat_c.setModel(
198                                    new CatalogTableModel(  m_catalogSource,
199                                                                                            getDataBasket(),
200                                                                                            ((CatalogTableModel)atm).getComparator(),
201                                                                                            ted));
202            }
203        }
204        
205        /**
206         * Set the source of the left table.
207         * New source is a {@link data.CountingStock}
208         *
209         * @param m_csSource the new datasource as CoutingStock
210         * @param fShowZeros if true, lines informing about a zero amount of objects will be shown. Only necessary if prior TableModel is different from actual TableModel.
211         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
212         * 
213         * @override Never
214         */
215        public void setLeftTable(   CountingStock m_csSource,
216                                                                    boolean fShowZeros,
217                                                                    TableEntryDescriptor ted) 
218            {
219            JAbstractTable jat_c = (JAbstractTable) getLeftTable();
220            AbstractTableModel atm = jat_c.getAbstractTableModel();
221            if(atm instanceof CountingStockTableModel) {
222                    atm.setData(m_csSource);
223            }
224            else {
225                    jat_c.setModel(
226                                    new CountingStockTableModel(    m_csSource,
227                                                                                                            getDataBasket(),
228                                                                                                            ((CatalogTableModel) atm).getComparator(),
229                                                                                                            fShowZeros,
230                                                                                                            ted));
231            }
232        }
233        
234        /**
235         * Set the source of the left table.
236         * New source is a {@link data.StoringStock}
237         *
238         * @param m_stSource the new datasource as StoringStock
239         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
240         * 
241         * @override Never
242         */
243        public void setLeftTable(   StoringStock m_stSource,
244                                                            TableEntryDescriptor ted)
245            {
246            JAbstractTable jat_c = (JAbstractTable) getLeftTable();
247            AbstractTableModel atm = jat_c.getAbstractTableModel();
248            if(atm instanceof StoringStockTableModel) {
249                    atm.setData(m_stSource);        
250            }
251            else {
252                    jat_c.setModel(
253                                    new StoringStockTableModel(     m_stSource,
254                                                                                            getDataBasket(),
255                                                                                                    null,
256                                                                                                    ted));
257            }
258            
259        }
260        
261        /**
262         * Set the source of the left table.
263         * New source is a {@link users.UserManager}
264         *
265         * @param m_umManager the new datasource as UserManager
266         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
267         *
268         * @override Never
269         */
270        public void setLeftTable(   UserManager m_umManager,
271                                                            TableEntryDescriptor ted) {
272            JAbstractTable jat_c = (JAbstractTable) getLeftTable();
273            AbstractTableModel atm = jat_c.getAbstractTableModel();
274            if(atm instanceof UserTableModel) {
275                    atm.setData(m_umManager);       
276            }
277            else {
278                    jat_c.setModel(
279                                    new UserTableModel(     m_umManager,
280                                                                            null,
281                                                                                    ted));
282            }
283        }
284        
285        /**
286         * Set the source of the left table.
287         * New source is a {@link data.DataBasket}
288         * 
289         * @param m_dbSource the new datasource as Databasket
290         * @param dbc a condition specifying the DataBasketEntries to be part of the model. Only necessary if prior TableModel is different from actual TableModel.
291         * @param dbeg dbeg a strategy that will group individual DataBasketEntries together for display. If
292         * <code>null</code>, no grouping will occur. Only necessary if prior TableModel is different from actual TableModel. 
293         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
294         * 
295         * @override Never
296         */
297        public void setLeftTable(   DataBasket m_dbSource,
298                                                            DataBasketCondition dbc,
299                                                                    DataBasketEntryGrouper dbeg,
300                                                                    TableEntryDescriptor ted) {
301            JAbstractTable jat_c = (JAbstractTable) getLeftTable();
302            AbstractTableModel atm = jat_c.getAbstractTableModel();
303            if(atm instanceof DataBasketTableModel) {
304                    atm.setData(m_dbSource);        
305            }
306            else {
307                    jat_c.setModel(
308                                    new DataBasketTableModel(       m_dbSource,
309                                                                                            dbc,
310                                                                                                    dbeg,
311                                                                                                    null,
312                                                                                                    ted));
313            }
314        }
315        
316        /**
317         * Set the source of the right table.
318         * New source is a {@link data.Catalog}
319         *
320         * @param m_catalogSource the new datasource as Catalog
321         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
322         * 
323         * @override Never
324         */
325        public void setRightTable(  Catalog m_catalogSource,
326                                                            TableEntryDescriptor ted) {
327            JAbstractTable jat_c = (JAbstractTable) getRightTable();
328            AbstractTableModel atm = jat_c.getAbstractTableModel();
329            if(atm instanceof CatalogTableModel) {
330                    atm.setData(m_catalogSource);
331            }
332            else {
333                    jat_c.setModel(
334                                    new CatalogTableModel(  m_catalogSource,
335                                                                                            getDataBasket(),
336                                                                                            ((CatalogTableModel)atm).getComparator(),
337                                                                                            ted));
338            }
339        }
340        
341        /**
342         * Set the source of the right table.
343         * New source is a {@link data.CountingStock}
344         *
345         * @param m_csSource the new datasource as CoutingStock
346         * @param fShowZeros if true, lines informing about a zero amount of objects will be shown. Only necessary if prior TableModel is different from actual TableModel.
347         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
348         * 
349         * @override Never
350         */
351        public void setRightTable(  CountingStock m_csSource,
352                                                                    boolean fShowZeros,
353                                                                    TableEntryDescriptor ted) 
354            {
355            JAbstractTable jat_c = (JAbstractTable) getRightTable();
356            AbstractTableModel atm = jat_c.getAbstractTableModel();
357            if(atm instanceof CountingStockTableModel) {
358                    atm.setData(m_csSource);
359            }
360            else {
361                    jat_c.setModel(
362                                    new CountingStockTableModel(    m_csSource,
363                                                                                                            getDataBasket(),
364                                                                                                            ((CatalogTableModel) atm).getComparator(),
365                                                                                                            fShowZeros,
366                                                                                                            ted));
367            }
368        }
369        
370        /**
371         * Set the source of the right table.
372         * New source is a {@link data.StoringStock}
373         *
374         * @param m_stSource the new datasource as StoringStock
375         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
376         * 
377         * @override Never
378         */
379        public void setRightTable(  StoringStock m_stSource,
380                                                            TableEntryDescriptor ted)
381            {
382            JAbstractTable jat_c = (JAbstractTable) getRightTable();
383            AbstractTableModel atm = jat_c.getAbstractTableModel();
384            if(atm instanceof StoringStockTableModel) {
385                    atm.setData(m_stSource);        
386            }
387            else {
388                    jat_c.setModel(
389                                    new StoringStockTableModel(     m_stSource,
390                                                                                            getDataBasket(),
391                                                                                                    null,
392                                                                                                    ted));
393            }
394            
395        }
396        
397        /**
398         * Set the source of the right table.
399         * New source is a {@link data.DataBasket}
400         * 
401         * @param m_dbSource the new datasource as Databasket
402         * @param dbc a condition specifying the DataBasketEntries to be part of the model. Only necessary if prior TableModel is different from actual TableModel.
403         * @param dbeg dbeg a strategy that will group individual DataBasketEntries together for display. If
404         * <code>null</code>, no grouping will occur. Only necessary if prior TableModel is different from actual TableModel. 
405         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
406         * 
407         * @override Never
408         */
409        public void setRightTable(  DataBasket m_dbSource,
410                                                            DataBasketCondition dbc,
411                                                                    DataBasketEntryGrouper dbeg,
412                                                                    TableEntryDescriptor ted) {
413            JAbstractTable jat_c = (JAbstractTable) getRightTable();
414            AbstractTableModel atm = jat_c.getAbstractTableModel();
415            if(atm instanceof DataBasketTableModel) {
416                    atm.setData(m_dbSource);        
417            }
418            else {
419                    jat_c.setModel(
420                                    new DataBasketTableModel(       m_dbSource,
421                                                                                            dbc,
422                                                                                                    dbeg,
423                                                                                                    null,
424                                                                                                    ted));
425            }
426        }
427        
428        /**
429         * Set the source of the right table.
430         * New source is a {@link users.UserManager}
431         *
432         * @param m_umManager the new datasource as UserManager
433         * @param ted the new TableEntryDescriptor for the DataBasket. Only necessary if prior TableModel is different from actual TableModel.
434         *
435         * @override Never
436         */
437        public void setRightTable(  UserManager m_umManager,
438                                                            TableEntryDescriptor ted) {
439            JAbstractTable jat_c = (JAbstractTable) getRightTable();
440            AbstractTableModel atm = jat_c.getAbstractTableModel();
441            if(atm instanceof UserTableModel) {
442                    atm.setData(m_umManager);       
443            }
444            else {
445                    jat_c.setModel(
446                                    new UserTableModel(     m_umManager,
447                                                                            null,
448                                                                                    ted));
449            }
450        }
451        
452        /**
453         * Get the left table.
454         *
455         * @override Never
456         */
457        public JTable getLeftTable() {
458            return m_leftTable;
459        }
460    
461        /**
462         * Get the right table.
463         *
464         * @override Never
465         */
466        public JTable getRightTable() {
467            return m_rightTable;
468        }
469    
470        /**
471         * Get the strategy used when moving items between source and destination.
472         *
473         * @override Never
474         */
475        public MoveStrategy getStrategy() {
476            return m_ms;
477        }
478    
479        /**
480         * Set the strategy to be used when moving items between source and destination. Note, that the new
481         * strategy's {@link MoveStrategy#canMoveToDest} and {@link MoveStrategy#canMoveToSource} methods will
482         * have no effect. Also, it is your responsibility to make sure, that the actual class of the strategy
483         * matches the source/destination combination.
484         *
485         * @param ms the new strategy
486         *
487         * @override Never
488         */
489        public void setStrategy(MoveStrategy ms) {
490            m_ms = ms;
491        }
492    
493        /**
494         * Get the gate at which the FormSheet is being displayed.
495         *
496         * @override Never
497         */
498        public UIGate getGate() {
499            return m_uigGate;
500        }
501    
502        /**
503         * Set the gate at which to display the FormSheet. The FormSheet will be moved to the new gate, i.e.
504         * {@link UIGate#setFormSheet} will be called with the FormSheet as a parameter.
505         *
506         * @override Never
507         */
508        public void setGate(UIGate uigGate) {
509            if (m_uigGate != null) {
510                m_uigGate.setFormSheet(null);
511            }
512    
513            m_uigGate = uigGate;
514    
515            if (m_uigGate != null) {
516                m_uigGate.setFormSheet(this);
517            }
518        }
519    
520    
521        //set methods have to change the move strategy, still to do...
522        /**
523         * Changes the {@link TableModel} of the left table
524         * @param the new TableModel
525         */
526      /*  public void setLeftTableModel(util.swing.AbstractTableModel tm) {
527            m_atmLeftModel.fireTableDataChanged(); //unselect a possibly selected record
528            if (tm instanceof TableSorter) {
529                m_atmLeftModel = tm;
530            } else {
531                m_atmLeftModel = new TableSorter(tm);
532            }
533            m_leftTable.setModel(m_atmLeftModel);
534            ((JAbstractTable)m_leftTable).initialize();
535        }*/
536    
537        /**
538         * Changes the {@link TableModel} of the right table
539         * @param the new TableModel
540         */
541        /*public void setRightTableModel(util.swing.AbstractTableModel tm) {
542            m_atmRightModel.fireTableDataChanged(); //unselect a possibly selected record
543            if (tm instanceof TableSorter) {
544                m_atmRightModel = tm;
545            } else {
546                m_atmRightModel = new TableSorter(tm);
547            }
548            m_rightTable.setModel(m_atmRightModel);
549            ((JAbstractTable)m_rightTable).initialize();
550        }*/
551    
552        // 1. CountingStock -> CountingStock
553    
554        /**
555         * Create and return a new TwoTableFormSheet where source and destination are CountingStocks.
556         *
557         * <p>There will be an input line where the user can specify how many items to move with the next action.
558         * </p>
559         *
560         * @param sCaption the caption of the FormSheet.
561         * @param csSource the source Stock.
562         * @param csDest the destination Stock.
563         * @param db the DataBasket relative to which to perform all operations.
564         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
565         * {@link #setGate set} before actually using the FormSheet.
566         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be the
567         * keys of the individual items. If <code>null</code> the ordering will be the natural ordering of the keys.
568         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
569         * the keys of the individual items. If <code>null</code> the ordering will be the natural ordering of the
570         * keys.
571         * @param fShowZerosSource if false, source lines containing '0' in the &quot;Count&quot; column will be
572         * hidden.
573         * @param fShowZerosDest if false, destination lines containing '0' in the &quot;Count&quot; column will be
574         * hidden.
575         * @param tedSource a TableEntryDescriptor that can split individual
576         * {@link data.swing.CountingStockTableModel.Record CountingStockTableModel records} into a table's cells. It will be
577         * used for the source table. If <code>null</code> and <code>csSource</code> is a {@link MoneyBag} it
578         * defaults to a {@link DefaultMoneyBagItemTED} using <code>csSource.getCatalog()</code> to format values.
579         * Otherwise, it defaults to a {@link DefaultCountingStockItemTED}.
580         * @param tedDest a TableEntryDescriptor that can split individual
581         * {@link data.swing.CountingStockTableModel.Record CountingStockTableModel records} into a table's cells. It will be
582         * used for the destination table. If <code>null</code> and <code>csDest</code> is a {@link MoneyBag} it
583         * defaults to a {@link DefaultMoneyBagItemTED} using <code>csDest.getCatalog()</code> to format values.
584         * Otherwise, it defaults to a {@link DefaultCountingStockItemTED}.
585         * @param cscssMoveStrategy the strategy to be used when moving items between source and destination. If
586         * <code>null</code>, defaults to a {@link CSCSStrategy} object.
587         * @param direction the direction in which the move operation (from source to destination) should be performed
588         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
589         */
590        public static TwoTableFormSheet create(String sCaption, final CountingStock csSource,
591                final CountingStock csDest, final DataBasket db, UIGate uigGate, final Comparator<CatalogItem> cmpSource,
592                final Comparator<CatalogItem> cmpDest, final boolean fShowZerosSource, final boolean fShowZerosDest,
593                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
594                CSCSStrategy cscssMoveStrategy, final int direction) {
595    
596            if (csSource.getCatalog(db) != csDest.getCatalog(db)) {
597                throw new CatalogConflictException();
598            }
599    
600            FormSheetContentCreator fscc = new FormSheetContentCreator() {
601                            private static final long serialVersionUID = -8133335597008065230L;
602    
603                            protected void createFormSheetContent(FormSheet fs) {
604    
605                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
606    
607                    final int[] anCounter = {
608                            1};
609    
610                    JCountingStockTable jcstSource = new JCountingStockTable(csSource, db, cmpSource,
611                            fShowZerosSource,
612                            ((tedSource != null) ? (tedSource) : ((csSource instanceof MoneyBag) ?
613                            (new DefaultMoneyBagItemTED((data.Currency)csSource.getCatalog(db))) :
614                            (new DefaultCountingStockItemTED()))));
615                    jcstSource.setSelectionObserver(ttfs.m_anLeftSelection);
616                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jcstSource.
617                            getModel();
618    
619                    ttfs.m_atmLeftModel = atmSource;
620                    ttfs.m_leftTable = jcstSource;
621                    ttfs.m_leftSource = csSource;
622                    ttfs.m_db = db;
623    
624                    JCountingStockTable jcstDest = new JCountingStockTable(csDest, db, cmpDest, fShowZerosDest,
625                            ((tedDest != null) ? (tedDest) : ((csDest instanceof MoneyBag) ?
626                            (new DefaultMoneyBagItemTED((data.Currency)csDest.getCatalog(db))) :
627                            (new DefaultCountingStockItemTED()))));
628                    jcstDest.setSelectionObserver(ttfs.m_anRightSelection);
629                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jcstDest.
630                            getModel();
631    
632                    ttfs.m_atmRightModel = atmDest;
633                    ttfs.m_rightTable = jcstDest;
634                    ttfs.m_rightSource = csDest;
635                    
636                    JTextField jtf = new JIntInput(anCounter, 1, 1, Integer.MAX_VALUE);
637    
638                    JButton jbRight = createMoveButton("right", direction);
639                    JButton jbLeft = createMoveButton("left", direction);
640                    JPanel jpForm = createForm(jbRight, jbLeft, jtf, jcstSource, jcstDest, ttfs, direction);
641                    
642                    if (ttfs.getStrategy().canMoveToDest()) {
643                        jbRight.addActionListener(new ActionActionListener(fs) {
644                                                    private static final long serialVersionUID = 1112118904469417631L;
645    
646                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
647                                CountingStockTableModel.Record r = (CountingStockTableModel.Record)atmSource.
648                                        getRecord(ttfs.m_anLeftSelection[0]);
649    
650                                if (r != null) {
651                                    UIGate uig = ttfs.getGate();
652                                    if (uig != null) {
653                                        uig.setNextTransition(((CSCSStrategy)ttfs.getStrategy()).
654                                                getMoveToDestProcess(p, sp, csSource, csDest, db, r.getDescriptor(),
655                                                anCounter[0], ttfs));
656                                    }
657                                }
658                            }
659                        });
660                    }
661    
662                    if (ttfs.getStrategy().canMoveToSource()) {
663                        jbLeft.addActionListener(new ActionActionListener(fs) {
664                                                    private static final long serialVersionUID = -8570898083061871811L;
665    
666                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
667                                CountingStockTableModel.Record r = (CountingStockTableModel.Record)atmDest.
668                                        getRecord(ttfs.m_anRightSelection[0]);
669    
670                                if (r != null) {
671                                    UIGate uig = ttfs.getGate();
672                                    if (uig != null) {
673                                        uig.setNextTransition(((CSCSStrategy)ttfs.getStrategy()).
674                                                getMoveToSourceProcess(p, sp, csSource, csDest, db,
675                                                r.getDescriptor(), anCounter[0], ttfs));
676                                    }
677                                }
678                            }
679                        });
680                    }
681    
682                    fs.setComponent(jpForm);
683                }
684            };
685    
686            cscssMoveStrategy = ((cscssMoveStrategy != null) ? (cscssMoveStrategy) : (new CSCSStrategy()));
687    
688            return new TwoTableFormSheet(sCaption, fscc, uigGate, cscssMoveStrategy);
689        }
690    
691        /**
692         * Create and return a new TwoTableFormSheet where source and destination are CountingStocks.
693         *
694         * <p>Calls the appropriate fully parameterized function, passing default values (i.e. <code>null</code> or
695         * false) for the missing parameters.</p>
696         *
697         * @param sCaption the caption of the FormSheet.
698         * @param csSource the source Stock.
699         * @param csDest the destination Stock.
700         * @param db the DataBasket relative to which to perform all operations.
701         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
702         * {@link #setGate set} before actually using the FormSheet.
703         * @param direction the direction in which the move operation (from source to destination) should be performed
704         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
705         */
706        public static TwoTableFormSheet create(String sCaption, CountingStock csSource, CountingStock csDest,
707                DataBasket db, UIGate uigGate, int direction) {
708            return create(sCaption, csSource, csDest, db, uigGate, null, null, false, false, null, null, null, direction);
709        }
710    
711        // 2. StoringStock -> StoringStock
712    
713        /**
714         * Create and return a new TwoTableFormSheet where source and destination are StoringStocks.
715         *
716         * @param sCaption the caption of the FormSheet.
717         * @param ssSource the source Stock.
718         * @param ssDest the destination Stock.
719         * @param db the DataBasket relative to which to perform all operations.
720         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
721         * {@link #setGate set} before actually using the FormSheet.
722         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be the
723         * individual items. If <code>null</code> the ordering will be the natural ordering of the items.
724         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
725         * the individual items. If <code>null</code> the ordering will be the natural ordering of the items.
726         * @param tedSource a TableEntryDescriptor that can split individual {@link StockItem StockItems} into a
727         * table's cells. It will be used for the source table. If <code>null</code> it defaults to a
728         * {@link DefaultStockItemTED}.
729         * @param tedDest a TableEntryDescriptor that can split individual {@link StockItem StockItems} into a
730         * table's cells. It will be used for the destination table. If <code>null</code> it defaults to a
731         * {@link DefaultStockItemTED}.
732         * @param sssssMoveStrategy the strategy to be used when moving items between source and destination. If
733         * <code>null</code>, defaults to a {@link SSSSStrategy} object.
734         * @param direction the direction in which the move operation (from source to destination) should be performed
735         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
736         */
737        public static TwoTableFormSheet create(String sCaption, final StoringStock ssSource,
738                final StoringStock ssDest, final DataBasket db, UIGate uigGate, final Comparator<StockItem> cmpSource,
739                final Comparator<StockItem> cmpDest, final TableEntryDescriptor tedSource,
740                final TableEntryDescriptor tedDest, SSSSStrategy sssssMoveStrategy, final int direction) {
741            FormSheetContentCreator fscc = new FormSheetContentCreator() {
742                            private static final long serialVersionUID = -3246844792440325885L;
743    
744                            protected void createFormSheetContent(FormSheet fs) {
745                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
746    
747                    JStoringStockTable jsstSource = new JStoringStockTable(ssSource, db, cmpSource,
748                            ((tedSource != null) ? (tedSource) : (new DefaultStockItemTED())));
749                    jsstSource.setSelectionObserver(ttfs.m_anLeftSelection);
750                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jsstSource.
751                            getModel();
752    
753                    ttfs.m_atmLeftModel = atmSource;
754                    ttfs.m_leftTable = jsstSource;
755                    ttfs.m_leftSource = ssSource;
756                    ttfs.m_db = db;
757    
758                    JStoringStockTable jsstDest = new JStoringStockTable(ssDest, db, cmpDest,
759                            ((tedDest != null) ? (tedDest) : (new DefaultStockItemTED())));
760                    jsstDest.setSelectionObserver(ttfs.m_anRightSelection);
761                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jsstDest.
762                            getModel();
763    
764                    ttfs.m_atmRightModel = atmDest;
765                    ttfs.m_rightTable = jsstDest;
766                    ttfs.m_rightSource = ssDest;
767                    
768                    JButton jbRight = createMoveButton("right", direction);
769                    JButton jbLeft = createMoveButton("left", direction);
770                    JPanel jpForm = createForm(jbRight, jbLeft, null, jsstSource, jsstDest, ttfs, direction);                
771    
772             /*       JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
773                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
774    
775                    JPanel jpForm = new JPanel();
776                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
777    
778                    jpForm.add(new JScrollPane(jsstSource));
779    
780                    jpForm.add(createCentralBox(jbRight, jbLeft, null, ttfs.getStrategy()));
781    
782                    jpForm.add(new JScrollPane(jsstDest));*/
783    
784                    if (ttfs.getStrategy().canMoveToDest()) {
785                        jbRight.addActionListener(new ActionActionListener(fs) {
786                                                    private static final long serialVersionUID = -4181225063618764681L;
787    
788                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
789                                StockItem si = (StockItem)atmSource.getRecord(ttfs.m_anLeftSelection[0]);
790    
791                                if (si != null) {
792                                    UIGate uig = ttfs.getGate();
793                                    if (uig != null) {
794                                        uig.setNextTransition(((SSSSStrategy)ttfs.getStrategy()).
795                                                getMoveToDestProcess(p, sp, ssSource, ssDest, db, si, ttfs));
796                                    }
797                                }
798                            }
799                        });
800                    }
801    
802                    if (ttfs.getStrategy().canMoveToSource()) {
803                        jbLeft.addActionListener(new ActionActionListener(fs) {
804                                                    private static final long serialVersionUID = -4160594553952172204L;
805    
806                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
807                                StockItem si = (StockItem)atmDest.getRecord(ttfs.m_anRightSelection[0]);
808    
809                                if (si != null) {
810                                    UIGate uig = ttfs.getGate();
811                                    if (uig != null) {
812                                        uig.setNextTransition(((SSSSStrategy)ttfs.getStrategy()).
813                                                getMoveToSourceProcess(p, sp, ssSource, ssDest, db, si, ttfs));
814                                    }
815                                }
816                            }
817                        });
818                    }
819    
820                    fs.setComponent(jpForm);
821                }
822            };
823    
824            sssssMoveStrategy = ((sssssMoveStrategy != null) ? (sssssMoveStrategy) : (new SSSSStrategy()));
825    
826            return new TwoTableFormSheet(sCaption, fscc, uigGate, sssssMoveStrategy);
827        }
828    
829        /**
830         * Create and return a new TwoTableFormSheet where source and destination are StoringStocks.
831         *
832         * <p>Calls the appropriate fully parameterized function, passing <code>null</code> for the missing
833         * parameters.</p>
834         *
835         * @param sCaption the caption of the FormSheet.
836         * @param ssSource the source Stock.
837         * @param ssDest the destination Stock.
838         * @param db the DataBasket relative to which to perform all operations.
839         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
840         * {@link #setGate set} before actually using the FormSheet.
841         * @param direction the direction in which the move operation (from source to destination) should be performed
842         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
843         */
844        public static TwoTableFormSheet create(String sCaption, StoringStock ssSource, StoringStock ssDest,
845                DataBasket db, UIGate uigGate, int direction) {
846    
847            return create(sCaption, ssSource, ssDest, db, uigGate, null, null, null, null, null, direction);
848        }
849    
850        // 3. CountingStock -> DataBasket
851    
852        /**
853         * Create and return a new TwoTableFormSheet where the source is a CountingStock and the destination is a
854         * DataBasket.
855         *
856         * <p>There will be an input line where the user can specify how many items to move with the next action.
857         * </p>
858         *
859         * @param sCaption the caption of the FormSheet.
860         * @param csSource the source Stock.
861         * @param dbDest the destination DataBasket.
862         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
863         * {@link #setGate set} before actually using the FormSheet.
864         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be the
865         * keys of the individual items. If <code>null</code> the ordering will be the natural ordering of the keys.
866         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
867         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
868         * secondary keys.
869         * @param dbegDest a {@link DataBasketEntryGrouper} defining the representation of the DataBasketEntries at the
870         * right JDataBasketTable.
871         * @param fShowZeros if false, source lines containing '0' in the &quot;Count&quot; column will be hidden.
872         * @param tedSource a TableEntryDescriptor that can split individual
873         * {@link data.swing.CountingStockTableModel.Record CountingStockTableModel records} into a table's cells. It will be
874         * used for the source table. If <code>null</code> and <code>csSource</code> is a {@link MoneyBag} it
875         * defaults to a {@link DefaultMoneyBagItemTED} using <code>csSource.getCatalog()</code> to format values.
876         * Otherwise, it defaults to a {@link DefaultCountingStockItemTED}.
877         * @param tedDest a TableEntryDescriptor that can split individual {@link DataBasketEntry DataBasketEntries}
878         * into a table's cells. It will be used for the destination table. If <code>null</code>  it defaults to a
879         * {@link DefaultCountingStockDBETableEntryDescriptor}.
880         * @param csdbsMoveStrategy the strategy to be used when moving items between source and destination. If
881         * <code>null</code>, defaults to a {@link CSDBStrategy} object.
882         * @param direction the direction in which the move operation (from source to destination) should be performed
883         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
884         */
885        public static TwoTableFormSheet create(String sCaption, final CountingStock csSource,
886                final DataBasket dbDest, UIGate uigGate, final Comparator<CatalogItem> cmpSource, final Comparator<DataBasketEntry> cmpDest,
887                final DataBasketEntryGrouper dbegDest, final boolean fShowZeros,
888                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
889                CSDBStrategy csdbsMoveStrategy, final int direction) {
890    
891            FormSheetContentCreator fscc = new FormSheetContentCreator() {
892                            private static final long serialVersionUID = -5795620030475564035L;
893    
894                            protected void createFormSheetContent(FormSheet fs) {
895                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
896    
897                    final int[] anCounter = {
898                            1};
899    
900                    JCountingStockTable jcstSource = new JCountingStockTable(csSource, dbDest, cmpSource,
901                            fShowZeros,
902                            ((tedSource != null) ? (tedSource) : ((csSource instanceof MoneyBag) ?
903                            (new DefaultMoneyBagItemTED((data.Currency)csSource.getCatalog(dbDest))) :
904                            (new DefaultCountingStockItemTED()))));
905                    jcstSource.setSelectionObserver(ttfs.m_anLeftSelection);
906                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jcstSource.
907                            getModel();
908    
909                    ttfs.m_atmLeftModel = atmSource;
910                    ttfs.m_leftTable = jcstSource;
911                    ttfs.m_leftSource = csSource;
912                    ttfs.m_db = dbDest;
913    
914                    JDataBasketTable jdbtDest = new JDataBasketTable(dbDest,
915                            ((csSource instanceof AbstractStockFilter) ?
916                            DataBasketConditionImpl.allStockItemsWithSource(((AbstractStockFilter)csSource).
917                            getMainStock()) : DataBasketConditionImpl.allStockItemsWithSource(csSource)),
918                            ((dbegDest != null) ? (dbegDest) : (new CountingStockDBEGrouper())), cmpDest,
919                            ((tedDest != null) ? (tedDest) : (new DefaultCountingStockDBETableEntryDescriptor())));
920                    jdbtDest.setSelectionObserver(ttfs.m_anRightSelection);
921                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jdbtDest.
922                            getModel();
923    
924                    ttfs.m_atmRightModel = atmDest;
925                    ttfs.m_rightTable = jdbtDest;
926                    ttfs.m_rightSource = dbDest;
927    
928                    JTextField jtf = new JIntInput(anCounter, 1, 1, Integer.MAX_VALUE);
929                    
930                    JButton jbRight = createMoveButton("right", direction);
931                    JButton jbLeft = createMoveButton("left", direction);
932                    JPanel jpForm = createForm(jbRight, jbLeft, jtf, jcstSource, jdbtDest, ttfs, direction);                
933    
934          /*          JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
935                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
936    
937                    JPanel jpForm = new JPanel();
938                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
939    
940                    jpForm.add(new JScrollPane(jcstSource));
941    
942                    jpForm.add(createCentralBox(jbRight, jbLeft, jtf, ttfs.getStrategy()));
943    
944                    jpForm.add(new JScrollPane(jdbtDest));*/
945    
946                    if (ttfs.getStrategy().canMoveToDest()) {
947                        jbRight.addActionListener(new ActionActionListener(fs) {
948                                                    private static final long serialVersionUID = 4471703500502108028L;
949    
950                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
951                                CountingStockTableModel.Record r = (CountingStockTableModel.Record)atmSource.
952                                        getRecord(ttfs.m_anLeftSelection[0]);
953    
954                                if (r != null) {
955                                    UIGate uig = ttfs.getGate();
956                                    if (uig != null) {
957                                        uig.setNextTransition(((CSDBStrategy)ttfs.getStrategy()).
958                                                getMoveToDestProcess(p, sp, csSource, dbDest, r.getDescriptor(),
959                                                anCounter[0], ttfs));
960                                    }
961                                }
962                            }
963                        });
964                    }
965    
966                    if (ttfs.getStrategy().canMoveToSource()) {
967                        jbLeft.addActionListener(new ActionActionListener(fs) {
968                                                    private static final long serialVersionUID = -5007638342896652663L;
969    
970                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
971                                DataBasketEntry dbe = (DataBasketEntry)atmDest.getRecord(ttfs.m_anRightSelection[
972                                        0]);
973    
974                                if (dbe != null) {
975                                    UIGate uig = ttfs.getGate();
976                                    if (uig != null) {
977                                        uig.setNextTransition(((CSDBStrategy)ttfs.getStrategy()).
978                                                getMoveToSourceProcess(p, sp, csSource, dbDest, dbe, anCounter[0],
979                                                ttfs));
980                                    }
981                                }
982                            }
983                        });
984                    }
985    
986                    fs.setComponent(jpForm);
987                }
988            };
989    
990            csdbsMoveStrategy = ((csdbsMoveStrategy != null) ? (csdbsMoveStrategy) : (new CSDBStrategy()));
991    
992            return new TwoTableFormSheet(sCaption, fscc, uigGate, csdbsMoveStrategy);
993        }
994    
995        /**
996         * Create and return a new TwoTableFormSheet where the source is a CountingStock and the destination is a
997         * DataBasket.
998         *
999         * <p>There will be an input line where the user can specify how many items to move with the next action.
1000         * </p>
1001         *
1002         * @param sCaption the caption of the FormSheet.
1003         * @param csSource the source Stock.
1004         * @param dbDest the destination DataBasket.
1005         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1006         * {@link #setGate set} before actually using the FormSheet.
1007         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be the
1008         * keys of the individual items. If <code>null</code> the ordering will be the natural ordering of the keys.
1009         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1010         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1011         * secondary keys.
1012         * @param fShowZeros if false, source lines containing '0' in the &quot;Count&quot; column will be hidden.
1013         * @param tedSource a TableEntryDescriptor that can split individual
1014         * {@link data.swing.CountingStockTableModel.Record CountingStockTableModel records} into a table's cells. It will be
1015         * used for the source table. If <code>null</code> and <code>csSource</code> is a {@link MoneyBag} it
1016         * defaults to a {@link DefaultMoneyBagItemTED} using <code>csSource.getCatalog()</code> to format values.
1017         * Otherwise, it defaults to a {@link DefaultCountingStockItemTED}.
1018         * @param tedDest a TableEntryDescriptor that can split individual {@link DataBasketEntry DataBasketEntries}
1019         * into a table's cells. It will be used for the destination table. If <code>null</code>  it defaults to a
1020         * {@link DefaultCountingStockDBETableEntryDescriptor}.
1021         * @param csdbsMoveStrategy the strategy to be used when moving items between source and destination. If
1022         * <code>null</code>, defaults to a {@link CSDBStrategy} object.
1023         * @param direction the direction in which the move operation (from source to destination) should be performed
1024         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1025         */
1026        public static TwoTableFormSheet create(String sCaption, final CountingStock csSource,
1027                final DataBasket dbDest, UIGate uigGate, final Comparator<CatalogItem> cmpSource, final Comparator<DataBasketEntry> cmpDest,
1028                final boolean fShowZeros, final TableEntryDescriptor tedSource,
1029                final TableEntryDescriptor tedDest, CSDBStrategy csdbsMoveStrategy, int direction) {
1030            return create(sCaption, csSource, dbDest, uigGate, cmpSource, cmpDest, null, fShowZeros, tedSource,
1031                    tedDest, csdbsMoveStrategy, direction);
1032        }
1033    
1034        /**
1035         * Create and return a new TwoTableFormSheet where the source is a CountingStocks and the destination is a
1036         * DataBasket.
1037         *
1038         * <p>Calls the appropriate fully parameterized function, passing default values (i.e. <code>null</code> or
1039         * false) for the missing parameters.</p>
1040         *
1041         * @param sCaption the caption of the FormSheet.
1042         * @param csSource the source Stock.
1043         * @param dbDest the destination DataBasket.
1044         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1045         * {@link #setGate set} before actually using the FormSheet.
1046         * @param direction the direction in which the move operation (from source to destination) should be performed
1047         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1048         */
1049        public static TwoTableFormSheet create(String sCaption, CountingStock csSource, DataBasket dbDest,
1050                UIGate uigGate, int direction) {
1051            return create(sCaption, csSource, dbDest, uigGate, null, null, null, false, null, null, null, direction);
1052        }
1053    
1054        // 4. DataBasket -> CountingStock
1055    
1056        /**
1057         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
1058         * CountingStock.
1059         *
1060         * <p>There will be an input line where the user can specify how many items to move with the next action.
1061         * </p>
1062         *
1063         * @param sCaption the caption of the FormSheet.
1064         * @param dbSource the source DataBasket.
1065         * @param csDest the destination Stock.
1066         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1067         * {@link #setGate set} before actually using the FormSheet.
1068         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be
1069         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1070         * secondary keys.
1071         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1072         * the keys of the individual items. If <code>null</code> the ordering will be the natural ordering of the
1073         * keys.
1074         * @param dbegSource a {@link DataBasketEntryGrouper} defining the representation of the DataBasketEntries at the
1075         * left JDataBasketTable.
1076         * @param fShowZeros if false, destination lines containing '0' in the &quot;Count&quot; column will be
1077         * hidden.
1078         * @param tedSource a TableEntryDescriptor that can split individual
1079         * {@link DataBasketEntry DataBasketEntries} into a table's cells. It will be used for the source table.
1080         * If <code>null</code>  it defaults to a {@link DefaultCountingStockDBETableEntryDescriptor}.
1081         * @param tedDest a TableEntryDescriptor that can split individual
1082         * {@link data.swing.CountingStockTableModel.Record CountingStockTableModel records} into a table's cells. It will be
1083         * used for the destination table. If <code>null</code> and <code>csDest</code> is a {@link MoneyBag} it
1084         * defaults to a {@link DefaultMoneyBagItemTED} using <code>csDest.getCatalog()</code> to format values.
1085         * Otherwise, it defaults to a {@link DefaultCountingStockItemTED}.
1086         * @param dbcssMoveStrategy the strategy to be used when moving items between source and destination. If
1087         * <code>null</code>, defaults to a {@link DBCSStrategy} object.
1088         * @param direction the direction in which the move operation (from source to destination) should be performed
1089         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1090         */
1091        public static TwoTableFormSheet create(String sCaption, final DataBasket dbSource,
1092                final CountingStock csDest, UIGate uigGate, final Comparator<DataBasketEntry> cmpSource, final Comparator<CatalogItem> cmpDest,
1093                final DataBasketEntryGrouper dbegSource, final boolean fShowZeros,
1094                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
1095                DBCSStrategy dbcssMoveStrategy, final int direction) {
1096    
1097            FormSheetContentCreator fscc = new FormSheetContentCreator() {
1098                            private static final long serialVersionUID = -2079940405267654611L;
1099    
1100                            protected void createFormSheetContent(FormSheet fs) {
1101                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
1102    
1103                    final int[] anCounter = {
1104                            1};
1105    
1106                    JDataBasketTable jdbtSource = new JDataBasketTable(dbSource,
1107                            new DataBasketConditionImpl(DataBasketKeys.STOCK_ITEM_MAIN_KEY, null, null, null, null) {
1108                                            private static final long serialVersionUID = 1142154905328043110L;
1109    
1110                                            public boolean match(DataBasketEntry dbe) {
1111                            return (dbe.getDestination() == null);
1112                        }
1113                    }
1114    
1115                    , ((dbegSource != null) ? (dbegSource) : (new CountingStockDBEGrouper())), cmpSource,
1116                            ((tedSource != null) ? (tedSource) : (new DefaultCountingStockDBETableEntryDescriptor())));
1117                    jdbtSource.setSelectionObserver(ttfs.m_anLeftSelection);
1118                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jdbtSource.
1119                            getModel();
1120    
1121                    ttfs.m_atmLeftModel = atmSource;
1122                    ttfs.m_leftTable = jdbtSource;
1123                    ttfs.m_leftSource = dbSource;
1124                    ttfs.m_db = dbSource;
1125    
1126                    JCountingStockTable jcstDest = new JCountingStockTable(csDest, dbSource, cmpDest, fShowZeros,
1127                            ((tedDest != null) ? (tedDest) : ((csDest instanceof MoneyBag) ?
1128                            (new DefaultMoneyBagItemTED((data.Currency)csDest.getCatalog(dbSource))) :
1129                            (new DefaultCountingStockItemTED()))));
1130                    jcstDest.setSelectionObserver(ttfs.m_anRightSelection);
1131                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jcstDest.
1132                            getModel();
1133    
1134                    ttfs.m_atmRightModel = atmDest;
1135                    ttfs.m_rightTable = jcstDest;
1136                    ttfs.m_rightSource = csDest;
1137    
1138                    JTextField jtf = new JIntInput(anCounter, 1, 1, Integer.MAX_VALUE);
1139                    
1140                    JButton jbRight = createMoveButton("right", direction);
1141                    JButton jbLeft = createMoveButton("left", direction);
1142                    JPanel jpForm = createForm(jbRight, jbLeft, jtf, jdbtSource, jcstDest, ttfs, direction);                
1143    /*
1144                    JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
1145                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
1146    
1147                    JPanel jpForm = new JPanel();
1148                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
1149    
1150                    jpForm.add(new JScrollPane(jdbtSource));
1151    
1152                    jpForm.add(createCentralBox(jbRight, jbLeft, jtf, ttfs.getStrategy()));
1153    
1154                    jpForm.add(new JScrollPane(jcstDest));*/
1155    
1156                    if (ttfs.getStrategy().canMoveToDest()) {
1157                        jbRight.addActionListener(new ActionActionListener(fs) {
1158                                                    private static final long serialVersionUID = -8588835240056512061L;
1159    
1160                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1161                                DataBasketEntry dbe = (DataBasketEntry)atmSource.getRecord(ttfs.m_anLeftSelection[
1162                                        0]);
1163    
1164                                if (dbe != null) {
1165                                    UIGate uig = ttfs.getGate();
1166                                    if (uig != null) {
1167                                        uig.setNextTransition(((DBCSStrategy)ttfs.getStrategy()).
1168                                                getMoveToDestProcess(p, sp, dbSource, csDest, dbe, anCounter[0],
1169                                                ttfs));
1170                                    }
1171                                }
1172                            }
1173                        });
1174                    }
1175    
1176                    if (ttfs.getStrategy().canMoveToSource()) {
1177                        jbLeft.addActionListener(new ActionActionListener(fs) {
1178                                                    private static final long serialVersionUID = 5431271030825698400L;
1179    
1180                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1181                                CountingStockTableModel.Record r = (CountingStockTableModel.Record)atmDest.
1182                                        getRecord(ttfs.m_anRightSelection[0]);
1183    
1184                                if (r != null) {
1185                                    UIGate uig = ttfs.getGate();
1186                                    if (uig != null) {
1187                                        uig.setNextTransition(((DBCSStrategy)ttfs.getStrategy()).
1188                                                getMoveToSourceProcess(p, sp, dbSource, csDest, r.getDescriptor(),
1189                                                anCounter[0], ttfs));
1190                                    }
1191                                }
1192                            }
1193                        });
1194                    }
1195    
1196                    fs.setComponent(jpForm);
1197                }
1198            };
1199    
1200            dbcssMoveStrategy = ((dbcssMoveStrategy != null) ? (dbcssMoveStrategy) : (new DBCSStrategy()));
1201    
1202            return new TwoTableFormSheet(sCaption, fscc, uigGate, dbcssMoveStrategy);
1203        }
1204    
1205        /**
1206         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
1207         * CountingStock.
1208         *
1209         * <p>There will be an input line where the user can specify how many items to move with the next action.
1210         * </p>
1211         *
1212         * @param sCaption the caption of the FormSheet.
1213         * @param dbSource the source DataBasket.
1214         * @param csDest the destination Stock.
1215         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1216         * {@link #setGate set} before actually using the FormSheet.
1217         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be
1218         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1219         * secondary keys.
1220         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1221         * the keys of the individual items. If <code>null</code> the ordering will be the natural ordering of the
1222         * keys.
1223         * @param fShowZeros if false, destination lines containing '0' in the &quot;Count&quot; column will be
1224         * hidden.
1225         * @param tedSource a TableEntryDescriptor that can split individual
1226         * {@link DataBasketEntry DataBasketEntries} into a table's cells. It will be used for the source table.
1227         * If <code>null</code>  it defaults to a {@link DefaultCountingStockDBETableEntryDescriptor}.
1228         * @param tedDest a TableEntryDescriptor that can split individual
1229         * {@link data.swing.CountingStockTableModel.Record CountingStockTableModel records} into a table's cells. It will be
1230         * used for the destination table. If <code>null</code> and <code>csDest</code> is a {@link MoneyBag} it
1231         * defaults to a {@link DefaultMoneyBagItemTED} using <code>csDest.getCatalog()</code> to format values.
1232         * Otherwise, it defaults to a {@link DefaultCountingStockItemTED}.
1233         * @param dbcssMoveStrategy the strategy to be used when moving items between source and destination. If
1234         * <code>null</code>, defaults to a {@link DBCSStrategy} object.
1235         * @param direction the direction in which the move operation (from source to destination) should be performed
1236         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1237         */
1238        public static TwoTableFormSheet create(String sCaption, final DataBasket dbSource,
1239                final CountingStock csDest, UIGate uigGate, final Comparator<DataBasketEntry> cmpSource, final Comparator<CatalogItem> cmpDest,
1240                final boolean fShowZeros, final TableEntryDescriptor tedSource,
1241                final TableEntryDescriptor tedDest, DBCSStrategy dbcssMoveStrategy, int direction) {
1242            return create(sCaption, dbSource, csDest, uigGate, cmpSource, cmpDest, null, fShowZeros, tedSource,
1243                    tedDest, dbcssMoveStrategy, direction);
1244        }
1245    
1246        /**
1247         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
1248         * CountingStock.
1249         *
1250         * <p>Calls the appropriate fully parameterized function, passing default values (i.e. <code>null</code> or
1251         * false) for the missing parameters.</p>
1252         *
1253         * @param sCaption the caption of the FormSheet.
1254         * @param dbSource the source DataBasket.
1255         * @param csDest the destination Stock.
1256         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1257         * {@link #setGate set} before actually using the FormSheet.
1258         * @param direction the direction in which the move operation (from source to destination) should be performed
1259         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1260         */
1261        public static TwoTableFormSheet create(String sCaption, DataBasket dbSource, CountingStock csDest,
1262                UIGate uigGate, int direction) {
1263            return create(sCaption, dbSource, csDest, uigGate, null, null, null, false, null, null, null, direction);
1264        }
1265    
1266        // 5. StoringStock -> DataBasket
1267    
1268        /**
1269         * Create and return a new TwoTableFormSheet where the source is a StoringStock and the destination is a
1270         * DataBasket.
1271         *
1272         * @param sCaption the caption of the FormSheet.
1273         * @param ssSource the source Stock.
1274         * @param dbDest the destination DataBasket.
1275         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1276         * {@link #setGate set} before actually using the FormSheet.
1277         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be the
1278         * individual items. If <code>null</code> the ordering will be the natural ordering of the items.
1279         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1280         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1281         * secondary keys.
1282         * @param dbegDest a {@link DataBasketEntryGrouper} defining the representation of the DataBasketEntries at the
1283         * right JDataBasketTable.
1284         * @param tedSource a TableEntryDescriptor that can split individual {@link StockItem StockItems} into a
1285         * table's cells. It will be used for the source table. If <code>null</code> it defaults to a
1286         * {@link DefaultStockItemTED}.
1287         * @param tedDest a TableEntryDescriptor that can split individual {@link DataBasketEntry DataBasketEntries}
1288         * into a table's cells. It will be used for the destination table. If <code>null</code>  it defaults to a
1289         * {@link DefaultStoringStockDBETableEntryDescriptor}.
1290         * @param ssdbsMoveStrategy the strategy to be used when moving items between source and destination. If
1291         * <code>null</code>, defaults to a {@link SSDBStrategy} object.
1292         * @param direction the direction in which the move operation (from source to destination) should be performed
1293         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1294         */
1295        public static TwoTableFormSheet create(String sCaption, final StoringStock ssSource,
1296                final DataBasket dbDest, UIGate uigGate, final Comparator<StockItem> cmpSource, final Comparator<DataBasketEntry> cmpDest,
1297                final DataBasketEntryGrouper dbegDest, final TableEntryDescriptor tedSource,
1298                final TableEntryDescriptor tedDest, SSDBStrategy ssdbsMoveStrategy, final int direction) {
1299            FormSheetContentCreator fscc = new FormSheetContentCreator() {
1300                            private static final long serialVersionUID = -4435653161479409701L;
1301    
1302                            protected void createFormSheetContent(FormSheet fs) {
1303                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
1304    
1305                    JStoringStockTable jsstSource = new JStoringStockTable(ssSource, dbDest, cmpSource,
1306                            ((tedSource != null) ? (tedSource) : (new DefaultStockItemTED())));
1307                    jsstSource.setSelectionObserver(ttfs.m_anLeftSelection);
1308                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jsstSource.
1309                            getModel();
1310    
1311                    ttfs.m_atmLeftModel = atmSource;
1312                    ttfs.m_leftTable = jsstSource;
1313                    ttfs.m_leftSource = ssSource;
1314                    ttfs.m_db = dbDest;
1315    
1316                    JDataBasketTable jdbtDest = new JDataBasketTable(dbDest,
1317                            ((ssSource instanceof AbstractStockFilter) ?
1318                            DataBasketConditionImpl.allStockItemsWithSource(((AbstractStockFilter)ssSource).
1319                            getMainStock()) : DataBasketConditionImpl.allStockItemsWithSource(ssSource)),
1320                            ((dbegDest != null) ? (dbegDest) : (NOPDataBasketEntryGrouper.NO_GROUPS)), cmpDest,
1321                            ((tedDest != null) ? (tedDest) : (new DefaultStoringStockDBETableEntryDescriptor())));
1322                    jdbtDest.setSelectionObserver(ttfs.m_anRightSelection);
1323                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jdbtDest.
1324                            getModel();
1325    
1326                    ttfs.m_atmRightModel = atmDest;
1327                    ttfs.m_rightTable = jdbtDest;
1328                    ttfs.m_rightSource = dbDest;
1329                    
1330                    JButton jbRight = createMoveButton("right", direction);
1331                    JButton jbLeft = createMoveButton("left", direction);
1332                    JPanel jpForm = createForm(jbRight, jbLeft, null, jsstSource, jdbtDest, ttfs, direction);                
1333                    
1334    /*
1335                    JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
1336                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
1337    
1338                    JPanel jpForm = new JPanel();
1339                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
1340    
1341                    jpForm.add(new JScrollPane(jsstSource));
1342    
1343                    jpForm.add(createCentralBox(jbRight, jbLeft, null, ttfs.getStrategy()));
1344    
1345                    jpForm.add(new JScrollPane(jdbtDest));*/
1346    
1347                    if (ttfs.getStrategy().canMoveToDest()) {
1348                        jbRight.addActionListener(new ActionActionListener(fs) {
1349                                                    private static final long serialVersionUID = -6327031877893874831L;
1350    
1351                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1352                                final StockItem si = (StockItem)atmSource.getRecord(ttfs.m_anLeftSelection[0]);
1353    
1354                                if (si != null) {
1355                                    UIGate uig = ttfs.getGate();
1356                                    if (uig != null) {
1357                                        uig.setNextTransition(((SSDBStrategy)ttfs.getStrategy()).
1358                                                getMoveToDestProcess(p, sp, ssSource, dbDest, si, ttfs));
1359                                    }
1360                                }
1361                            }
1362                        });
1363                    }
1364    
1365                    if (ttfs.getStrategy().canMoveToSource()) {
1366                        jbLeft.addActionListener(new ActionActionListener(fs) {
1367                                                    private static final long serialVersionUID = -361676770169467572L;
1368    
1369                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1370                                final DataBasketEntry dbe = (DataBasketEntry)atmDest.getRecord(ttfs.
1371                                        m_anRightSelection[0]);
1372    
1373                                if (dbe != null) {
1374                                    UIGate uig = ttfs.getGate();
1375                                    if (uig != null) {
1376                                        uig.setNextTransition(((SSDBStrategy)ttfs.getStrategy()).
1377                                                getMoveToSourceProcess(p, sp, ssSource, dbDest, dbe, ttfs));
1378                                    }
1379                                }
1380                            }
1381                        });
1382                    }
1383    
1384                    fs.setComponent(jpForm);
1385                }
1386            };
1387    
1388            ssdbsMoveStrategy = ((ssdbsMoveStrategy != null) ? (ssdbsMoveStrategy) : (new SSDBStrategy()));
1389    
1390            return new TwoTableFormSheet(sCaption, fscc, uigGate, ssdbsMoveStrategy);
1391        }
1392    
1393        /**
1394         * Create and return a new TwoTableFormSheet where the source is a StoringStock and the destination is a
1395         * DataBasket.
1396         *
1397         * @param sCaption the caption of the FormSheet.
1398         * @param ssSource the source Stock.
1399         * @param dbDest the destination DataBasket.
1400         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1401         * {@link #setGate set} before actually using the FormSheet.
1402         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be the
1403         * individual items. If <code>null</code> the ordering will be the natural ordering of the items.
1404         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1405         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1406         * secondary keys.
1407         * @param tedSource a TableEntryDescriptor that can split individual {@link StockItem StockItems} into a
1408         * table's cells. It will be used for the source table. If <code>null</code> it defaults to a
1409         * {@link DefaultStockItemTED}.
1410         * @param tedDest a TableEntryDescriptor that can split individual {@link DataBasketEntry DataBasketEntries}
1411         * into a table's cells. It will be used for the destination table. If <code>null</code>  it defaults to a
1412         * {@link DefaultStoringStockDBETableEntryDescriptor}.
1413         * @param ssdbsMoveStrategy the strategy to be used when moving items between source and destination. If
1414         * <code>null</code>, defaults to a {@link SSDBStrategy} object.
1415         * @param direction the direction in which the move operation (from source to destination) should be performed
1416         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1417         */
1418        public static TwoTableFormSheet create(String sCaption, final StoringStock ssSource,
1419                final DataBasket dbDest, UIGate uigGate, final Comparator<StockItem> cmpSource, final Comparator<DataBasketEntry> cmpDest,
1420                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
1421                SSDBStrategy ssdbsMoveStrategy, int direction) {
1422            return create(sCaption, ssSource, dbDest, uigGate, cmpSource, cmpDest, null, tedSource, tedDest,
1423                    ssdbsMoveStrategy, direction);
1424        }
1425    
1426        /**
1427         * Create and return a new TwoTableFormSheet where the source is a StoringStock and the destination is a
1428         * DataBasket.
1429         *
1430         * <p>Calls the appropriate fully parameterized function, passing <code>null</code> for the missing
1431         * parameters.</p>
1432         *
1433         * @param sCaption the caption of the FormSheet.
1434         * @param ssSource the source Stock.
1435         * @param dbDest the destination DataBasket.
1436         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1437         * {@link #setGate set} before actually using the FormSheet.
1438         * @param direction the direction in which the move operation (from source to destination) should be performed
1439         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1440         */
1441        public static TwoTableFormSheet create(String sCaption, StoringStock ssSource, DataBasket dbDest,
1442                UIGate uigGate, int direction) {
1443            return create(sCaption, ssSource, dbDest, uigGate, null, null, null, null, null, null, direction);
1444        }
1445    
1446        // 6. DataBasket -> StoringStock
1447    
1448        /**
1449         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
1450         * StoringStock.
1451         *
1452         * @param sCaption the caption of the FormSheet.
1453         * @param dbSource the source DataBasket.
1454         * @param ssDest the destination Stock.
1455         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1456         * {@link #setGate set} before actually using the FormSheet.
1457         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be
1458         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1459         * secondary keys.
1460         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1461         * the individual items. If <code>null</code> the ordering will be the natural ordering of the items.
1462         * @param dbegSource a {@link DataBasketEntryGrouper} defining the representation of the DataBasketEntries at the
1463         * left JDataBasketTable.
1464         * @param tedSource a TableEntryDescriptor that can split individual
1465         * {@link DataBasketEntry DataBasketEntries} into a table's cells. It will be used for the source table. If
1466         * <code>null</code>  it defaults to a {@link DefaultStoringStockDBETableEntryDescriptor}.
1467         * @param tedDest a TableEntryDescriptor that can split individual {@link StockItem StockItems} into a
1468         * table's cells. It will be used for the destination table. If <code>null</code> it defaults to a
1469         * {@link DefaultStockItemTED}.
1470         * @param dbsssMoveStrategy the strategy to be used when moving items between source and destination. If
1471         * <code>null</code>, defaults to a {@link DBSSStrategy} object.
1472         * @param direction the direction in which the move operation (from source to destination) should be performed
1473         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1474         */
1475        public static TwoTableFormSheet create(String sCaption, final DataBasket dbSource,
1476                final StoringStock ssDest, UIGate uigGate, final Comparator<DataBasketEntry> cmpSource, final Comparator<StockItem> cmpDest,
1477                final DataBasketEntryGrouper dbegSource, final TableEntryDescriptor tedSource,
1478                final TableEntryDescriptor tedDest, DBSSStrategy dbsssMoveStrategy, final int direction) {
1479            FormSheetContentCreator fscc = new FormSheetContentCreator() {
1480                            private static final long serialVersionUID = 5765146452893400940L;
1481    
1482                            protected void createFormSheetContent(FormSheet fs) {
1483                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
1484    
1485                    JDataBasketTable jdbtSource = new JDataBasketTable(dbSource,
1486                            new DataBasketConditionImpl(DataBasketKeys.STOCK_ITEM_MAIN_KEY, null, null, null, null) {
1487                                            private static final long serialVersionUID = -5401073810821293576L;
1488    
1489                                            public boolean match(DataBasketEntry dbe) {
1490                            return (dbe.getDestination() == null);
1491                        }
1492                    }
1493    
1494                    , ((dbegSource != null) ? (dbegSource) : (NOPDataBasketEntryGrouper.NO_GROUPS)), cmpSource,
1495                            ((tedSource != null) ? (tedSource) : (new DefaultStoringStockDBETableEntryDescriptor())));
1496                    jdbtSource.setSelectionObserver(ttfs.m_anLeftSelection);
1497                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jdbtSource.
1498                            getModel();
1499    
1500                    ttfs.m_atmLeftModel = atmSource;
1501                    ttfs.m_leftTable = jdbtSource;
1502                    ttfs.m_leftSource = dbSource;
1503                    ttfs.m_db = dbSource;
1504    
1505                    JStoringStockTable jsstDest = new JStoringStockTable(ssDest, dbSource, cmpDest,
1506                            ((tedDest != null) ? (tedDest) : (new DefaultStockItemTED())));
1507                    jsstDest.setSelectionObserver(ttfs.m_anRightSelection);
1508                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jsstDest.
1509                            getModel();
1510    
1511                    ttfs.m_atmRightModel = atmDest;
1512                    ttfs.m_rightTable = jsstDest;
1513                    ttfs.m_rightSource = ssDest;
1514                    
1515                    JButton jbRight = createMoveButton("right", direction);
1516                    JButton jbLeft = createMoveButton("left", direction);
1517                    JPanel jpForm = createForm(jbRight, jbLeft, null, jdbtSource, jsstDest, ttfs, direction);                
1518                    
1519    /*
1520                    JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
1521                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
1522    
1523                    JPanel jpForm = new JPanel();
1524                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
1525    
1526                    jpForm.add(new JScrollPane(jdbtSource));
1527    
1528                    jpForm.add(createCentralBox(jbRight, jbLeft, null, ttfs.getStrategy()));
1529    
1530                    jpForm.add(new JScrollPane(jsstDest));*/
1531    
1532                    if (ttfs.getStrategy().canMoveToDest()) {
1533                        jbRight.addActionListener(new ActionActionListener(fs) {
1534                                                    private static final long serialVersionUID = 1913174881601181320L;
1535    
1536                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1537                                final DataBasketEntry dbe = (DataBasketEntry)atmSource.getRecord(ttfs.
1538                                        m_anLeftSelection[0]);
1539    
1540                                if (dbe != null) {
1541                                    UIGate uig = ttfs.getGate();
1542                                    if (uig != null) {
1543                                        uig.setNextTransition(((DBSSStrategy)ttfs.getStrategy()).
1544                                                getMoveToDestProcess(p, sp, dbSource, ssDest, dbe, ttfs));
1545                                    }
1546                                }
1547                            }
1548                        });
1549                    }
1550    
1551                    if (ttfs.getStrategy().canMoveToSource()) {
1552                        jbLeft.addActionListener(new ActionActionListener(fs) {
1553                                                    private static final long serialVersionUID = -207034683832569198L;
1554    
1555                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1556                                final StockItem si = (StockItem)atmDest.getRecord(ttfs.m_anRightSelection[0]);
1557    
1558                                if (si != null) {
1559                                    UIGate uig = ttfs.getGate();
1560                                    if (uig != null) {
1561                                        uig.setNextTransition(((DBSSStrategy)ttfs.getStrategy()).
1562                                                getMoveToSourceProcess(p, sp, dbSource, ssDest, si, ttfs));
1563                                    }
1564                                }
1565                            }
1566                        });
1567                    }
1568    
1569                    fs.setComponent(jpForm);
1570                }
1571            };
1572    
1573            dbsssMoveStrategy = ((dbsssMoveStrategy != null) ? (dbsssMoveStrategy) : (new DBSSStrategy()));
1574    
1575            return new TwoTableFormSheet(sCaption, fscc, uigGate, dbsssMoveStrategy);
1576        }
1577    
1578        /**
1579         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
1580         * StoringStock.
1581         *
1582         * @param sCaption the caption of the FormSheet.
1583         * @param dbSource the source DataBasket.
1584         * @param ssDest the destination Stock.
1585         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1586         * {@link #setGate set} before actually using the FormSheet.
1587         * @param cmpSource a comparator defining the source sorting order. The objects to be compared will be
1588         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1589         * secondary keys.
1590         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1591         * the individual items. If <code>null</code> the ordering will be the natural ordering of the items.
1592         * @param tedSource a TableEntryDescriptor that can split individual
1593         * {@link DataBasketEntry DataBasketEntries} into a table's cells. It will be used for the source table. If
1594         * <code>null</code>  it defaults to a {@link DefaultStoringStockDBETableEntryDescriptor}.
1595         * @param tedDest a TableEntryDescriptor that can split individual {@link StockItem StockItems} into a
1596         * table's cells. It will be used for the destination table. If <code>null</code> it defaults to a
1597         * {@link DefaultStockItemTED}.
1598         * @param dbsssMoveStrategy the strategy to be used when moving items between source and destination. If
1599         * <code>null</code>, defaults to a {@link DBSSStrategy} object.
1600         * @param direction the direction in which the move operation (from source to destination) should be performed
1601         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1602         */
1603        public static TwoTableFormSheet create(String sCaption, final DataBasket dbSource,
1604                final StoringStock ssDest, UIGate uigGate, final Comparator<DataBasketEntry> cmpSource, final Comparator<StockItem> cmpDest,
1605                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
1606                DBSSStrategy dbsssMoveStrategy, int direction) {
1607            return create(sCaption, dbSource, ssDest, uigGate, cmpSource, cmpDest, null, tedSource, tedDest,
1608                    dbsssMoveStrategy, direction);
1609        }
1610    
1611        /**
1612         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
1613         * StoringStock.
1614         *
1615         * <p>Calls the appropriate fully parameterized function, passing <code>null</code> for the missing
1616         * parameters.</p>
1617         *
1618         * @param sCaption the caption of the FormSheet.
1619         * @param dbSource the source DataBasket.
1620         * @param ssDest the destination Stock.
1621         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1622         * {@link #setGate set} before actually using the FormSheet.
1623         * @param direction the direction in which the move operation (from source to destination) should be performed
1624         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1625         */
1626        public static TwoTableFormSheet create(String sCaption, DataBasket dbSource, StoringStock ssDest,
1627                UIGate uigGate, int direction) {
1628            return create(sCaption, dbSource, ssDest, uigGate, null, null, null, null, null, null, direction);
1629        }
1630    
1631        // 7. Catalog -> Catalog
1632    
1633        /**
1634         * Create and return a new TwoTableFormSheet where source and destination are Catalogs.
1635         *
1636         * @param sCaption the caption of the FormSheet.
1637         * @param cSource the source Catalog.
1638         * @param cDest the destination Catalog.
1639         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1640         * {@link #setGate set} before actually using the FormSheet.
1641         * @param cmpSource a comparator defining the source sorting order. The items to be compared are
1642         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
1643         * natural ordering.
1644         * @param cmpDest a comparator defining the destination sorting order. The items to be compared are
1645         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
1646         * natural ordering.
1647         * @param tedSource a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
1648         * for the source table. If <code>null</code> and <code>cSource</code> is a {@link Currency} it defaults to
1649         * a {@link DefaultCurrencyItemTED} using <code>cSource</code> to format values. Otherwise, it defaults to a
1650         * {@link DefaultCatalogItemTED}.
1651         * @param tedDest a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
1652         * for the destination table. If <code>null</code> and <code>cDest</code> is a {@link Currency} it defaults
1653         * to a {@link DefaultCurrencyItemTED} using <code>cDest</code> to format values. Otherwise, it defaults to
1654         * a {@link DefaultCatalogItemTED}.
1655         * @param ccsMoveStrategy the strategy to be used when moving items between source and destination. If
1656         * <code>null</code> it defaults to a {@link CCStrategy} object.
1657         * @param direction the direction in which the move operation (from source to destination) should be performed
1658         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1659         */
1660        public static TwoTableFormSheet create(String sCaption, final Catalog cSource, final Catalog cDest,
1661                final DataBasket db, UIGate uigGate, final Comparator<CatalogItem> cmpSource, final Comparator<CatalogItem> cmpDest,
1662                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
1663                CCStrategy ccsMoveStrategy, final int direction) {
1664            FormSheetContentCreator fscc = new FormSheetContentCreator() {
1665                            private static final long serialVersionUID = 5921766528918967555L;
1666    
1667                            protected void createFormSheetContent(FormSheet fs) {
1668                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
1669    
1670                    JCatalogTable jctSource = new JCatalogTable(cSource, db, cmpSource,
1671                            ((tedSource != null) ? (tedSource) : ((cSource instanceof data.Currency) ?
1672                            (new DefaultCurrencyItemTED((data.Currency)cSource)) : (new DefaultCatalogItemTED()))));
1673                    jctSource.setSelectionObserver(ttfs.m_anLeftSelection);
1674                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jctSource.
1675                            getModel();
1676    
1677                    ttfs.m_atmLeftModel = atmSource;
1678                    ttfs.m_leftTable = jctSource;
1679                    ttfs.m_leftSource = cSource;
1680                    ttfs.m_db = db;
1681    
1682                    JCatalogTable jctDest = new JCatalogTable(cDest, db, cmpDest,
1683                            ((tedDest != null) ? (tedDest) : ((cDest instanceof data.Currency) ?
1684                            (new DefaultCurrencyItemTED((data.Currency)cDest)) : (new DefaultCatalogItemTED()))));
1685                    jctDest.setSelectionObserver(ttfs.m_anRightSelection);
1686                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jctDest.getModel();
1687    
1688                    ttfs.m_atmRightModel = atmDest;
1689                    ttfs.m_rightTable = jctDest;
1690                    ttfs.m_rightSource = cDest;
1691                    
1692                    JButton jbRight = createMoveButton("right", direction);
1693                    JButton jbLeft = createMoveButton("left", direction);
1694                    JPanel jpForm = createForm(jbRight, jbLeft, null, jctSource, jctDest, ttfs, direction);                
1695    
1696    
1697    /*                JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
1698                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
1699    
1700                    JPanel jpForm = new JPanel();
1701                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
1702    
1703                    jpForm.add(new JScrollPane(jctSource));
1704    
1705                    jpForm.add(createCentralBox(jbRight, jbLeft, null, ttfs.getStrategy()));
1706    
1707                    jpForm.add(new JScrollPane(jctDest));*/
1708    
1709                    if (ttfs.getStrategy().canMoveToDest()) {
1710                        jbRight.addActionListener(new ActionActionListener(fs) {
1711                                                    private static final long serialVersionUID = 3141626245269084808L;
1712    
1713                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1714                                final CatalogItem ci = (CatalogItem)atmSource.getRecord(ttfs.m_anLeftSelection[0]);
1715    
1716                                if (ci != null) {
1717                                    UIGate uig = ttfs.getGate();
1718                                    if (uig != null) {
1719                                        uig.setNextTransition(((CCStrategy)ttfs.getStrategy()).
1720                                                getMoveToDestProcess(p, sp, cSource, cDest, db, ci, ttfs));
1721                                    }
1722                                }
1723                            }
1724                        });
1725                    }
1726    
1727                    if (ttfs.getStrategy().canMoveToSource()) {
1728                        jbLeft.addActionListener(new ActionActionListener(fs) {
1729                                                    private static final long serialVersionUID = -3299578886725522974L;
1730    
1731                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1732                                final CatalogItem ci = (CatalogItem)atmDest.getRecord(ttfs.m_anRightSelection[0]);
1733    
1734                                if (ci != null) {
1735                                    UIGate uig = ttfs.getGate();
1736                                    if (uig != null) {
1737                                        uig.setNextTransition(((CCStrategy)ttfs.getStrategy()).
1738                                                getMoveToSourceProcess(p, sp, cSource, cDest, db, ci, ttfs));
1739                                    }
1740                                }
1741                            }
1742                        });
1743                    }
1744    
1745                    fs.setComponent(jpForm);
1746                }
1747            };
1748    
1749            ccsMoveStrategy = ((ccsMoveStrategy != null) ? (ccsMoveStrategy) : (new CCStrategy()));
1750    
1751            return new TwoTableFormSheet(sCaption, fscc, uigGate, ccsMoveStrategy);
1752        }
1753    
1754        /**
1755         * Create and return a new TwoTableFormSheet where source and destination are Catalogs.
1756         *
1757         * <p>Calls the appropriate fully parameterized function, passing <code>null</code> for the missing
1758         * parameters.</p>
1759         *
1760         * @param sCaption the caption of the FormSheet.
1761         * @param cSource the source Catalog.
1762         * @param cDest the destination Catalog.
1763         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1764         * {@link #setGate set} before actually using the FormSheet.
1765         * @param direction the direction in which the move operation (from source to destination) should be performed
1766         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1767         */
1768        public static TwoTableFormSheet create(String sCaption, Catalog cSource, Catalog cDest, DataBasket db,
1769                UIGate uigGate, int direction) {
1770            return create(sCaption, cSource, cDest, db, uigGate, null, null, null, null, null, direction);
1771        }
1772    
1773        // 8. Catalog -> DataBasket
1774    
1775        /**
1776         * Create and return a new TwoTableFormSheet where the source is a Catalog and the destination is a
1777         * DataBasket.
1778         *
1779         * @param sCaption the caption of the FormSheet.
1780         * @param cSource the source Catalog.
1781         * @param dbDest the destination Databasket.
1782         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1783         * {@link #setGate set} before actually using the FormSheet.
1784         * @param cmpSource a comparator defining the source sorting order. The items to be compared are
1785         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
1786         * natural ordering.
1787         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1788         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1789         * secondary keys.
1790         * @param dbegDest a {@link DataBasketEntryGrouper} defining the representation of the DataBasketEntries at the
1791         * right JDataBasketTable.
1792         * @param tedSource a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
1793         * for the source table. If <code>null</code> and <code>cSource</code> is a {@link Currency} it defaults to
1794         * a {@link DefaultCurrencyItemTED} using <code>cSource</code> to format values. Otherwise, it defaults to a
1795         * {@link DefaultCatalogItemTED}.
1796         * @param tedDest a TableEntryDescriptor that can split individual {@link DataBasketEntry DataBasketEntries}
1797         * into a table's cells. It will be used for the destination table. If <code>null</code>  it defaults to a
1798         * {@link DefaultCatalogItemDBETableEntryDescriptor}.
1799         * @param cdbsMoveStrategy the strategy to be used when moving items between source and destination. If
1800         * <code>null</code> it defaults to a {@link CDBStrategy} object.
1801         * @param direction the direction in which the move operation (from source to destination) should be performed
1802         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1803         */
1804        public static TwoTableFormSheet create(String sCaption, final Catalog cSource, final DataBasket dbDest,
1805                UIGate uigGate, final Comparator<CatalogItem> cmpSource, final Comparator<DataBasketEntry> cmpDest,
1806                final DataBasketEntryGrouper dbegDest, final TableEntryDescriptor tedSource,
1807                final TableEntryDescriptor tedDest, CDBStrategy cdbsMoveStrategy, final int direction) {
1808    
1809            FormSheetContentCreator fscc = new FormSheetContentCreator() {
1810                            private static final long serialVersionUID = 406970467078360943L;
1811    
1812                            protected void createFormSheetContent(FormSheet fs) {
1813                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
1814    
1815                    JCatalogTable jctSource = new JCatalogTable(cSource, dbDest, cmpSource,
1816                            ((tedSource != null) ? (tedSource) : ((cSource instanceof data.Currency) ?
1817                            (new DefaultCurrencyItemTED((data.Currency)cSource)) : (new DefaultCatalogItemTED()))));
1818                    jctSource.setSelectionObserver(ttfs.m_anLeftSelection);
1819                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jctSource.
1820                            getModel();
1821    
1822                    ttfs.m_atmLeftModel = atmSource;
1823                    ttfs.m_leftTable = jctSource;
1824                    ttfs.m_leftSource = cSource;
1825                    ttfs.m_db = dbDest;
1826    
1827                    JDataBasketTable jdbtDest = new JDataBasketTable(dbDest,
1828                            ((cSource instanceof CatalogFilter) ?
1829                            DataBasketConditionImpl.allCatalogItemsWithSource(((CatalogFilter)cSource).
1830                            getMainCatalog()) : DataBasketConditionImpl.allCatalogItemsWithSource(cSource)),
1831                            ((dbegDest != null) ? (dbegDest) : (null)), cmpDest,
1832                            ((tedDest != null) ? (tedDest) : (new DefaultCatalogItemDBETableEntryDescriptor())));
1833                    jdbtDest.setSelectionObserver(ttfs.m_anRightSelection);
1834                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jdbtDest.
1835                            getModel();
1836    
1837                    ttfs.m_atmRightModel = atmDest;
1838                    ttfs.m_rightTable = jdbtDest;
1839                    ttfs.m_rightSource = dbDest;
1840    
1841                    JButton jbRight = createMoveButton("right", direction);
1842                    JButton jbLeft = createMoveButton("left", direction);
1843                    JPanel jpForm = createForm(jbRight, jbLeft, null, jctSource, jdbtDest, ttfs, direction);                
1844                    
1845    /*                JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
1846                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
1847    
1848                    JPanel jpForm = new JPanel();
1849                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
1850    
1851                    jpForm.add(new JScrollPane(jctSource));
1852    
1853                    jpForm.add(createCentralBox(jbRight, jbLeft, null, ttfs.getStrategy()));
1854    
1855                    jpForm.add(new JScrollPane(jdbtDest));*/
1856    
1857                    if (ttfs.getStrategy().canMoveToDest()) {
1858                        jbRight.addActionListener(new ActionActionListener(fs) {
1859                                                    private static final long serialVersionUID = 7258489945075658182L;
1860    
1861                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1862                                CatalogItem ci = (CatalogItem)atmSource.getRecord(ttfs.m_anLeftSelection[0]);
1863    
1864                                if (ci != null) {
1865                                    UIGate uig = ttfs.getGate();
1866                                    if (uig != null) {
1867                                        uig.setNextTransition(((CDBStrategy)ttfs.getStrategy()).
1868                                                getMoveToDestProcess(p, sp, cSource, dbDest, ci, ttfs));
1869                                    }
1870                                }
1871                            }
1872                        });
1873                    }
1874    
1875                    if (ttfs.getStrategy().canMoveToSource()) {
1876                        jbLeft.addActionListener(new ActionActionListener(fs) {
1877                                                    private static final long serialVersionUID = -8778627391361553525L;
1878    
1879                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
1880                                DataBasketEntry dbe = (DataBasketEntry)atmDest.getRecord(ttfs.m_anRightSelection[
1881                                        0]);
1882    
1883                                if (dbe != null) {
1884                                    CatalogItem ci = (CatalogItem)dbe.getValue();
1885    
1886                                    if (ci != null) {
1887                                        UIGate uig = ttfs.getGate();
1888                                        if (uig != null) {
1889                                            uig.setNextTransition(((CDBStrategy)ttfs.getStrategy()).
1890                                                    getMoveToSourceProcess(p, sp, cSource, dbDest, ci, ttfs));
1891                                        }
1892                                    }
1893                                }
1894                            }
1895                        });
1896                    }
1897    
1898                    fs.setComponent(jpForm);
1899                }
1900            };
1901    
1902            cdbsMoveStrategy = ((cdbsMoveStrategy != null) ? (cdbsMoveStrategy) : (new CDBStrategy()));
1903    
1904            return new TwoTableFormSheet(sCaption, fscc, uigGate, cdbsMoveStrategy);
1905        }
1906    
1907        /**
1908         * Create and return a new TwoTableFormSheet where the source is a Catalog and the destination is a
1909         * DataBasket.
1910         *
1911         * @param sCaption the caption of the FormSheet.
1912         * @param cSource the source Catalog.
1913         * @param dbDest the destination Databasket.
1914         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1915         * {@link #setGate set} before actually using the FormSheet.
1916         * @param cmpSource a comparator defining the source sorting order. The items to be compared are
1917         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
1918         * natural ordering.
1919         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
1920         * DataBasketEntries. If <code>null</code> the entries will be ordered first by their main and then by their
1921         * secondary keys.
1922         * @param tedSource a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
1923         * for the source table. If <code>null</code> and <code>cSource</code> is a {@link Currency} it defaults to
1924         * a {@link DefaultCurrencyItemTED} using <code>cSource</code> to format values. Otherwise, it defaults to a
1925         * {@link DefaultCatalogItemTED}.
1926         * @param tedDest a TableEntryDescriptor that can split individual {@link DataBasketEntry DataBasketEntries}
1927         * into a table's cells. It will be used for the destination table. If <code>null</code>  it defaults to a
1928         * {@link DefaultCatalogItemDBETableEntryDescriptor}.
1929         * @param cdbsMoveStrategy the strategy to be used when moving items between source and destination. If
1930         * <code>null</code> it defaults to a {@link CDBStrategy} object.
1931         * @param direction the direction in which the move operation (from source to destination) should be performed
1932         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1933         */
1934        public static TwoTableFormSheet create(String sCaption, final Catalog cSource, final DataBasket dbDest,
1935                UIGate uigGate, final Comparator<CatalogItem> cmpSource, final Comparator<DataBasketEntry> cmpDest,
1936                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
1937                CDBStrategy cdbsMoveStrategy, int direction) {
1938            return create(sCaption, cSource, dbDest, uigGate, cmpSource, cmpDest, null, tedSource, tedDest,
1939                    cdbsMoveStrategy, direction);
1940        }
1941    
1942        /**
1943         * Create and return a new TwoTableFormSheet where the source is a Catalog and the destination is a
1944         * DataBasket.
1945         *
1946         * <p>Calls the appropriate fully parameterized function, passing <code>null</code> for the missing
1947         * parameters.</p>
1948         *
1949         * @param sCaption the caption of the FormSheet.
1950         * @param cSource the source Catalog.
1951         * @param dbDest the destination Databasket.
1952         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1953         * {@link #setGate set} before actually using the FormSheet.
1954         * @param direction the direction in which the move operation (from source to destination) should be performed
1955         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1956         */
1957        public static TwoTableFormSheet create(String sCaption, final Catalog cSource, final DataBasket dbDest,
1958                UIGate uigGate, int direction) {
1959            return create(sCaption, cSource, dbDest, uigGate, null, null, null, null, null, null, direction);
1960        }
1961    
1962        // 9. DataBasket -> Catalog
1963    
1964        /**
1965         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
1966         * Catalog.
1967         *
1968         * @param sCaption the caption of the FormSheet.
1969         * @param dbSource the source Databasket.
1970         * @param cDest the destination Catalog.
1971         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
1972         * {@link #setGate set} before actually using the FormSheet.
1973         * @param cmpSource a comparator defining the destination sorting order. The items to be compared are
1974         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
1975         * natural ordering.
1976         * @param dbegSource a {@link DataBasketEntryGrouper} defining the representation of the DataBasketEntries at the
1977         * left JDataBasketTable.
1978         * @param tedSource a TableEntryDescriptor that can split individual
1979         * {@link DataBasketEntry DataBasketEntries} into a table's cells. It will be used for the source table.
1980         * If <code>null</code>  it defaults to a {@link DefaultCatalogItemDBETableEntryDescriptor}.
1981         * @param tedDest a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
1982         * for the destination table. If <code>null</code> and <code>cDest</code> is a {@link Currency} it defaults
1983         * to a {@link DefaultCurrencyItemTED} using <code>cDest</code> to format values. Otherwise, it defaults to
1984         * a {@link DefaultCatalogItemTED}.
1985         * @param dbcsMoveStrategy the strategy to be used when moving items between source and destination. If
1986         * <code>null</code> it defaults to a {@link DBCStrategy} object.
1987         * @param direction the direction in which the move operation (from source to destination) should be performed
1988         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
1989         */
1990        public static TwoTableFormSheet create(String sCaption, final DataBasket dbSource, final Catalog cDest,
1991                UIGate uigGate, final Comparator<DataBasketEntry> cmpSource, final Comparator<CatalogItem> cmpDest,
1992                final DataBasketEntryGrouper dbegSource, final TableEntryDescriptor tedSource,
1993                final TableEntryDescriptor tedDest, DBCStrategy dbcsMoveStrategy, final int direction) {
1994    
1995            FormSheetContentCreator fscc = new FormSheetContentCreator() {
1996                            private static final long serialVersionUID = 459826710705161118L;
1997    
1998                            protected void createFormSheetContent(FormSheet fs) {
1999                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
2000    
2001                    JDataBasketTable jdbtSource = new JDataBasketTable(dbSource,
2002                            new DataBasketConditionImpl(DataBasketKeys.CATALOG_ITEM_MAIN_KEY, null, null, null, null) {
2003                                            private static final long serialVersionUID = 4162132666448138305L;
2004    
2005                                            public boolean match(DataBasketEntry dbe) {
2006                            return (dbe.getDestination() == null);
2007                        }
2008                    }
2009    
2010                    , ((dbegSource != null) ? (dbegSource) : (null)), cmpSource,
2011                            ((tedSource != null) ? (tedSource) : (new DefaultCountingStockDBETableEntryDescriptor())));
2012                    jdbtSource.setSelectionObserver(ttfs.m_anLeftSelection);
2013                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jdbtSource.
2014                            getModel();
2015    
2016                    ttfs.m_atmLeftModel = atmSource;
2017                    ttfs.m_leftTable = jdbtSource;
2018                    ttfs.m_leftSource = dbSource;
2019                    ttfs.m_db = dbSource;
2020    
2021                    JCatalogTable jctDest = new JCatalogTable(cDest, dbSource, cmpDest,
2022                            ((tedDest != null) ? (tedDest) : ((cDest instanceof data.Currency) ?
2023                            (new DefaultCurrencyItemTED((data.Currency)cDest)) : (new DefaultCatalogItemTED()))));
2024                    jctDest.setSelectionObserver(ttfs.m_anRightSelection);
2025                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jctDest.getModel();
2026    
2027                    ttfs.m_atmRightModel = atmDest;
2028                    ttfs.m_rightTable = jctDest;
2029                    ttfs.m_leftSource = cDest;
2030    
2031                    JButton jbRight = createMoveButton("right", direction);
2032                    JButton jbLeft = createMoveButton("left", direction);
2033                    JPanel jpForm = createForm(jbRight, jbLeft, null, jdbtSource, jctDest, ttfs, direction);                
2034                    
2035                /*    
2036                    JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
2037                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
2038    
2039                    JPanel jpForm = new JPanel();
2040                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
2041    
2042                    jpForm.add(new JScrollPane(jdbtSource));
2043    
2044                    jpForm.add(createCentralBox(jbRight, jbLeft, null, ttfs.getStrategy()));
2045    
2046                    jpForm.add(new JScrollPane(jctDest));*/
2047    
2048                    if (ttfs.getStrategy().canMoveToDest()) {
2049                        jbRight.addActionListener(new ActionActionListener(fs) {
2050                                                    private static final long serialVersionUID = 8884940052850676776L;
2051    
2052                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
2053                                CatalogItem ci = (CatalogItem)((DataBasketEntry)atmSource.getRecord(ttfs.
2054                                        m_anLeftSelection[0])).getValue();
2055    
2056                                if (ci != null) {
2057                                    UIGate uig = ttfs.getGate();
2058                                    if (uig != null) {
2059                                        uig.setNextTransition(((DBCStrategy)ttfs.getStrategy()).
2060                                                getMoveToDestProcess(p, sp, dbSource, cDest, ci, ttfs));
2061                                    }
2062                                }
2063                            }
2064                        });
2065                    }
2066    
2067                    if (ttfs.getStrategy().canMoveToSource()) {
2068                        jbLeft.addActionListener(new ActionActionListener(fs) {
2069                                                    private static final long serialVersionUID = 3980373479669559911L;
2070    
2071                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
2072                                CatalogItem ci = (CatalogItem)atmDest.getRecord(ttfs.m_anRightSelection[0]);
2073    
2074                                if (ci != null) {
2075                                    UIGate uig = ttfs.getGate();
2076                                    if (uig != null) {
2077                                        uig.setNextTransition(((DBCStrategy)ttfs.getStrategy()).
2078                                                getMoveToSourceProcess(p, sp, dbSource, cDest, ci, ttfs));
2079                                    }
2080                                }
2081                            }
2082                        });
2083                    }
2084    
2085                    fs.setComponent(jpForm);
2086                }
2087            };
2088    
2089            dbcsMoveStrategy = ((dbcsMoveStrategy != null) ? (dbcsMoveStrategy) : (new DBCStrategy()));
2090    
2091            return new TwoTableFormSheet(sCaption, fscc, uigGate, dbcsMoveStrategy);
2092        }
2093    
2094        /**
2095         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
2096         * Catalog.
2097         *
2098         * @param sCaption the caption of the FormSheet.
2099         * @param dbSource the source Databasket.
2100         * @param cDest the destination Catalog.
2101         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
2102         * {@link #setGate set} before actually using the FormSheet.
2103         * @param cmpSource a comparator defining the destination sorting order. The items to be compared are
2104         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
2105         * natural ordering.
2106         * @param tedSource a TableEntryDescriptor that can split individual
2107         * {@link DataBasketEntry DataBasketEntries} into a table's cells. It will be used for the source table.
2108         * If <code>null</code>  it defaults to a {@link DefaultCatalogItemDBETableEntryDescriptor}.
2109         * @param tedDest a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
2110         * for the destination table. If <code>null</code> and <code>cDest</code> is a {@link Currency} it defaults
2111         * to a {@link DefaultCurrencyItemTED} using <code>cDest</code> to format values. Otherwise, it defaults to
2112         * a {@link DefaultCatalogItemTED}.
2113         * @param dbcsMoveStrategy the strategy to be used when moving items between source and destination. If
2114         * <code>null</code> it defaults to a {@link DBCStrategy} object.
2115         * @param direction the direction in which the move operation (from source to destination) should be performed
2116         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
2117         */
2118        public static TwoTableFormSheet create(String sCaption, final DataBasket dbSource, final Catalog cDest,
2119                UIGate uigGate, final Comparator<DataBasketEntry> cmpSource, final Comparator<CatalogItem> cmpDest,
2120                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
2121                DBCStrategy dbcsMoveStrategy, int direction) {
2122            return create(sCaption, dbSource, cDest, uigGate, cmpSource, cmpDest, null, tedSource, tedDest,
2123                    dbcsMoveStrategy, direction);
2124        }
2125    
2126        /**
2127         * Create and return a new TwoTableFormSheet where the source is a DataBasket and the destination is a
2128         * Catalog.
2129         *
2130         * <p>Calls the appropriate fully parameterized function, passing <code>null</code> for the missing
2131         * parameters.</p>
2132         *
2133         * @param sCaption the caption of the FormSheet.
2134         * @param dbSource the source Databasket.
2135         * @param cDest the destination Catalog.
2136         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
2137         * {@link #setGate set} before actually using the FormSheet.
2138         * @param direction the direction in which the move operation (from source to destination) should be performed
2139         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
2140         */
2141        public static TwoTableFormSheet create(String sCaption, DataBasket dbSource, Catalog cDest,
2142                UIGate uigGate, int direction) {
2143            return create(sCaption, dbSource, cDest, uigGate, null, null, null, null, null, null, direction);
2144        }
2145    
2146        // 10. Catalog -> StoringStock
2147    
2148        /**
2149         * Create and return a new TwoTableFormSheet where the source is a Catalog and the destination is a
2150         * StoringStock.
2151         *
2152         * @param sCaption the caption of the FormSheet.
2153         * @param cSource the source Catalog.
2154         * @param ssDest the destination Stock.
2155         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
2156         * {@link #setGate set} before actually using the FormSheet.
2157         * @param cmpSource a comparator defining the source sorting order. The items to be compared are
2158         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
2159         * natural ordering.
2160         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
2161         * the individual items. If <code>null</code> the ordering will be the natural ordering of the items.
2162         * @param tedSource a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
2163         * for the source table. If <code>null</code> and <code>cSource</code> is a {@link Currency} it defaults to
2164         * a {@link DefaultCurrencyItemTED} using <code>cSource</code> to format values. Otherwise, it defaults to a
2165         * {@link DefaultCatalogItemTED}.
2166         * @param tedDest a TableEntryDescriptor that can split individual {@link StockItem StockItems} into a
2167         * table's cells. It will be used for the destination table. If <code>null</code> it defaults to a
2168         * {@link DefaultStockItemTED}.
2169         * @param csssMoveStrategy the strategy to be used when moving items between source and destination.
2170         * <strong>Attention</strong>: Must not be <code>null</code>!
2171         * @param direction the direction in which the move operation (from source to destination) should be performed
2172         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
2173         */
2174        public static TwoTableFormSheet create(String sCaption, final Catalog cSource, final StoringStock ssDest,
2175                final DataBasket db, UIGate uigGate, final Comparator<CatalogItem> cmpSource, final Comparator<StockItem> cmpDest,
2176                final TableEntryDescriptor tedSource, final TableEntryDescriptor tedDest,
2177                CSSStrategy csssMoveStrategy, final int direction) { // EXCEPTION : STRATEGY MUST NOT BE NULL!!!
2178            FormSheetContentCreator fscc = new FormSheetContentCreator() {
2179                            private static final long serialVersionUID = 2334337490991839881L;
2180    
2181                            protected void createFormSheetContent(FormSheet fs) {
2182                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
2183    
2184                    JCatalogTable jctSource = new JCatalogTable(cSource, db, cmpSource,
2185                            ((tedSource != null) ? (tedSource) : ((cSource instanceof data.Currency) ?
2186                            (new DefaultCurrencyItemTED((data.Currency)cSource)) : (new DefaultCatalogItemTED()))));
2187                    jctSource.setSelectionObserver(ttfs.m_anLeftSelection);
2188                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jctSource.
2189                            getModel();
2190    
2191                    ttfs.m_atmLeftModel = atmSource;
2192                    ttfs.m_leftTable = jctSource;
2193                    ttfs.m_leftSource = cSource;
2194                    ttfs.m_db = db;
2195    
2196                    JStoringStockTable jsstDest = new JStoringStockTable(ssDest, db, cmpDest,
2197                            ((tedDest != null) ? (tedDest) : (new DefaultStockItemTED())));
2198                    jsstDest.setSelectionObserver(ttfs.m_anRightSelection);
2199                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jsstDest.
2200                            getModel();
2201    
2202                    ttfs.m_atmRightModel = atmDest;
2203                    ttfs.m_rightTable = jsstDest;
2204                    ttfs.m_rightSource = ssDest;
2205                    
2206                    JButton jbRight = createMoveButton("right", direction);
2207                    JButton jbLeft = createMoveButton("left", direction);
2208                    JPanel jpForm = createForm(jbRight, jbLeft, null, jctSource, jsstDest, ttfs, direction);                
2209                    
2210    
2211      /*              JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
2212                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
2213    
2214                    JPanel jpForm = new JPanel();
2215                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
2216    
2217                    jpForm.add(new JScrollPane(jctSource));
2218    
2219                    jpForm.add(createCentralBox(jbRight, jbLeft, null, ttfs.getStrategy()));
2220    
2221                    jpForm.add(new JScrollPane(jsstDest));*/
2222    
2223                    if (ttfs.getStrategy().canMoveToDest()) {
2224                        jbRight.addActionListener(new ActionActionListener(fs) {
2225                                                    private static final long serialVersionUID = -4160889060552520441L;
2226    
2227                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
2228                                CatalogItem ci = (CatalogItem)atmSource.getRecord(ttfs.m_anLeftSelection[0]);
2229    
2230                                if (ci != null) {
2231                                    UIGate uig = ttfs.getGate();
2232                                    if (uig != null) {
2233                                        uig.setNextTransition(((CSSStrategy)ttfs.getStrategy()).
2234                                                getMoveToDestProcess(p, sp, cSource, ssDest, db, ci, ttfs));
2235                                    }
2236                                }
2237                            }
2238                        });
2239                    }
2240    
2241                    if (ttfs.getStrategy().canMoveToSource()) {
2242                        jbLeft.addActionListener(new ActionActionListener(fs) {
2243                                                    private static final long serialVersionUID = 8908544965167249317L;
2244    
2245                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
2246                                StockItem si = (StockItem)atmDest.getRecord(ttfs.m_anRightSelection[0]);
2247    
2248                                if (si != null) {
2249                                    UIGate uig = ttfs.getGate();
2250                                    if (uig != null) {
2251                                        uig.setNextTransition(((CSSStrategy)ttfs.getStrategy()).
2252                                                getMoveToSourceProcess(p, sp, cSource, ssDest, db, si, ttfs));
2253                                    }
2254                                }
2255                            }
2256                        });
2257                    }
2258    
2259                    fs.setComponent(jpForm);
2260                }
2261            };
2262    
2263            return new TwoTableFormSheet(sCaption, fscc, uigGate, csssMoveStrategy);
2264        }
2265    
2266        /**
2267         * Create and return a new TwoTableFormSheet where the source is a Catalog and the destination is a
2268         * StoringStock.
2269         *
2270         * <p>Calls the appropriate fully parameterized function, passing <code>null</code> for the missing
2271         * parameters.</p>
2272         *
2273         * @param sCaption the caption of the FormSheet.
2274         * @param cSource the source Catalog.
2275         * @param ssDest the destination Stock.
2276         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
2277         * {@link #setGate set} before actually using the FormSheet.
2278         * @param csssMoveStrategy the strategy to be used when moving items between source and destination.
2279         * <strong>Attention</strong>: Must not be <code>null</code>!
2280         * @param direction the direction in which the move operation (from source to destination) should be performed
2281         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
2282         */
2283        public static TwoTableFormSheet create(String sCaption, Catalog cSource, StoringStock ssDest,
2284                DataBasket db, UIGate uigGate, CSSStrategy csssMoveStrategy, int direction) { // EXCEPTION : STRATEGY MUST NOT BE NULL!!!
2285            return create(sCaption, cSource, ssDest, db, uigGate, null, null, null, null, csssMoveStrategy, direction);
2286        }
2287    
2288        // 11. Catalog -> CountingStock
2289    
2290        /**
2291         * Create and return a new TwoTableFormSheet where the source is a Catalog and the destination is a
2292         * CountingStock.
2293         *
2294         * @param sCaption the caption of the FormSheet.
2295         * @param cSource the source Catalog.
2296         * @param csDest the destination Stock.
2297         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
2298         * {@link #setGate set} before actually using the FormSheet.
2299         * @param cmpSource a comparator defining the source sorting order. The items to be compared are
2300         * {@link CatalogItem CatalogItems}. If <code>null</code> the items will be sorted according to their
2301         * natural ordering.
2302         * @param cmpDest a comparator defining the destination sorting order. The objects to be compared will be
2303         * the keys of the individual items. If <code>null</code> the ordering will be the natural ordering of the
2304         * keys.
2305         * @param fShowZeros if false, destination lines containing '0' in the &quot;Count&quot; column will be
2306         * hidden.
2307         * @param tedSource a TableEntryDescriptor that can split CatalogItems into a table's cells. It will be used
2308         * for the source table. If <code>null</code> and <code>cSource</code> is a {@link Currency} it defaults to
2309         * a {@link DefaultCurrencyItemTED} using <code>cSource</code> to format values. Otherwise, it defaults to a
2310         * {@link DefaultCatalogItemTED}.
2311         * @param tedDest a TableEntryDescriptor that can split individual
2312         * {@link data.swing.CountingStockTableModel.Record CountingStockTableModel records} into a table's cells. It will be
2313         * used for the destination table. If <code>null</code> and <code>csDest</code> is a {@link MoneyBag} it
2314         * defaults to a {@link DefaultMoneyBagItemTED} using <code>csDest.getCatalog()</code> to format values.
2315         * Otherwise, it defaults to a {@link DefaultCountingStockItemTED}.
2316         * @param ccssMoveStrategy the strategy to be used when moving items between source and destination. If
2317         * <code>null</code>, defaults to a {@link CCSStrategy} object.
2318         * @param direction the direction in which the move operation (from source to destination) should be performed
2319         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
2320         */
2321        public static TwoTableFormSheet create(String sCaption, final Catalog cSource, final CountingStock csDest,
2322                final DataBasket db, UIGate uigGate, final Comparator<CatalogItem> cmpSource, final Comparator<CatalogItem> cmpDest,
2323                final boolean fShowZeros, final TableEntryDescriptor tedSource,
2324                final TableEntryDescriptor tedDest, CCSStrategy ccssMoveStrategy, final int direction) {
2325            FormSheetContentCreator fscc = new FormSheetContentCreator() {
2326                            private static final long serialVersionUID = 213845399196367982L;
2327    
2328                            protected void createFormSheetContent(FormSheet fs) {
2329                    final TwoTableFormSheet ttfs = (TwoTableFormSheet)fs;
2330    
2331                    final int[] anCounter = {
2332                            1};
2333    
2334                    JCatalogTable jctSource = new JCatalogTable(cSource, db, cmpSource,
2335                            ((tedSource != null) ? (tedSource) : ((cSource instanceof data.Currency) ?
2336                            (new DefaultCurrencyItemTED((data.Currency)cSource)) : (new DefaultCatalogItemTED()))));
2337                    jctSource.setSelectionObserver(ttfs.m_anLeftSelection);
2338                    final util.swing.AbstractTableModel atmSource = (util.swing.AbstractTableModel)jctSource.
2339                            getModel();
2340    
2341                    ttfs.m_atmLeftModel = atmSource;
2342                    ttfs.m_leftTable = jctSource;
2343                    ttfs.m_leftSource = cSource;
2344                    ttfs.m_db = db;
2345    
2346                    JCountingStockTable jcstDest = new JCountingStockTable(csDest, db, cmpDest, fShowZeros,
2347                            ((tedDest != null) ? (tedDest) : ((csDest instanceof MoneyBag) ?
2348                            (new DefaultMoneyBagItemTED((data.Currency)csDest.getCatalog(db))) :
2349                            (new DefaultCountingStockItemTED()))));
2350                    jcstDest.setSelectionObserver(ttfs.m_anRightSelection);
2351                    final util.swing.AbstractTableModel atmDest = (util.swing.AbstractTableModel)jcstDest.
2352                            getModel();
2353    
2354                    ttfs.m_atmRightModel = atmDest;
2355                    ttfs.m_rightTable = jcstDest;
2356                    ttfs.m_rightSource = csDest;
2357    
2358                    JTextField jtf = new JIntInput(anCounter, 1, 1, Integer.MAX_VALUE);
2359                    
2360                    JButton jbRight = createMoveButton("right", direction);
2361                    JButton jbLeft = createMoveButton("left", direction);
2362                    JPanel jpForm = createForm(jbRight, jbLeft, jtf, jctSource, jcstDest, ttfs, direction);                
2363                    
2364    
2365                  /*  JButton jbRight = new JButton(getResourceText(BUTTON_RIGHT));
2366                    JButton jbLeft = new JButton(getResourceText(BUTTON_LEFT));
2367    
2368                    JPanel jpForm = new JPanel();
2369                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
2370    
2371                    jpForm.add(new JScrollPane(jctSource));
2372    
2373                    jpForm.add(createCentralBox(jbRight, jbLeft, jtf, ttfs.getStrategy()));
2374    
2375                    jpForm.add(new JScrollPane(jcstDest));*/
2376    
2377                    if (ttfs.getStrategy().canMoveToDest()) {
2378                        jbRight.addActionListener(new ActionActionListener(fs) {
2379                            private static final long serialVersionUID = 8512187040845269111L;
2380    
2381                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
2382                                CatalogItem ci = (CatalogItem)atmSource.getRecord(ttfs.m_anLeftSelection[0]);
2383    
2384                                if (ci != null) {
2385                                    UIGate uig = ttfs.getGate();
2386                                    if (uig != null) {
2387                                        uig.setNextTransition(((CCSStrategy)ttfs.getStrategy()).
2388                                                getMoveToDestProcess(p, sp, cSource, csDest, db, ci, anCounter[0],
2389                                                ttfs));
2390                                    }
2391                                }
2392                            }
2393                        });
2394                    }
2395    
2396                    if (ttfs.getStrategy().canMoveToSource()) {
2397                        jbLeft.addActionListener(new ActionActionListener(fs) {
2398                                                    private static final long serialVersionUID = 4756376603858005686L;
2399    
2400                                                    public void doAction(SaleProcess p, final SalesPoint sp) {
2401                                CountingStockTableModel.Record r = (CountingStockTableModel.Record)atmDest.
2402                                        getRecord(ttfs.m_anRightSelection[0]);
2403    
2404                                if (r != null) {
2405                                    UIGate uig = ttfs.getGate();
2406                                    if (uig != null) {
2407                                        uig.setNextTransition(((CCSStrategy)ttfs.getStrategy()).
2408                                                getMoveToSourceProcess(p, sp, cSource, csDest, db,
2409                                                r.getDescriptor(), anCounter[0], ttfs));
2410                                    }
2411                                }
2412                            }
2413                        });
2414                    }
2415    
2416                    fs.setComponent(jpForm);
2417                }
2418            };
2419    
2420            ccssMoveStrategy = ((ccssMoveStrategy != null) ? (ccssMoveStrategy) : (new CCSStrategy()));
2421    
2422            return new TwoTableFormSheet(sCaption, fscc, uigGate, ccssMoveStrategy);
2423        }
2424    
2425        /**
2426         * Create and return a new TwoTableFormSheet where the source is a Catalog and the destination is a
2427         * CountingStock.
2428         *
2429         * <p>Calls the appropriate fully parameterized function, passing default values (i.e. <code>null</code> or
2430         * false) for the missing parameters.</p>
2431         *
2432         * @param sCaption the caption of the FormSheet.
2433         * @param cSource the source Catalog.
2434         * @param csDest the destination Stock.
2435         * @param uigGate the Gate at which the FormSheet will be displayed. If this is <code>null</code> it must be
2436         * {@link #setGate set} before actually using the FormSheet.
2437         * @param direction the direction in which the move operation (from source to destination) should be performed
2438         * within the gui. It can be either {@link #RIGHT}, {@link #LEFT}, {@link #DOWN} or {@link #UP}.
2439         */
2440        public static TwoTableFormSheet create(String sCaption, Catalog cSource, CountingStock csDest,
2441                DataBasket db, UIGate uigGate, int direction) {
2442            return create(sCaption, cSource, csDest, db, uigGate, null, null, false, null, null, null, direction);
2443        }
2444    
2445        // helper routines...
2446    
2447        /**
2448         * Internal helper function creating the central box with the two buttons and the input line.
2449         */
2450        private static final Box createCentralBox(JButton jbRight, JButton jbLeft, JTextField jtf,
2451                MoveStrategy ms, int direction) {
2452            Box b = Box.createVerticalBox();
2453            b.add(Box.createGlue());
2454    
2455            if (jtf != null) {
2456                jtf.setMaximumSize(new Dimension(jbRight.getMaximumSize().width * 2 - 1,
2457                        jtf.getMinimumSize().height));
2458                b.add(jtf);
2459            }
2460    
2461            JPanel btns = new JPanel(new GridLayout(1, 2));
2462            btns.setMaximumSize(new Dimension(100, 20));
2463            
2464            if (ms.canMoveToSource()) {
2465                btns.add(jbLeft);
2466            }
2467            if (ms.canMoveToDest()) {
2468                btns.add(jbRight);
2469            }
2470            
2471            b.add(btns);
2472            b.add(Box.createGlue());
2473    
2474            Box bButtonBar = Box.createHorizontalBox();
2475            bButtonBar.add(Box.createGlue());
2476            bButtonBar.add(b);
2477            bButtonBar.add(Box.createGlue());
2478    
2479            return bButtonBar;
2480        }
2481    
2482        /**
2483         * Helper method that positions all elements of the formsheet according to the given
2484         * direction. 
2485         */
2486        private static final JPanel createForm(JButton btnToDest, JButton btnToSource, JTextField jtf,
2487                                                                               JTable jtSource, JTable jtDest, TwoTableFormSheet ttfs,
2488                                                                               int direction) {
2489            JPanel jpForm = new JPanel();
2490            
2491            switch (direction) {
2492                    case RIGHT: 
2493                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
2494                    jpForm.add(new JScrollPane(jtSource));
2495                    jpForm.add(createCentralBox(btnToDest, btnToSource, jtf, ttfs.getStrategy(), direction));
2496                    jpForm.add(new JScrollPane(jtDest));
2497                    break;
2498                    case LEFT:
2499                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.X_AXIS));
2500                    jpForm.add(new JScrollPane(jtDest));
2501                    jpForm.add(createCentralBox(btnToDest, btnToSource, jtf, ttfs.getStrategy(), direction));
2502                    jpForm.add(new JScrollPane(jtSource));
2503                    break;
2504                    case UP:
2505                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.Y_AXIS));
2506                    jpForm.add(new JScrollPane(jtDest));
2507                    jpForm.add(createCentralBox(btnToDest, btnToSource, jtf, ttfs.getStrategy(), direction));
2508                    jpForm.add(new JScrollPane(jtSource));
2509                    break;
2510                    case DOWN:
2511                    jpForm.setLayout(new BoxLayout(jpForm, BoxLayout.Y_AXIS));
2512                    jpForm.add(new JScrollPane(jtSource));
2513                    jpForm.add(createCentralBox(btnToDest, btnToSource, jtf, ttfs.getStrategy(), direction));
2514                    jpForm.add(new JScrollPane(jtDest));
2515                    break;
2516            }
2517            
2518            
2519            return jpForm;
2520        }
2521        
2522        /**
2523         * Create a move button according to the given direction and the mode ("right" means from
2524         * source to destination and "left" means from destination to source container). 
2525         */
2526        private static final JButton createMoveButton(String mode, int direction) {
2527            switch (direction) {
2528                    case RIGHT:
2529                            if (mode == "right") {
2530                                    return new JButton(LEFT_ICON);
2531                            }
2532                            return new JButton(RIGHT_ICON);
2533                    case LEFT:
2534                            if (mode == "right") {
2535                                    return new JButton(RIGHT_ICON);
2536                            }
2537                            return new JButton(LEFT_ICON);
2538                    case DOWN:
2539                            if (mode == "right") {
2540                                    return new JButton(DOWN_ICON);
2541                            }
2542                            return new JButton(UP_ICON);
2543                    case UP:
2544                            if (mode == "right") {
2545                                    return new JButton(UP_ICON);
2546                            }
2547                            return new JButton(DOWN_ICON);
2548            }
2549            throw new IllegalArgumentException();
2550        }
2551        
2552        /**
2553         * Constant indicating that the destination table is to be placed left 
2554         * of the source table.
2555         */
2556        public static final int LEFT = 0;
2557        
2558        /**
2559         * Constant indicating that the destination table is to be placed right 
2560         * of the source table.
2561         */
2562        public static final int RIGHT = 1;
2563        
2564        /**
2565         * Constant indicating that the destination table is to be placed above 
2566         * the source table.
2567         */
2568        public static final int UP = 2;
2569        
2570        /**
2571         * Constant indicating that the destination table is to be placed beneath 
2572         * the source table.
2573         */
2574        public static final int DOWN = 3;
2575        
2576        /**
2577         * Icon with an arrow pointing right.
2578         */
2579        private static final ImageIcon RIGHT_ICON = new ImageIcon(ResourceManager.getInstance().getResource(
2580                ResourceManager.RESOURCE_PNG, "icon.icon_right_16x16"));
2581    
2582        /**
2583         * Icon with an arrow pointing left.
2584         */
2585        private static final ImageIcon LEFT_ICON = new ImageIcon(ResourceManager.getInstance().getResource(
2586                ResourceManager.RESOURCE_PNG, "icon.icon_left_16x16"));
2587        
2588        /**
2589         * Icon with an arrow pointing upwards.
2590         */
2591        private static final ImageIcon UP_ICON = new ImageIcon(ResourceManager.getInstance().getResource(
2592                ResourceManager.RESOURCE_PNG, "icon.icon_up_16x16"));
2593        
2594        /**
2595         * Icon with an arrow pointing downwards.
2596         */
2597        private static final ImageIcon DOWN_ICON = new ImageIcon(ResourceManager.getInstance().getResource(
2598                ResourceManager.RESOURCE_PNG, "icon.icon_down_16x16"));
2599    }