001    /**
002     * ObtainQueryWithFormMethod.java
003     * jCOLIBRI2 framework. 
004     * @author Juan A. Recio-García.
005     * GAIA - Group for Artificial Intelligence Applications
006     * http://gaia.fdi.ucm.es
007     * 23/10/2007
008     */
009    package jcolibri.method.gui.formFilling;
010    
011    import java.awt.BorderLayout;
012    import java.awt.event.ActionEvent;
013    import java.awt.event.ActionListener;
014    import java.util.ArrayList;
015    import java.util.Collection;
016    import java.util.HashMap;
017    import java.util.Hashtable;
018    import java.util.Map;
019    
020    import javax.swing.BoxLayout;
021    import javax.swing.JButton;
022    import javax.swing.JDialog;
023    import javax.swing.JLabel;
024    import javax.swing.JPanel;
025    import javax.swing.SpringLayout;
026    
027    import jcolibri.cbrcore.Attribute;
028    import jcolibri.cbrcore.CBRQuery;
029    import jcolibri.cbrcore.CaseComponent;
030    import jcolibri.exception.AttributeAccessException;
031    import jcolibri.method.gui.editors.ParameterEditor;
032    import jcolibri.method.gui.editors.ParameterEditorFactory;
033    import jcolibri.method.gui.utils.LayoutUtils;
034    import jcolibri.method.gui.utils.WindowUtils;
035    import jcolibri.util.AttributeUtils;
036    
037    /**
038     * Shows a from to obtain the query.<br>
039     * The methods of this class allow to use default values (read from the query),
040     * hide some attributes and specify the label shown with each attribute.
041     * 
042     * @author Juan A. Recio-Garcia
043     * @version 1.0
044     *
045     */
046    public class ObtainQueryWithFormMethod
047    {
048        private static Hashtable<Attribute, ParameterEditor> editors;
049        private static JDialog dialog;
050    
051        /**
052         * Obtains a query without showing initila values.
053         * It shows every attribute and uses the attribute name as the label.
054         * @param query to obtain.
055         */
056        public static void obtainQueryWithoutInitialValues(CBRQuery query, Collection<Attribute> hiddenAttributes, Map<Attribute, String> labels)
057        {
058            obtainQuery(query, false, hiddenAttributes, labels);
059        }
060        
061        /**
062         * Obtains a query showing the initial values of the received query object.
063         * It shows every attribute and uses the attribute name as the label.
064         * @param query with the initial values and where the user new values are stored
065         */
066        public static void obtainQueryWithInitialValues(CBRQuery query, Collection<Attribute> hiddenAttributes, Map<Attribute, String> labels)
067        {
068            obtainQuery(query, true,  hiddenAttributes, labels);
069        }
070        
071        /**
072         * Obtains the query showing a form
073         * @param query to fill with the obtained values and containing the initial values
074         * @param useQueryvalues indicates if the query values are shown by default
075         * @param hiddenAttributes is a list of not shown attributes
076         * @param labels for each attribute. If there is no label for an attribute, 
077         * the attribute name is used.
078         */
079        static void obtainQuery(CBRQuery query, boolean useQueryvalues, Collection<Attribute> hiddenAttributes, Map<Attribute, String> labels)
080        {
081            dialog = new JDialog();
082            dialog.setModal(true);
083            
084            editors = new Hashtable<Attribute, ParameterEditor>();
085            
086            JPanel panel = new JPanel();
087            
088            addAttributes(query.getDescription(), panel, hiddenAttributes, labels);
089            
090            if(useQueryvalues)
091            {
092                for(Attribute a: editors.keySet())
093                {
094                    ParameterEditor editor = editors.get(a);
095                    editor.setEditorValue(jcolibri.util.AttributeUtils.findValue(a, query));
096                }
097            }
098            
099            dialog.getContentPane().setLayout(new BorderLayout());
100            dialog.getContentPane().add(panel,BorderLayout.CENTER);
101            
102            JPanel okPanel = new JPanel();
103            JButton okButton = new JButton("Ok");
104            okButton.addActionListener(new ActionListener(){
105                public void actionPerformed(ActionEvent arg0)
106                {
107                    dialog.setVisible(false);       
108                }
109            });
110            okPanel.add(okButton);
111            dialog.getContentPane().add(okPanel,BorderLayout.SOUTH);
112            
113            
114            dialog.pack();
115            WindowUtils.centerWindow(dialog);
116            dialog.setTitle("Query");
117            dialog.setVisible(true);
118            
119            for(Attribute a: editors.keySet())
120            {
121                Object value = editors.get(a).getEditorValue();
122                jcolibri.util.AttributeUtils.setValue(a, query, value);
123            }
124            System.out.println(query);
125        }
126        
127        /**
128         * Adds Parameter editor to the panel for each attribute in the CaseComponent
129         * @param cc CaseComponent with the attributes
130         * @param panel to add the ParameterEditor
131         * @param hiddenAttributes attributes not shown
132         * @param labels for the attributes
133         */
134        private static void addAttributes(CaseComponent cc, JPanel panel, Collection<Attribute> hiddenAttributes, Map<Attribute, String> labels)
135        {
136            panel.setLayout(new BoxLayout(panel,BoxLayout.Y_AXIS));
137            JPanel simplePanel = new JPanel();
138            simplePanel.setLayout(new SpringLayout());
139            
140            JPanel compoundPanel = new JPanel();
141            compoundPanel.setLayout(new BoxLayout(compoundPanel,BoxLayout.Y_AXIS));
142    
143            try
144            {
145                if(hiddenAttributes == null)
146                    hiddenAttributes = new ArrayList<Attribute>();
147                if(labels == null)
148                    labels = new HashMap<Attribute,String>();
149                
150                Attribute[] ats = jcolibri.util.AttributeUtils.getAttributes(cc.getClass());
151                Attribute id = cc.getIdAttribute();
152                
153                ArrayList<Attribute> compounds = new ArrayList<Attribute>();
154                int sAtts = 0;
155                for(Attribute a: ats)
156                {
157                    if(a.equals(id))
158                        continue;
159                    else if(a.getType().equals(CaseComponent.class))
160                    {
161                        compounds.add(a);
162                    }
163                    else if(hiddenAttributes.contains(a))
164                        continue;
165                    else
166                    {
167                        String label = labels.get(a);
168                        if(label==null)
169                            label = a.getName();
170                        simplePanel.add(new JLabel(label));
171                        ParameterEditor pe = ParameterEditorFactory.getEditor(a.getType());
172                        simplePanel.add(pe.getJComponent());
173                        editors.put(a,pe);
174                        sAtts++;
175                    }
176                }
177                LayoutUtils.makeCompactGrid(simplePanel, sAtts,2,5,5,5,5);
178                
179                
180                //Now process compounds
181                for(Attribute comp: compounds)
182                {
183                    JPanel subpanel = new JPanel();
184                    subpanel.setBorder(javax.swing.BorderFactory.createTitledBorder(comp.getName()));
185                    addAttributes((CaseComponent)comp.getValue(cc),subpanel,hiddenAttributes,labels);
186                    compoundPanel.add(subpanel);
187                }
188                
189                panel.add(simplePanel);
190                panel.add(compoundPanel);
191            } catch (AttributeAccessException e)
192            {
193                org.apache.commons.logging.LogFactory.getLog(AttributeUtils.class).error(e);
194            }
195        }
196        
197    }