changeset 26:c5db34797ff3

Visual feedback for responses: consistent for mouse and keyboard input; disable buttons when not inactive. Improved debugging messages.
author Jeremy Gow <jeremy.gow@gmail.com>
date Mon, 12 Nov 2012 22:48:39 +0000
parents cd11981476ec
children 014c83185b2a
files ExperimentController.class ExperimentController.java ExperimentGui.class ExperimentGui.java StimulusPanel.class StimulusPanel.java
diffstat 6 files changed, 123 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
Binary file ExperimentController.class has changed
--- a/ExperimentController.java	Mon Nov 12 22:34:52 2012 +0000
+++ b/ExperimentController.java	Mon Nov 12 22:48:39 2012 +0000
@@ -154,20 +154,28 @@
                 }
             }
         } else { 
+	    if (exp.getDebug()) 
+		System.out.println("Button response, getAcceptingResponses: " + gui.getAcceptingResponses() + " " + e.getActionCommand());
+
             JButton[] rButtons = sp.getResponseButtons(); 
             for (int i = 0; i < rButtons.length; i++) { 
-                System.out.println("getAcceptingResponses: " + gui.getAcceptingResponses());
                 if (source == rButtons[i] && (exp.isRunning() || exp.hasRun()) && gui.getAcceptingResponses()) { 
+		    ratingResponse(i, time);
+		    /*
                     block.addResponse(i+1, time);
                     gui.setAcceptingResponses(false); 
                     rButtons[i].setBackground(Color.red);
+		    rButtons[i].setOpaque(true);
+		    */
                 }
             }
         }
     }
