001    package market.stdform;
002    
003    import java.awt.GridBagConstraints;
004    import java.awt.GridBagLayout;
005    import java.awt.event.ItemEvent;
006    import java.awt.event.ItemListener;
007    import java.util.Comparator;
008    
009    import javax.swing.Box;
010    import javax.swing.BoxLayout;
011    import javax.swing.DefaultCellEditor;
012    import javax.swing.JComboBox;
013    import javax.swing.JPanel;
014    import javax.swing.JScrollPane;
015    import javax.swing.JTextField;
016    import javax.swing.event.ListSelectionEvent;
017    import javax.swing.event.ListSelectionListener;
018    import javax.swing.table.TableCellEditor;
019    
020    import market.CFilter;
021    import market.CIArticle;
022    import market.CSOffer;
023    import market.Conversions;
024    import market.SMarket;
025    import market.swing.CmpNumbers;
026    import market.swing.JTADescriptionArea;
027    import sale.FormSheet;
028    import sale.FormSheetContentCreator;
029    import util.swing.AbstractTableEntryDescriptor;
030    import util.swing.TableEntryDescriptor;
031    import data.IntegerValue;
032    import data.stdforms.SingleTableFormSheet;
033    import data.swing.CountingStockTableModel;
034    
035    /**
036     * This FormSheet displays the market's stock. The contained table allows editing of the bid
037     * when the market is closed.
038     */
039    public class FSManagerOffer {
040    
041        /**
042         * Creates a {@link SingleTableFormSheet} with some extra components. The look of the table is
043         * defined by the {@link TEDManagerOffer}.
044         *
045         * @return the created SingleTableFormSheet.
046         */
047        public static SingleTableFormSheet create() {
048            final TableEntryDescriptor ted = new TEDManagerOffer();
049            final CSOffer source = SMarket.getOffer();
050            final SingleTableFormSheet stfs = SingleTableFormSheet.create(
051                    "Bestands- und Preisübersicht",
052                    source,
053                    null,                         //UIGate
054                    true,                         //show zeros
055                    ted                           //TED
056            );
057            stfs.addContentCreator(new FormSheetContentCreator() {
058                protected void createFormSheetContent(final FormSheet fs) {
059                    JPanel jpMain = new JPanel();
060                    JPanel jpTable = new JPanel();
061                    JPanel jpFilter = new JPanel();
062                    JPanel jpTableAndFilter = new JPanel();
063                    JPanel jpDescription = new JPanel();
064                    JScrollPane jsc = new JScrollPane();
065                    GridBagConstraints c = new GridBagConstraints();
066                    GridBagLayout gridbag = new GridBagLayout();
067                    final JComboBox jcbFilter = new JComboBox(SMarket.getArticleCategories());
068                    jcbFilter.addItemListener(new ItemListener() {
069                        public void itemStateChanged(ItemEvent e) {
070                            if (e.getStateChange() == e.SELECTED) {
071                                int i = jcbFilter.getSelectedIndex();
072                                CFilter cf = new CFilter(source.getCatalog(null), i); //filter CatalogItems
073                                CSOffer cs = (CSOffer)source.clone();
074                                try {
075                                    cs.changeArticleCatalog(cf);  //make new CountingStock from
076                                }                                 //filtered CatalogItems
077                                catch (Exception ex){
078                                    ex.printStackTrace();
079                                }
080                                //send new created CountingStock to table
081                                stfs.setTableModel(new CountingStockTableModel(cs, null, null, true, ted));
082                            }
083                        }
084                    });
085                    final JTADescriptionArea da = new JTADescriptionArea();
086                    //add Listener to table that reacts on selection change
087                    stfs.getTable().getSelectionModel().addListSelectionListener(new ListSelectionListener() {
088                        public void valueChanged(ListSelectionEvent e) {
089                            if (!e.getValueIsAdjusting()) {
090                                da.setDescription(Conversions.recordToCIArticle(stfs.getSelectedRecord()));
091                            }
092                        }
093                    });
094                    jpTableAndFilter.setLayout(gridbag);
095                        c.gridx = 0;
096                        c.weightx = 1;
097                        c.weighty = 1;
098                        c.gridy = 0;
099                        c.fill = GridBagConstraints.BOTH;
100                      gridbag.setConstraints(jpTable, c);
101                        c.gridx = 1;
102                        c.weightx = 0;
103                        c.weighty = 1;
104                        c.gridy = 0;
105                        c.fill = GridBagConstraints.BOTH;
106                      gridbag.setConstraints(jpFilter, c);
107                    jpTableAndFilter.add(jpTable);
108                    jpTable.setLayout(new BoxLayout(jpTable, BoxLayout.X_AXIS));
109                    jpTable.add(fs.getComponent());
110                    jpTableAndFilter.add(jpFilter);
111                        jpFilter.add(jcbFilter);
112                    jpDescription.setLayout(new BoxLayout(jpDescription, BoxLayout.X_AXIS));
113                    jpDescription.add(jsc);
114                        jsc.setViewportView(da);
115    
116                    jpMain.setLayout(new BoxLayout(jpMain, BoxLayout.Y_AXIS));
117                    jpMain.add(jpTableAndFilter);
118                    jpMain.add(Box.createVerticalStrut(10));
119                    jpMain.add(jpDescription);
120    
121                    fs.setComponent(jpMain);
122                    fs.removeAllButtons();
123                }
124            });
125            return stfs;
126        }
127    }
128    
129    /**
130     * The {@link util.swing.TableEntryDescriptor} used by {@link FSManagerOffer}.
131     */
132    class TEDManagerOffer extends AbstractTableEntryDescriptor {
133    
134        private Comparator sortOffer = new CmpNumbers(CmpNumbers.OFFER);
135        private Comparator sortBid   = new CmpNumbers(CmpNumbers.BID);
136        private Comparator sortCount = new CmpNumbers(CmpNumbers.COUNT);
137    
138        /**
139         * @return the number of the table's columns.
140         */
141        public int getColumnCount() {
142            return 4;
143        }
144    
145        /**
146         * @param nIndex the affected column.
147         * @return columns' names.
148         */
149        public String getColumnName(int nIndex) {
150            return (new String[]{ "Artikel", "Einkaufspreis", "Verkaufspreis", "Anzahl"}) [nIndex];
151        }
152    
153        /**
154         * @param nIndex the affected column.
155         * @return columns' classes. They indicate how column's values should be aligned.
156         */
157        public Class getColumnClass  (int nIndex) {
158            return (new Class[] {String.class, Number.class, Number.class, Number.class}) [nIndex];
159        }
160    
161        /**
162         * @param oRecord the affected table record.
163         * @param nIndex the affected column.
164         * @return columns' values
165         */
166        public Object getValueAt(Object oRecord, int nIndex) {
167            CountingStockTableModel.Record stockitem = null;
168            CIArticle article = Conversions.recordToCIArticle(oRecord);
169            int count = ((CountingStockTableModel.Record)oRecord).getCount();
170            switch (nIndex) {
171                case 0: return article.getArticleName();
172                case 1: return Conversions.doubleToCurrency(article.getOffer());
173                case 2: return Conversions.doubleToCurrency(article.getBid());
174                case 3: return new Integer(count).toString();
175            }
176            return null;
177        }
178    
179        /**
180         * Determines if columns can be sorted by the user.
181         *
182         * @param nIndex the affected column.
183         * @return <ul><li>true: columns can be sorted</li>
184         *              <li>false: columns cannot be sorted</li></ul>
185         */
186        public boolean canSortByColumn(int nIndex) {
187            return true;
188        }
189    
190        /**
191         * @param nIndex the affected column.
192         * @return the {@link Comparator} to be used when sorting the column.
193         */
194        public Comparator getColumnOrder(int nIndex) {
195            switch(nIndex) {
196                case 1: return sortOffer;
197                case 2: return sortBid;
198                case 3: return sortCount;
199            }
200            return null;
201        }
202    
203        /**
204         * Determines editable columns.
205         *
206         * @param oRecord the affected table record.
207         * @param nIndex the affected column.
208         * @return <ul><li>true: column's cells are editable</li>
209         *              <li>false: column's cells are not editable</li></ul>
210         */
211        public boolean isElementEditable(Object oRecord, int nIndex) {
212            //3rd column, but only if market is not open
213            return nIndex == 2 && !SMarket.isOpen();
214        }
215    
216        /**
217         * Assigns the value to a table cell.
218         *
219         * @param oRecord the affected table record
220         * @param nIndex the affected column.
221         * @param oValue the new Object that is tried to be set as the table cell's content.
222         */
223        public void setValueAt(Object oRecord, int nIndex, Object oValue) {
224            String newValueString = Conversions.convertComma((String)oValue);
225    
226            if (newValueString != null) {
227                int newPrice = new Double(Double.parseDouble(newValueString)*100).intValue();
228                if (newPrice >= 0) {
229                    Conversions.recordToCIArticle(oRecord).setBid(new IntegerValue(newPrice));
230                }
231                SMarket.getMonthlySalesStats().get(Conversions.recordToCIArticle(oRecord).getName()).newPriceSet(
232                        SMarket.getTime(), newPrice);
233            }
234        }
235    
236        /**
237         * Sets a {@link JTextField} as the editor for the editable column.
238         *
239         * @param nIndex the affected column.
240         * @return TableCellEditor of the affected column.
241         */
242        public TableCellEditor getCellEditor(int nIndex) {
243            if (nIndex == 2) {
244                 return new DefaultCellEditor(new JTextField());
245            }
246            return null;
247        }
248    }