001    package market.stdform;
002    
003    import java.awt.Component;
004    import java.util.ArrayList;
005    import java.util.Collections;
006    import java.util.Comparator;
007    import java.util.Iterator;
008    import java.util.LinkedList;
009    import java.util.List;
010    
011    import javax.swing.JComponent;
012    import javax.swing.JPanel;
013    
014    import market.JDDShowMessage;
015    import market.swing.JTFCheckable;
016    import sale.FormSheet;
017    import sale.FormSheetContentCreator;
018    import data.stdforms.SingleTableFormSheet;
019    
020    /**
021     * This special FormSheet wraps "normal" {@link FormSheet FormSheets} and provides the possibilty to both
022     * check special {@link JTFCheckable checkable text fields} for valid entries and to retrieve those entries.
023     * Furthermore, this class generates error messages in case one or more of those special text fields
024     * contain invalid entries.
025     * However, {@link JTFCheckable checkable text fields} have already to be defined in the original
026     * FormSheet.
027     */
028    public class FSCheckable extends FormSheet implements java.io.Serializable {
029    
030        /**
031         * The original FormSheet to be wrapped.
032         */
033        private FormSheet formSheet;
034        private List checkableComponents, invalidFields;
035        public static final int NO_ERRORMESSAGE = 0;
036        public static final int FIRST_ERRORMESSAGE = 1;
037        public static final int ALL_ERRORMESSAGES_SEQUENTIALLY = 2;
038        public static final int ALL_ERRORMESSAGES_AT_ONCE = 3;
039    
040        /**
041         * Creates an empty FormSheet, sets the content and the buttons of the FormSheet
042         * which is passed as parameter as its own.
043         *
044         * @param fs the FormSheet to be wrapped.
045         */
046        public FSCheckable(FormSheet fs) {
047            super(fs.getCaption(), (JComponent)null);
048            this.formSheet = fs;
049            addContentCreator(new FormSheetContentCreator() {
050                protected void createFormSheetContent(FormSheet fsOrig) {
051                    fsOrig.setComponent(formSheet.getComponent());
052                    setButtons(getButtons());
053                }
054            });
055            invalidFields = new ArrayList();
056        }
057    
058        /**
059         * @return a List of all buttons in the {@link #formSheet formSheet's} button bar
060         */
061        public List getButtons() {
062            List buttonList = new LinkedList();
063            Iterator it = formSheet.buttonIterator(false);
064            while (it.hasNext()) {
065                buttonList.add((FormButton)it.next());
066            }
067            return buttonList;
068        }
069    
070        /**
071         * Sets buttons to the button bar.
072         *
073         * @param buttonList the list of buttons to be set.
074         */
075        public void setButtons(List buttonList) {
076            removeAllButtons();
077            Iterator it = buttonList.iterator();
078            while (it.hasNext()) {
079                addButton((FormButton)it.next());
080            }
081        }
082    
083    
084        /**
085         * @param number the ID of the desired {@link JTFCheckable}
086         * @return the text of a {@link JTFCheckable}
087         */
088        public String getEntry(int number) {
089            Object listObject = null;
090            JTFCheckable ctf = null;
091            boolean found = false;
092            checkableComponents = getCheckableComponents(getComponent());
093            Iterator it = checkableComponents.iterator();
094            while (it.hasNext() && !found) {
095                ctf = (JTFCheckable)it.next();
096                found = (ctf.getID() == number);
097            }
098            return found ? ctf.getText() : "";
099        }
100    
101        /**
102         * Checks all {@link JTFCheckable JTFCheckables} for validity entries.
103         * @param option the style of the {@link #generateErrorMessage(int, boolean) error message} to be created.
104         * @param sorted the order of the {@link #generateErrorMessage(int, boolean) error messages} to be created.
105         * @return true, if all checkable text fields contain a valid value, else false.
106         */
107        public boolean checkTextFields(int option, boolean sorted) {
108            boolean returnValue = true;
109            boolean singleValue;
110            JTFCheckable nextField = null;
111            checkableComponents = getCheckableComponents(getComponent());
112            Iterator it = checkableComponents.iterator();
113            while (it.hasNext()) {
114                nextField = (JTFCheckable)it.next();
115                if (!nextField.hasValidValue()) {
116                    returnValue = false;
117                    invalidFields.add(nextField);
118                };
119            }
120            if (!returnValue) {
121                generateErrorMessage(option, sorted);
122            }
123            invalidFields.clear();
124            return returnValue;
125        }
126    
127        /**
128         * Generates error messages for {@link JTFCheckable checkable text fields} that do not contain
129         * valid values.
130         * @param option defines style of the error message.
131         *  <ul><li>0: show no error messages</li>
132         *      <li>1: show only first error message</li>
133         *      <li>2: show all error messages sequentially</li>
134         *      <li>3: show all error messages at once</l>
135         *  </ul>
136         * @param sorted Select if the error messages should be displayed in the order the associated
137         * {@link JTFCheckable checkable text fields} have been added to the FormSheet (false)<br>
138         * or sorted by their ButtonIDs (true).
139         */
140        private void generateErrorMessage(int option, boolean sorted) {
141            List invF = sorted ? sort(invalidFields) : invalidFields;
142            Iterator it = invF.iterator();
143            JTFCheckable ctf = null;
144            switch (option) {
145                case 1:
146                    JDDShowMessage.showMessageDialog(this, ((JTFCheckable)it.next()).getErrorMessage(),
147                            "Fehlerhafte Eingabe");
148                    break;
149                case 2:
150                    while (it.hasNext()) {
151                        ctf = (JTFCheckable)it.next();
152                        JDDShowMessage.showMessageDialog(this, ctf.getErrorMessage(), "Fehlerhafte Eingabe");
153                    }
154                   break;
155                case 3:
156                    String s = "";
157                    while (it.hasNext()) {
158                        ctf = (JTFCheckable)it.next();
159                        s += "- " + ctf.getErrorMessage() + "\n";
160                    }
161                    JDDShowMessage.showMessageDialog(this, s, "Fehlerhafte Eingabe");
162                    break;
163            }
164        }
165    
166        /**
167         * Sorts a List of {@link JTFCheckable checkable text fields} by their IDs.
168         *
169         * @param toSort the list of checkable text fields to be sorted.
170         * @return the sorted list.
171         */
172        private List sort(List toSort) {
173            Collections.sort(toSort, new Comparator() {
174                public int compare(Object o1, Object o2) {
175                    JTFCheckable ctf1 = (JTFCheckable)o1;
176                    JTFCheckable ctf2 = (JTFCheckable)o2;
177                    return (ctf1.getID() - ctf2.getID());
178                }
179            });
180            return toSort;
181        }
182    
183        /**
184         * Recursively searches a given JComponent for CheckableTextFields.
185         *
186         * @param comp the user interface's component to be searched upon.
187         * @return a list of all {@link JTFCheckable checkable text fields}.
188         */
189        private List getCheckableComponents(JComponent comp) {
190            List returnComponents = new ArrayList();
191            Component[] comps = comp.getComponents();
192            for (int i = 0; i < comps.length; i++) {
193                //add all Components following recursions might find
194                if (comps[i] instanceof JPanel) {
195                    returnComponents.addAll(getCheckableComponents((JComponent)comps[i]));
196                };
197                //check for Class market.stdform.JTFCheckable, if found add Component to list
198                if (comps[i] instanceof JTFCheckable) {
199                    returnComponents.add(comps[i]);
200                }
201            }
202            return returnComponents;
203        }
204    
205        /**
206         * @return the selected Record of an embedded {@link SingleTableFormSheet}.
207         * If no SingleTableFormSheet is embedded, null is returned.
208         */
209        public Object getSelectedRecord() {
210            if (formSheet instanceof SingleTableFormSheet) {
211                return ((SingleTableFormSheet)formSheet).getSelectedRecord();
212            } else {
213                return null;
214            }
215        }
216    
217        /**
218         * @return the FormSheet which is wrapped by this FSCheckable.
219         */
220        public FormSheet getFormSheet(){
221            return this.formSheet;
222        }
223    }