1 diff --git a/motsim/ControlPanel.java b/motsim/ControlPanel.java
2 index 855ef2a..c2b69de 100644
3 --- a/motsim/ControlPanel.java
4 +++ b/motsim/ControlPanel.java
5 @@ -119,7 +119,7 @@ class ControlPanel extends JFrame implements ActionListener {
6 options_panel.add(trials_spinner);
7 targets_label = new JLabel("Number of targets: ");
9 - new JSpinner(new SpinnerNumberModel(22, 1, 50, 1));
10 + new JSpinner(new SpinnerNumberModel(4, 1, 50, 1));
11 targets_spinner.setFocusable(false);
12 options_panel.add(targets_label);
13 options_panel.add(targets_spinner);
14 diff --git a/motsim/Controller.java b/motsim/Controller.java
15 index fc9db80..2fb30a8 100755
16 --- a/motsim/Controller.java
17 +++ b/motsim/Controller.java
18 @@ -36,7 +36,7 @@ import java.awt.font.TextLayout;
19 import java.util.ArrayList;
20 import java.util.Random;
22 -public class Controller {
23 +public class Controller implements Runnable {
27 @@ -130,64 +130,72 @@ public class Controller {
31 - class TrialThread implements Runnable {
37 - // First move the targets around the screen
38 - while (model.stage == Model.TrialStage.MOVE) {
39 - if (model.duration < model.maxduration) {
42 - model.stage = Model.TrialStage.CHOOSE;
45 - // After trial duration mask targets and pick a random target
46 - if (model.stage == Model.TrialStage.CHOOSE) {
47 - view.trial.repaint();
48 - model.target = rand.nextInt(model.targets.size());
49 - model.stage = Model.TrialStage.FIND;
53 + switch(model.stage) {
59 + if (model.duration < model.maxduration) {
63 - // Search for target
65 + model.stage = Model.TrialStage.CHOOSE_TARGET;
68 + view.trial.repaint();
69 + model.target = rand.nextInt(model.targets.size());
70 + model.stage = Model.TrialStage.START_SEARCH;
73 model.startTime = System.currentTimeMillis();
74 - while (model.stage == Model.TrialStage.FIND) {
75 - synchronized (model.trialThread) {
77 - model.trialThread.wait();
78 - } catch (InterruptedException e1) {
80 + model.stage = Model.TrialStage.FIND_TARGET;
83 + synchronized (model.trialThread) {
85 + model.trialThread.wait();
86 + } catch (InterruptedException e1) {
88 - view.trial.repaint();
91 - if (trials >= model.trialCount)
92 - view.trial.stopTrial();
93 - // Trial is over, wait
94 - model.waiting = true;
95 + view.trial.repaint();
99 + model.stopTime = System.currentTimeMillis();
100 + model.stage = Model.TrialStage.TRIAL_CLEANUP;
102 + case TRIAL_CLEANUP:
103 + model.trialCount++;
104 + if (model.trialCount < model.maxTrials) {
105 + model.stage = Model.TrialStage.START_TRIAL;
107 + model.stage = Model.TrialStage.END;
108 + view.trial.dispose();
112 + System.out.println(model.stopTime - model.startTime);
113 + model.stage = Model.TrialStage.WAIT;
116 synchronized (model.trialThread) {
118 model.trialThread.wait();
119 } catch (InterruptedException e1) {
122 - model.waiting = false;
131 - /* Store participant information */
132 - model.participant = new Participant(
133 - view.cp.sx_name_textfield.getText(),
134 - view.cp.sx_email_textfield.getText(),
135 - view.cp.genders[view.cp.gender_combobox.getSelectedIndex()],
136 - view.cp.handedness[view.cp.handedness_combobox.getSelectedIndex()],
137 - view.cp.vision[view.cp.vision_combobox.getSelectedIndex()],
138 - Integer.valueOf(view.cp.sx_age_textfield.getText())
140 /* Initialize trial values */
141 model.maxduration = 1000 * (Integer)view.cp.duration_spinner.getValue();
142 model.entropy = view.cp.entropy_combobox.getSelectedItem().toString();
143 @@ -222,15 +230,7 @@ public class Controller {
144 if (t.y < t.bounds.getHeight())
145 t.y = t.bounds.getHeight() + 1;
147 - model.stage = Model.TrialStage.MOVE;
148 - if (model.trialThread == null) {
149 - model.trialThread = new Thread(new TrialThread());
150 - model.trialThread.start();
152 - synchronized (model.trialThread) {
153 - model.trialThread.notifyAll();
156 + model.stage = Model.TrialStage.MOVE_TARGETS;
160 diff --git a/motsim/EventHandler.java b/motsim/EventHandler.java
161 index 7580c0c..5df9efd 100644
162 --- a/motsim/EventHandler.java
163 +++ b/motsim/EventHandler.java
164 @@ -29,14 +29,34 @@ ActionListener {
167 public void actionPerformed(ActionEvent e) {
168 - if (e.getActionCommand()=="cp-start" ||
169 - e.getActionCommand()=="sx-start") {
170 - if ((view.cp.collectdata_checkbox.getSelectedObjects()!=null) &&
171 - !(view.cp.sx_panel.isVisible())) {
172 - view.collectDemographics();
174 - view.cp.sx_panel.setVisible(false);
175 - controller.startTrials();
177 + if (e.getActionCommand()=="cp-start") {
178 + model.maxduration =
179 + 1000 * (Integer)view.cp.duration_spinner.getValue();
181 + view.cp.entropy_combobox.getSelectedItem().toString();
182 + model.fontsize = (Integer)view.cp.fontsize_spinner.getValue();
183 + model.maxTrials = (Integer)view.cp.trials_spinner.getValue();
184 + if (view.cp.collectdata_checkbox.isSelected()) {
185 + view.cp.config_panel.setVisible(false);
186 + view.cp.sx_panel.setVisible(true);
189 + } else if (e.getActionCommand()=="sx-start") {
190 + model.participant = new Participant(
191 + view.cp.sx_name_textfield.getText(),
192 + view.cp.sx_email_textfield.getText(),
193 + (String)view.cp.gender_combobox.getSelectedItem(),
194 + (String)view.cp.handedness_combobox.getSelectedItem(),
195 + (String)view.cp.vision_combobox.getSelectedItem(),
196 + Integer.valueOf(view.cp.sx_age_textfield.getText())
199 + if ((e.getActionCommand()=="sx-start") ||
200 + (e.getActionCommand()=="cp-start")) {
201 + model.stage = Model.TrialStage.START_TRIAL;
202 + synchronized (model.trialThread) {
203 + model.trialThread.notifyAll();
205 } else if (e.getActionCommand()=="simmode") {
206 if (view.cp.simmode_combobox.getSelectedItem().toString() ==
207 @@ -46,6 +66,7 @@ ActionListener {
208 view.cp.trials_spinner.setEnabled(false);
214 public void keyPressed(KeyEvent e) {
215 @@ -58,7 +79,7 @@ ActionListener {
218 public void mouseClicked(MouseEvent e) {
219 - if (model.stage == Model.TrialStage.FIND) {
220 + if (model.stage == Model.TrialStage.FIND_TARGET) {
221 model.mouse_x_clk = e.getX();
222 model.mouse_y_clk = e.getY();
223 synchronized (model.trialThread) {
224 @@ -83,7 +104,7 @@ ActionListener {
227 public void mouseMoved(MouseEvent e) {
228 - if (model.stage == Model.TrialStage.FIND) {
229 + if (model.stage == Model.TrialStage.FIND_TARGET) {
230 model.mouse_x = e.getX();
231 model.mouse_y = e.getY();
232 synchronized (model.trialThread) {
233 @@ -102,8 +123,11 @@ ActionListener {
236 public void windowDeactivated(WindowEvent e) {
237 - view.trial.stopTrial();
238 - //model.gd.setDisplayMode(model.display_mode_preferred);
239 + model.stage = Model.TrialStage.WAIT;
240 + synchronized (model.trialThread) {
241 + model.trialThread.notifyAll();
243 + view.trial.dispose();
246 public void windowDeiconified(WindowEvent e) {
247 diff --git a/motsim/MOTSIM.java b/motsim/MOTSIM.java
248 index d8ea078..33af943 100755
249 --- a/motsim/MOTSIM.java
250 +++ b/motsim/MOTSIM.java
251 @@ -47,6 +47,8 @@ public class MOTSIM {
252 View view = new View(model);
253 Controller controller = new Controller(model, view);
254 new EventHandler(model, view, controller);
255 + model.trialThread = new Thread(controller);
256 + model.trialThread.start();
257 view.startControlPanel();
258 view.cp.setVisible(true);
260 diff --git a/motsim/Model.java b/motsim/Model.java
261 index 01eeee2..6233cfb 100755
262 --- a/motsim/Model.java
263 +++ b/motsim/Model.java
267 import java.awt.Color;
268 -import java.awt.DisplayMode;
269 import java.awt.Font;
270 import java.awt.GraphicsDevice;
271 import java.awt.GraphicsEnvironment;
272 @@ -43,23 +42,34 @@ public class Model {
273 /* Graphic Environment Information */
274 GraphicsEnvironment ge;
276 - DisplayMode display_mode_default;
277 - DisplayMode display_mode_preferred;
278 - DisplayMode[] display_mode_available;
281 ArrayList<Target> targets;
284 * Use this enum to indicate which stage of the experiment we are in
286 public enum TrialStage {
287 - INIT, INFO, BIAS, CHOOSE, MOVE, FIND, TLX, END
303 - TrialStage stage = TrialStage.INIT;
304 + TrialStage stage = TrialStage.WAIT;
306 /* Represents basic experiment information */
307 Participant participant = null;
310 double startTime = 0;
313 @@ -68,6 +78,7 @@ public class Model {
315 /* GUI Information */
320 int query_font_size = 18;
321 @@ -87,7 +98,5 @@ public class Model {
324 int mouse_x_clk = -1;
325 - int mouse_y_clk = -1;
326 - boolean waiting = false;
328 + int mouse_y_clk = -1;
330 diff --git a/motsim/Trial.java b/motsim/Trial.java
331 index d6988c7..6767b2e 100644
332 --- a/motsim/Trial.java
333 +++ b/motsim/Trial.java
334 @@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
336 import java.awt.Color;
337 import java.awt.Dimension;
338 +import java.awt.Font;
339 import java.awt.Graphics;
340 import java.awt.Graphics2D;
341 import java.awt.Image;
342 @@ -65,13 +66,21 @@ class Trial extends JFrame {
343 setLocationRelativeTo(null);
344 setUndecorated(true);
345 model.gd.setFullScreenWindow(this);
346 - //model.gd.setDisplayMode(model.display_mode_preferred);
347 setBackground(Color.black);
348 offscreen = createImage(screen_size.width, screen_size.height);
349 bufferGraphics = (Graphics2D)offscreen.getGraphics();
350 frc = bufferGraphics.getFontRenderContext();
352 + // Set starting values
355 + model.duration = 0;
356 + model.target_font = new Font(getFont().getName(), getFont().getStyle(),
358 + model.query_font = new Font(getFont().getName(), getFont().getStyle(),
359 + model.query_font_size);
360 + bufferGraphics.setFont(model.target_font);
361 + mh = model.query_font.getSize() + model.query_font_size;
364 private void drawTarget(Target t, boolean isMasked) {
365 @@ -86,6 +95,31 @@ class Trial extends JFrame {
366 t.bounds = tl.getBounds();
367 tl.draw(bufferGraphics, (float)t.x, (float)t.y);
370 + private void drawFrame() {
371 + bufferGraphics.setColor(model.target_color);
372 + bufferGraphics.drawRect(0, 0, screen_size.width-1,
373 + screen_size.height-1);
374 + bufferGraphics.drawRect(0, screen_size.height-1-mh,
375 + screen_size.width-1, screen_size.height-1);
378 + private void drawQuery() {
379 + bufferGraphics.setColor(model.query_color);
380 + TextLayout tl = new TextLayout("Click on target: " + "\"" +
381 + model.targets.get(model.target).callsign + "\"",
382 + model.query_font, frc);
383 + tl.draw(bufferGraphics,
385 + screen_size.width / 2 - tl.getBounds().getCenterX()
388 + screen_size.height - mh / 2 +
389 + tl.getBounds().getCenterY() / 2
392 + bufferGraphics.setColor(model.target_color);
395 private void processTargets() {
397 @@ -96,7 +130,7 @@ class Trial extends JFrame {
399 t = model.targets.get(i);
401 - if (model.stage == Model.TrialStage.FIND) {
402 + if (model.stage == Model.TrialStage.FIND_TARGET) {
403 if ((model.mouse_x>=t.x) &&
404 (model.mouse_x<=(t.x+t.bounds.getWidth())) &&
405 (model.mouse_y>=(t.y-t.bounds.getHeight())) &&
406 @@ -111,9 +145,11 @@ class Trial extends JFrame {
407 (model.mouse_y_clk>=(t.y-t.bounds.getHeight())) &&
408 (model.mouse_y_clk<=t.y) ) {
409 if (model.targets.get(model.target)==t) {
410 - model.stopTime = System.currentTimeMillis();
412 - //System.out.println(model.stopTime - model.startTime);
413 + model.stage= Model.TrialStage.STOP_SEARCH;
414 + synchronized (model.trialThread) {
415 + model.trialThread.notifyAll();
421 @@ -123,37 +159,12 @@ class Trial extends JFrame {
425 - public void drawFrame() {
426 - bufferGraphics.setColor(model.target_color);
427 - bufferGraphics.drawRect(0, 0, screen_size.width-1,
428 - screen_size.height-1);
429 - bufferGraphics.drawRect(0, screen_size.height-1-mh,
430 - screen_size.width-1, screen_size.height-1);
433 - public void drawQuery() {
434 - bufferGraphics.setColor(model.query_color);
435 - TextLayout tl = new TextLayout("Click on target: " + "\"" +
436 - model.targets.get(model.target).callsign + "\"",
437 - model.query_font, frc);
438 - tl.draw(bufferGraphics,
440 - screen_size.width / 2 - tl.getBounds().getCenterX()
443 - screen_size.height - mh / 2 +
444 - tl.getBounds().getCenterY() / 2
447 - bufferGraphics.setColor(model.target_color);
450 public void paint(Graphics g) {
451 Graphics2D g2 = (Graphics2D)g;
452 bufferGraphics.clearRect(0, 0, screen_size.width,
455 - if (model.stage == Model.TrialStage.FIND)
456 + if (model.stage == Model.TrialStage.FIND_TARGET)
459 g2.drawImage(offscreen, 0, 0, this);
460 @@ -163,14 +174,4 @@ class Trial extends JFrame {
464 - protected void stopTrial() {
465 - model.stage = Model.TrialStage.END;
467 - if (!model.waiting) {
468 - synchronized (model.trialThread) {
469 - model.trialThread.notifyAll();
475 diff --git a/motsim/View.java b/motsim/View.java
476 index 68a442b..235a6b8 100755
477 --- a/motsim/View.java
478 +++ b/motsim/View.java
479 @@ -47,17 +47,8 @@ public class View {
480 public View(Model model) {
482 screen_size = Toolkit.getDefaultToolkit().getScreenSize();
483 - //int dpi = Toolkit.getDefaultToolkit().getScreenResolution();
484 model.ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
485 model.gd = model.ge.getDefaultScreenDevice();
486 - /*model.display_mode_default = model.gd.getDisplayMode();
487 - model.display_mode_available = model.gd.getDisplayModes();
488 - for (DisplayMode dm : model.display_mode_available) {
489 - if ((dm.getWidth() == 800) && (dm.getHeight() == 600)) {
490 - model.display_mode_preferred = dm;
496 public void setEventHandler(EventHandler evh) {
497 @@ -66,18 +57,10 @@ public class View {
499 public void startControlPanel() {
500 cp = new ControlPanel(evh);
501 - //cp.fontsize_spinner.setValue(cp.getFont().getSize());
504 public void startTrial() {
505 trial = new Trial(model, screen_size, evh);
508 - public void collectDemographics() {
509 - //new DemographicsPanel();
510 - cp.config_panel.setVisible(false);
511 - cp.sx_panel.setVisible(true);