001    /* BEE - Book Editing Environment for PAVLOV
002     * Copyright (C) 2004 T.J. Willis
003     * 
004     * This program is free software; you can redistribute it and/or
005     * modify it under the terms of the GNU General Public License
006     * as published by the Free Software Foundation; either version 2
007     * of the License, or (at your option) any later version.
008     * 
009     * This program is distributed in the hope that it will be useful,
010     * but WITHOUT ANY WARRANTY; without even the implied warranty of
011     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
012     * GNU General Public License for more details.
013     * 
014     * You should have received a copy of the GNU General Public License
015     * along with this program; if not, write to the Free Software
016     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
017     *
018     * $Header: /cvsroot/pavlov/net/sourceforge/bee/QuestionDruid.java,v 1.5 2004/05/10 14:46:07 tj_willis Exp $
019     */
020    package net.sourceforge.bee;
021    import javax.swing.*;
022    import java.awt.*;
023    import java.awt.event.*;
024    import java.util.*;
025    import net.sourceforge.pavlov.library.*;
026    
027    /**
028     * A GUI widget that lets the user create many similar questions quickly.
029     *
030     * @author <a href="mailto:"></a>
031     * @version 1.0
032     */
033    public class QuestionDruid
034        extends JInternalFrame
035        implements ActionListener
036    {
037        private JTextField qPreText, qPostText, aPreText, aPostText;
038        private JButton bSwitch, generate, clearAll; //bMoreRows; , done;
039        private int rows = 500;
040        private JTable tab;
041        private JTextArea preview;
042        private Random rand;
043        private ChapterEditor chapterPanel;
044    
045        /**
046         * Creates a new <code>QuestionDruid</code> instance.
047         *
048         * @param chapPanel a <code>ChapterEditor</code> value
049         */
050        public QuestionDruid(ChapterEditor chapPanel)
051        {
052            super("Question Factory");
053            setClosable(true);
054            setDefaultCloseOperation(HIDE_ON_CLOSE);
055            chapterPanel = chapPanel;
056            Container c = getContentPane();
057            BorderLayout border = new BorderLayout();
058            c.setLayout(border);
059            
060            Box left = new Box(BoxLayout.Y_AXIS);
061            
062            JPanel p1 = new JPanel();
063            p1.setBorder(BorderFactory.createTitledBorder("Question Pre Text"));
064            qPreText = new JTextField(25);
065            qPreText.addActionListener(this);
066            p1.add(qPreText);
067            left.add(p1);
068    
069            JPanel p2 = new JPanel();
070            p2.setBorder(BorderFactory.createTitledBorder("Question Post Text"));
071            qPostText = new JTextField(25);
072            qPostText.addActionListener(this);
073            p2.add(qPostText);
074            left.add(p2);
075    
076            JPanel p3 = new JPanel();
077            p3.setBorder(BorderFactory.createTitledBorder("Answer Pre Text"));
078            aPreText = new JTextField(25);
079            aPreText.addActionListener(this);
080            p3.add(aPreText);
081            left.add(p3);
082    
083            JPanel p4 = new JPanel();
084            p4.setBorder(BorderFactory.createTitledBorder("Answer Post Text"));
085            aPostText = new JTextField(25);
086            aPostText.addActionListener(this);
087            p4.add(aPostText);
088            left.add(p4);
089    
090            JPanel p5 = new JPanel();
091            p5.setBorder(BorderFactory.createTitledBorder("Sample Question Preview"));
092            preview = new JTextArea(10,25);
093            preview.setEditable(false);
094            JScrollPane js2 = new JScrollPane(preview);
095            p5.add(js2);
096            left.add(p5);
097    
098            c.add(left,BorderLayout.WEST);
099    
100    
101            JPanel center = new JPanel();
102            center.setBorder(BorderFactory.createTitledBorder("Input Text"));
103            BoxLayout bl = new BoxLayout(center,BoxLayout.Y_AXIS);
104            center.setLayout(bl);
105    
106            // TOFIX: 500 is a y2k
107            String foo[][] = new String[500][2];
108            String cols[] = { "Question Atom","Answer Atom" };
109            tab = new JTable(foo,cols); //rows,2);
110            JScrollPane sp = new JScrollPane(tab);
111            center.add(sp);
112    
113            JPanel btns = new JPanel();
114            BoxLayout bl1 = new BoxLayout(btns,BoxLayout.X_AXIS);
115            btns.setLayout(bl1);    
116    
117            bSwitch = new JButton("Switch Columns");
118            btns.add(bSwitch);
119            bSwitch.addActionListener(this);
120            //bMoreRows = new JButton("More Rows");
121            //btns.add(bMoreRows);
122            //bMoreRows.addActionListener(this);
123            
124    
125    
126            center.add(btns);
127    
128            c.add(center,BorderLayout.CENTER);
129    
130    
131            Box bottom = new Box(BoxLayout.X_AXIS);
132    
133            //done = new JButton("Done");
134            //done.addActionListener(this);
135            //bottom.add(done);     
136    
137            clearAll = new JButton("Reset Form");
138            clearAll.addActionListener(this);
139            bottom.add(clearAll);
140    
141    
142            generate = new JButton("Generate Questions");
143            generate.addActionListener(this);
144            bottom.add(generate);
145    
146            c.add(bottom, BorderLayout.SOUTH);
147    
148            pack();
149            setVisible(true);
150    
151            rand = new Random();
152        }
153    
154        private String getTabText(int i,int j)
155        {
156            if(tab.getValueAt(i,j)==null) return "";
157            //System.out.println( "class is " + tab.getValueAt(0,0).getClass());
158            return tab.getValueAt(i,j).toString();
159        }
160    
161        private void switchColumns(){
162            int k = tab.getRowCount();
163            for(int i=0;i<k;i++){
164                String x =getTabText(i,0);
165                String y =getTabText(i,1);
166                tab.setValueAt(y,i,0);
167                tab.setValueAt(x,i,1);
168            }
169        }
170    
171    
172        private ArrayList<String> uniqueWrongAnswers(int row)
173        {
174            int k = tab.getRowCount();
175            HashSet<String> set = new HashSet<String>();
176            for(int i=0;i<k;i++){
177                if(row==i) continue;
178                String x = getTabText(i,1);
179                if(x==null) continue;
180                if(x.equals("")) continue;
181                if(x.equals("###")) continue;
182                if(x.equals(getTabText(row,1))) continue;  // this is the right answer
183                set.add(x); // this keeps them unique
184            }
185            if(set.isEmpty()) return null;
186            return new ArrayList<String>(set);   
187        }
188    
189    
190        private String removeRandomElement(ArrayList lst)
191        {
192            int k = lst.size();
193            int t = rand.nextInt(k);
194            String x = (String)lst.remove(t);
195            return x;
196        }
197    
198        private ArrayList<String> getWrongAnswers(int row)
199        {
200            ArrayList lst = uniqueWrongAnswers(row);
201            if(lst==null) return null;
202            int k = lst.size();
203            if(k<3) return null;
204    
205            ArrayList<String> ret = new ArrayList<String>();
206            for(int i=0;i<3;i++){
207                String x = removeRandomElement(lst);
208                ret.add(x);
209            }
210            return ret;
211    
212        }
213    
214        private void clearAll()
215        {
216         int k = tab.getRowCount();
217          for(int i=0;i<k;i++){
218              tab.setValueAt("",i,0);
219              tab.setValueAt("",i,1);
220          }
221          qPreText.setText("");
222          qPostText.setText("");
223          aPreText.setText("");
224          aPostText.setText("");
225    
226        }
227    
228      private void generate()
229      {
230        Vector<Question> generated = new Vector<Question>();
231        try {
232          int k = tab.getRowCount();
233          for(int i=0;i<k;i++){
234              String txt = getTabText(i,0);
235              String ans = getTabText(i,1);
236              if(txt==null && ans == null) continue;
237              if(txt.equals("") && ans.equals("")) continue;
238              Question q = Question.makeBlankQuestion();
239              String s = qPreText.getText();
240              s += txt;
241              s += qPostText.getText();
242              q.setText(s);
243              q.setRightAnswer(makeAnswer(ans));
244              q.setId(new String("NOID"));
245              ArrayList answers = getWrongAnswers(i);
246              q.setWrongAnswer(makeAnswer(removeRandomElement(answers)),0);
247              q.setWrongAnswer(makeAnswer(removeRandomElement(answers)),1);
248              q.setWrongAnswer(makeAnswer(removeRandomElement(answers)),2);
249              generated.add(q);
250            }
251          chapterPanel.addGenerated(generated);
252        } catch (Exception e) {
253          System.out.println(e);
254          return;
255        }
256      }
257    
258        private String makeAnswer(String atom)
259        {
260            String s = aPreText.getText();
261            s += atom;
262            s += aPostText.getText();
263            return s;
264        }
265    
266        private void generatePreview()
267        {
268            String s = new String();
269            ArrayList<String> answers = getWrongAnswers(0);
270            //String right = getTabText(0,0);
271            //answers.add(right); // right answer
272            try {
273                s += qPreText.getText();
274                s += getTabText(0,0);
275                s += qPostText.getText() +"\n";
276                if(answers==null){
277                    s+= "A: (need more answers)\n";
278                    s+= "B: (need more answers)\n";
279                    s+= "C: (need more answers)\n";
280                    s+= "D: (need more answers)\n";
281                } else {
282                    String right = getTabText(0,1);
283                    answers.add(right); // right answer
284                    s += "A: " + aPreText.getText() + removeRandomElement(answers) + aPostText.getText() + "\n";
285                    s += "B: " + aPreText.getText() + removeRandomElement(answers) + aPostText.getText() + "\n";
286                    s += "C: " + aPreText.getText() + removeRandomElement(answers) + aPostText.getText() + "\n";
287                    s += "D: " + aPreText.getText() + removeRandomElement(answers) + aPostText.getText() + "\n";
288                }
289            } catch (Exception e) {
290                s = "Need more values";
291                System.out.println(e);
292                e.printStackTrace();
293            }
294            preview.setText(s);
295        }
296    
297        /**
298         * Handles GUI events.
299         *
300         * @param e an <code>ActionEvent</code> value
301         */
302        public void actionPerformed(ActionEvent e)
303        {
304            Object o = e.getSource();
305            if(o== qPreText){
306    
307            } else if(o==qPostText ){
308    
309            } else if(o==aPreText ){
310    
311            } else if(o==aPostText ){
312    
313            } else if(o==bSwitch ){
314                switchColumns();
315            } else if(o==generate ){
316                generate();
317            }else if(o==clearAll ){
318                clearAll();
319            }
320            generatePreview();
321        }
322    
323    }