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