+
     
     public void keyPressed(KeyEvent e)  {
-        //System.out.println("Key pressed: " + e.getKeyChar());
+        if (exp.getDebug())
+	    System.out.println("Key pressed: " + e.getKeyChar());
         long time = System.nanoTime();
 
         Block block = exp.getCurrentBlock();
@@ -186,10 +194,13 @@
                 for (int i = 0; i < rButtons.length; i++) {
                     //System.out.println("Char = " + Character.forDigit(i+1, 10));
                     if (e.getKeyChar() == Character.forDigit(i+1, 10)) {
+			ratingResponse(i, time);
+			/*
                         if (exp.getDebug())
                             System.out.println("Got rating: " + (i + 1));
                         block.addResponse(i+1, time);
                         gui.setAcceptingResponses(false); 
+			*/
                     }
                     //else 
                     //    block.addResponse(0, time);
@@ -204,4 +215,15 @@
     public void keyTyped(KeyEvent e)  {
         //System.out.println("Key typed: " + e.getKeyChar());
     }
+
+    protected void ratingResponse(int buttonIndex, long time) {
+
+	int rating = buttonIndex + 1;
+
+	if (exp.getDebug())
+	    System.out.println("Rating: " + rating);
+	exp.getCurrentBlock().addResponse(rating, time);
+	sp.highlightResponse(buttonIndex);
+	gui.setAcceptingResponses(false); 
+    }
 }
Binary file ExperimentGui.class has changed
--- a/ExperimentGui.java	Mon Nov 12 22:34:52 2012 +0000
+++ b/ExperimentGui.java	Mon Nov 12 22:48:39 2012 +0000
@@ -32,9 +32,12 @@
     /* accessors */ 
     public Boolean getAcceptingResponses() { return acceptingResponses; }
     public void setAcceptingResponses(Boolean b) { 
-        if (exp.getDebug()) 
-            System.out.println("\n\nChanging acceptingResponses from " + acceptingResponses + " to " + b); 
+	if (b) 
+	    debug("STARTED accepting responses");
+	else
+	    debug("STOPPED accepting responses");
         acceptingResponses = b;
+	stimulusPanel.setResponseEnabled(b);
     }
     public Experiment getExperiment() { return exp; }
     public InstructionsPanel getInstructionsPanel() { return instructionsPanel; }
@@ -50,7 +53,7 @@
         acceptingResponses = false; 
 
         // set up the clock 
-        clock = new Clock(); 
+        clock = new Clock(exp.getDebug()); 
         
         // construct the frame
         JFrame.setDefaultLookAndFeelDecorated(true);
@@ -63,6 +66,8 @@
         stimulusPanel = new StimulusPanel(this, clock); 
         interBlockPanel = new InterBlockPanel(exp); 
         subjectDataPanel = new SubjectDataPanel(this, exp.getSubjectResults()); 
+
+	stimulusPanel.setResponseEnabled(false);
         
         // The Controller 
         ExperimentController ec = new ExperimentController(this); 
@@ -109,7 +114,7 @@
 
     /* Show the Fixation Point */ 
     public void showFixationPoint() { 
-        System.out.println("showFixationPoint");
+        debug("showFixationPoint");
         clock.showClock = false; 
         clock.showFullClock = false; 
         clock.repaint(); 
@@ -131,79 +136,117 @@
     }
     
 
+    public void debug(String message) {
+	if (exp.getDebug()) {
+	    System.out.println(message);
+	}
+    }
+
+    public void debugList(String name, ArrayList list) {
+	if (exp.getDebug()) {
+	    Iterator itr = list.iterator();
+	    System.out.print("\n" + name + " (" + list.size() + "): ");
+	    while (itr.hasNext()) {
+		System.out.print(" " + itr.next());
+	    }
+	    System.out.print("\n");
+	}
+    }
+
     /* Run method for this thread */
     public void run() { 
-        System.out.println("Run!");
+
+	boolean debug = exp.getDebug();
+
+	debug("\nBegin trial");
         //showFixationPoint(); 
         clock.reset(); 
         showClock(); 
 
-        int clockUnits = exp.getClockUnits(); 
-        int numUnits = exp.getNumUnits(); 
         long tatum = exp.getCurrentBlock().getTatum(); 
         long tatumInMilliseconds = tatum / 1000; 
-        int nMinutes = 60 / numUnits; 
+        int nMinutes = 60 / exp.getNumUnits(); 
         
+	debug("Tatum: " + tatum);
+
         ArrayList onsets = exp.getCurrentBlock().getOnsets(); 
         ArrayList probes = exp.getCurrentBlock().getProbePositions(); 
         ArrayList clockStartTimes = exp.getCurrentBlock().getClockStartTimes(); 
-            
+
+	debugList("Onset times", onsets);
+	debugList("Probe times", probes);
+	debugList("Clock start times", clockStartTimes);
+	
         Iterator oi = onsets.iterator(); 
         Iterator pi = probes.iterator(); 
         Iterator ci = clockStartTimes.iterator(); 
         
         ProbeID probe = ProbeID.NOT_PROBE; 
 
-        long currentOnset = 0; 
+        long currentTime = 0; 
         long nextEventOnset = ((Long)(oi.next())).longValue();
         long nextClockStartTime = ((Long)(ci.next())).longValue();
 
         int clockUnit = 0; 
         boolean clockTicking = false; 
 
-         do { //using a do-while construct allows the user to enter a value at the end
-         //this should not really be in the 'view' anyway...
-            System.out.println("TATUM: " +tatum);
-            tatumInMilliseconds = tatum/1000;   
-            if (exp.getDebug())
-                System.out.println("Ticking = " + clockTicking + 
-                                   "; clockUnit = " + clockUnit + 
-                                   "; currentOnset = " + currentOnset + 
-                                   "; nextEventOnset = " + nextEventOnset + 
-                                   "; nextClockStartTime = " + nextClockStartTime + 
-                                   "; probe = " + probe); 
-            if (clockTicking == true && clockUnit == 0)
-                tick(nMinutes); 
+	do {// Using a do-while construct allows the user to enter a value at the end
+	    // this should not really be in the 'view' anyway...
+	    
+	    debug("\n\nTicking = " + clockTicking + 
+		  "; clockUnit = " + clockUnit + 
+		  "; currentTime = " + currentTime + 
+		  "; nextEventOnset = " + nextEventOnset + 
+		  "; nextClockStartTime = " + nextClockStartTime);
+	    
+	    // Tick the clock every <clockUnit> cycles
+	    if (clockTicking && clockUnit == 0) {
+		debug("Tick");
+		tick(nMinutes); 
+	    }
             
-            if (currentOnset >= nextClockStartTime) { 
+	    // Start the clock
+            if (currentTime >= nextClockStartTime) { 
+		debug("Start clock (" + (currentTime - nextClockStartTime) + " ago)");
                 //new Thread(clock).start(); 
                 clock.reset(); 
                 showClock(); 
                 clockTicking = true; 
+		
                 if (ci.hasNext())
                     nextClockStartTime = ((Long)(ci.next())).longValue();
-                else
+                else 
                     nextClockStartTime = Long.MAX_VALUE;
             }
-            if (currentOnset >= nextEventOnset) { 
-                 probe = (ProbeID)pi.next(); 
+
+	    // Event onset
+            if (currentTime >= nextEventOnset) { 
+
+                // Update probe identifier and onset 
+		
+		probe = (ProbeID) pi.next();
+		debug("Event " + probe + " " + nextEventOnset + " (" + (currentTime - nextEventOnset) + " ago)");
+		nextEventOnset = ((Long)(oi.next())).longValue();
+		
                 // Manipulate display depending on probe identifier
                 switch (probe) { 
                 case NOT_PROBE: 
-                    // if (clock.showClock == true) 
+		    // if (clock.showClock == true) 
                     //    tick(nMinutes); 
                     break; 
-                case START_CLOCK: 
+		    /* 
+                case START_CLOCK:  // No longer used...
                     //clock.reset(); 
                     //showClock(); 
                     //tick(nMinutes); 
                     break; 
+		    */
                 case BEFORE_PROBE:
-                    if (exp.getDebug())
-                        System.out.println("BEFORE_PROBE: acceptingResponses = " + 
-                                           acceptingResponses); 
-                    if (acceptingResponses == true) 
+		    debug("BEFORE_PROBE: acceptingResponses = " + acceptingResponses); 
+                    if (acceptingResponses) {
                         exp.getCurrentBlock().addResponse(0, System.nanoTime());
+			debug("Recording zero response");
+		    }
                     else 
                         setAcceptingResponses(true);
                     //tick(nMinutes); 
@@ -212,33 +255,30 @@
                 case PROBE:
                 case PROBE_EX:
                 case PROBE_UNEX:
-                    if (exp.getDebug())
-                        System.out.println("PROBE_{UN,}EX: acceptingResponses = " 
-                                           + acceptingResponses); 
+		    debug("PROBE_{UN,}EX: acceptingResponses = " + acceptingResponses); 
                     clock.showFullClock = false; 
                     clock.repaint(); 
                     break; 
                 case AFTER_PROBE: 
-                    //clock.showFullClock = false; 
-                    //clock.repaint(); 
-                    //showFixationPoint(); 
+                    showFixationPoint(); 
                     break; 
                 default: 
                     System.out.println("Unexpected probe id: " + probe); 
                     break; 
                 }
-                // Update probe identifier and onset 
+            } 
 
-                if (exp.getDebug())
-                    System.out.println("Next probe = " + probe);
-                nextEventOnset =((Long)(oi.next())).longValue();
-            } 
-            // sleep for a tatum 
+            // Sleep for tatum 
             try { Thread.sleep(tatumInMilliseconds); }
             catch (InterruptedException e) {}
-            currentOnset += tatum; 
-            clockUnit = (clockUnit + 1) % clockUnits; 
+            currentTime += tatum; 
+            clockUnit = (clockUnit + 1) % exp.getClockUnits(); 
+
         } while(oi.hasNext());
+
         showFixationPoint(); 
     }
+
+
+
 }
Binary file StimulusPanel.class has changed
--- a/StimulusPanel.java	Mon Nov 12 22:34:52 2012 +0000
+++ b/StimulusPanel.java	Mon Nov 12 22:48:39 2012 +0000
@@ -178,4 +178,16 @@
             responseButton[i].addKeyListener(al); 
         }
     }
+
+    public void setResponseEnabled(boolean set) {
+	for (int i = 0; i < responseButton.length; i++) {
+	    responseButton[i].setEnabled(set);
+	}
+    }
+
+    public void highlightResponse(int buttonIndex) {
+	responseButton[buttonIndex].setBackground(Color.blue);
+	responseButton[buttonIndex].setOpaque(true);
+    }
+
 }