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 }