view ExperimentGui.java @ 51:67ab1d1f9a87

Show Clock right until midnight (not 9am).
author Marcus Pearce <marcus.pearce@eecs.qmul.ac.uk>
date Wed, 25 Feb 2015 10:10:28 +0000
parents be66ee2fe9fe
children
line wrap: on
line source
/*=============================================================================
 * File:       ExperimentGui.java
 * Author:     Marcus Pearce <m.pearce@gold.ac.uk>
 * Created:    <2007-02-14 16:42:31 marcusp>
 * Time-stamp: <2015-02-25 10:07:48 marcusp>
 *=============================================================================
 */

import java.awt.*;
import javax.swing.*;
import java.util.ArrayList; 
import java.util.Iterator;

public class ExperimentGui extends JFrame implements Runnable {
    
    /* the Experiment */ 
    private Experiment exp; 

    /* The visual display indicating probe positions */ 
    private Clock clock; 

    /* The UI components */ 
    private JPanel mainPanel; 
    private InstructionsPanel instructionsPanel;
    private StimulusPanel stimulusPanel; 
    private SubjectDataPanel subjectDataPanel; 
    private InterBlockPanel interBlockPanel;
    private EndTestPanel endTestPanel;
    
    /* Whether we are accepting responses */ 
    private Boolean acceptingResponses; 
    
    /* accessors */ 
    public Boolean getAcceptingResponses() { return acceptingResponses; }
    public void setAcceptingResponses(Boolean 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; }
    public StimulusPanel getStimulusPanel() { return stimulusPanel; } 
    public SubjectDataPanel getSubjectDataPanel() { return subjectDataPanel; }
    public InterBlockPanel getInterBlockPanel() { return interBlockPanel; }
    public EndTestPanel getEndTestPanel() { return endTestPanel; }
    
    /* Constructor */ 
    public ExperimentGui(Experiment experiment) {

        
        
        // initialise experiment 
        exp = experiment; 
        acceptingResponses = false; 

        // set up the clock 
        clock = new Clock(exp.getDebug()); 
        
        // construct the frame
        JFrame.setDefaultLookAndFeelDecorated(true);
        this.getContentPane().setBackground (Color.black);
        this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        this.setLayout (new BorderLayout());
                
        // The different cards 
        instructionsPanel = new InstructionsPanel(this);
        stimulusPanel = new StimulusPanel(this, clock); 
        interBlockPanel = new InterBlockPanel(exp);
        endTestPanel = new EndTestPanel(exp);
        subjectDataPanel = new SubjectDataPanel(this, exp.getSubjectResults(), !exp.getAskFamiliarity());

	stimulusPanel.setResponseEnabled(false);
        
        // The Controller 
        ExperimentController ec = new ExperimentController(this); 

        // Show it all 
        CardLayout cl = new CardLayout(); 
        mainPanel = new JPanel(cl); 
        mainPanel.add(instructionsPanel, "instructions"); 
        mainPanel.add(interBlockPanel, "interblock");
        mainPanel.add(endTestPanel, "endTest");
        mainPanel.add(stimulusPanel, "stimulus"); 
        mainPanel.add(subjectDataPanel, "subject"); 

        this.add(mainPanel, BorderLayout.CENTER);
    }

    /* 
     * Methods for changing displayed card 
     */ 
    
    public void showCard(String card) { 
        CardLayout cl = (CardLayout)(mainPanel.getLayout());
        cl.show(mainPanel, card);
    }

    public void nextCard() { 
        CardLayout cl = (CardLayout)(mainPanel.getLayout());
        cl.next(mainPanel); 
    }
    
    /* Advance clock by 1 minute and redisplay. */
    public void tick(int n) {
        clock.tick(n);
        clock.repaint();
    }

    /* Show the Clock */ 
    public void showClock() { 
        if (exp.showClock()) {
            clock.showClock = true;
            clock.showFullClock = false; 
            clock.repaint();
        }
    } 

    /* Show the Fixation Point */ 
    public void showFixationPoint() { 
        debug("showFixationPoint");
        clock.showClock = false; 
        clock.showFullClock = false; 
        clock.repaint(); 
    } 
    
    /* Run clock for r revolutions at a rate of 1 minute (6 degrees)
     * every n milliseconds. 
     */
    //public void runClock(int r, long n) {
    //    clock.reset(); 
    //    showClock(); 
    //    for (int i = 0; i < (60 * r); i++) {
    //        try { Thread.sleep (n); } catch (InterruptedException e) {}
    //           clock.tick(1);
    //           clock.repaint();
    //    }
    //    try { Thread.sleep (1000); } catch (InterruptedException e) {}
    //    showFixationPoint(); 
    //}
    

    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() { 

	boolean debug = exp.getDebug();

	debug("\nBegin trial");
        //showFixationPoint(); 
        clock.reset(); 
        showClock(); 

        long tatum = exp.getCurrentBlock().getTatum(); 
        long tatumInMilliseconds = tatum / 1000; 
        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 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...
	    
	    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); 
	    }
            
	    // 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 
                    nextClockStartTime = Long.MAX_VALUE;
            }

	    // 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) 
                    //    tick(nMinutes); 
                    break; 
		    /* 
                case START_CLOCK:  // No longer used...
                    //clock.reset(); 
                    //showClock(); 
                    //tick(nMinutes); 
                    break; 
		    */
                case BEFORE_PROBE:
		    debug("BEFORE_PROBE: acceptingResponses = " + acceptingResponses); 
                    if (acceptingResponses) {
                        exp.getCurrentBlock().addResponse(0, System.nanoTime());
			debug("Recording zero response");
		    }
                    else 
                        setAcceptingResponses(true);
                    clock.showFullClock = true;
                    clock.repaint();
                    break; 
                case PROBE:
                case PROBE_EX:
                case PROBE_UNEX:
		    debug("PROBE_{UN,}EX: acceptingResponses = " + acceptingResponses); 
                    clock.showFullClock = true; 
                    clock.repaint(); 
                    break; 
                case AFTER_PROBE: 
                    showFixationPoint(); 
                    clock.showFullClock = false;
                    clockTicking = false;
                    break; 
                default: 
                    System.out.println("Unexpected probe id: " + probe); 
                    break; 
                }
            } 

            // Sleep for tatum 
            try { Thread.sleep(tatumInMilliseconds); }
            catch (InterruptedException e) {}
            currentTime += tatum; 
            clockUnit = (clockUnit + 1) % exp.getClockUnits(); 

        } while(oi.hasNext());

        showFixationPoint(); 
    }



}