m@0: /*============================================================================= m@0: * File: ExperimentGui.java m@0: * Author: Marcus Pearce m@0: * Created: <2007-02-14 16:42:31 marcusp> m@0: * Time-stamp: <2010-05-18 11:12:05 marcusp> m@0: *============================================================================= m@0: */ m@0: m@0: import java.awt.*; m@0: import javax.swing.*; m@0: import java.util.ArrayList; m@0: import java.util.Iterator; m@0: m@0: public class ExperimentGui extends JFrame implements Runnable { m@0: m@0: /* the Experiment */ m@0: private Experiment exp; m@0: m@0: /* The visual display indicating probe positions */ m@0: private Clock clock; m@0: m@0: /* The UI components */ m@0: private JPanel mainPanel; m@0: private InstructionsPanel instructionsPanel; m@0: private StimulusPanel stimulusPanel; m@0: private SubjectDataPanel subjectDataPanel; m@0: private InterBlockPanel interBlockPanel; m@0: m@0: /* Whether we are accepting responses */ m@0: private Boolean acceptingResponses; m@0: m@0: /* accessors */ m@0: public Boolean getAcceptingResponses() { return acceptingResponses; } m@0: public void setAcceptingResponses(Boolean b) { acceptingResponses = b; } m@0: public Experiment getExperiment() { return exp; } m@0: public InstructionsPanel getInstructionsPanel() { return instructionsPanel; } m@0: public StimulusPanel getStimulusPanel() { return stimulusPanel; } m@0: public SubjectDataPanel getSubjectDataPanel() { return subjectDataPanel; } m@0: public InterBlockPanel getInterBlockPanel() { return interBlockPanel; } m@0: m@0: /* Constructor */ m@0: public ExperimentGui(Experiment experiment) { m@0: m@0: // initialise experiment m@0: exp = experiment; m@0: acceptingResponses = false; m@0: m@0: // set up the clock m@0: clock = new Clock(); m@0: m@0: // construct the frame m@0: JFrame.setDefaultLookAndFeelDecorated(true); m@0: this.getContentPane().setBackground (Color.black); m@0: this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE); m@0: this.setLayout (new BorderLayout()); m@0: m@0: // The different cards m@0: instructionsPanel = new InstructionsPanel(this); m@0: stimulusPanel = new StimulusPanel(this, clock); m@0: interBlockPanel = new InterBlockPanel(exp); m@0: subjectDataPanel = new SubjectDataPanel(this, exp.getSubjectResults()); m@0: m@0: // The Controller m@0: ExperimentController ec = new ExperimentController(this); m@0: m@0: // Show it all m@0: CardLayout cl = new CardLayout(); m@0: mainPanel = new JPanel(cl); m@0: mainPanel.add(instructionsPanel, "instructions"); m@0: mainPanel.add(interBlockPanel, "interblock"); m@0: mainPanel.add(stimulusPanel, "stimulus"); m@0: mainPanel.add(subjectDataPanel, "subject"); m@0: m@0: this.add(mainPanel, BorderLayout.CENTER); m@0: } m@0: m@0: /* m@0: * Methods for changing displayed card m@0: */ m@0: m@0: public void showCard(String card) { m@0: CardLayout cl = (CardLayout)(mainPanel.getLayout()); m@0: cl.show(mainPanel, card); m@0: } m@0: m@0: public void nextCard() { m@0: CardLayout cl = (CardLayout)(mainPanel.getLayout()); m@0: cl.next(mainPanel); m@0: } m@0: m@0: /* Advance clock by 1 minute and redisplay. */ m@0: public void tick(int n) { m@0: clock.tick(n); m@0: clock.repaint(); m@0: } m@0: m@0: /* Show the Clock */ m@0: public void showClock() { m@0: clock.showClock = true; m@0: clock.showFullClock = false; m@0: clock.repaint(); m@0: } m@0: m@0: /* Show the Fixation Point */ m@0: public void showFixationPoint() { m@0: clock.showClock = false; m@0: clock.showFullClock = false; m@0: clock.repaint(); m@0: } m@0: m@0: /* Run clock for r revolutions at a rate of 1 minute (6 degrees) m@0: * every n milliseconds. m@0: */ m@0: public void runClock(int r, long n) { m@0: clock.reset(); m@0: showClock(); m@0: for (int i = 0; i < (60 * r); i++) { m@0: try { Thread.sleep (n); } catch (InterruptedException e) {} m@0: clock.tick(1); m@0: clock.repaint(); m@0: } m@0: try { Thread.sleep (1000); } catch (InterruptedException e) {} m@0: showFixationPoint(); m@0: } m@0: m@0: /* Run method for this thread */ m@0: public void run() { m@0: m@0: //showFixationPoint(); m@0: clock.reset(); m@0: showClock(); m@0: m@0: int clockUnits = exp.getClockUnits(); m@0: int numUnits = exp.getNumUnits(); m@0: long tatum = exp.getCurrentBlock().getTatum(); m@0: long tatumInMilliseconds = tatum / 1000; m@0: int nMinutes = 60 / numUnits; m@0: m@0: ArrayList onsets = exp.getCurrentBlock().getOnsets(); m@0: ArrayList probes = exp.getCurrentBlock().getProbePositions(); m@0: ArrayList clockStartTimes = exp.getCurrentBlock().getClockStartTimes(); m@0: m@0: Iterator oi = onsets.iterator(); m@0: Iterator pi = probes.iterator(); m@0: Iterator ci = clockStartTimes.iterator(); m@0: m@0: ProbeID probe = ProbeID.NOT_PROBE; m@0: m@0: long currentOnset = 0; m@0: long nextEventOnset = ((Long)(oi.next())).longValue(); m@0: long nextClockStartTime = ((Long)(ci.next())).longValue(); m@0: m@0: int clockUnit = 0; m@0: boolean clockTicking = false; m@0: m@0: while(oi.hasNext()) { m@0: //System.out.println("Ticking = " + clockTicking + m@0: // "; clockUnit = " + clockUnit); m@0: if (clockTicking == true && clockUnit == 0) m@0: tick(nMinutes); m@0: m@0: if (currentOnset == nextClockStartTime) { m@0: //new Thread(clock).start(); m@0: clock.reset(); m@0: showClock(); m@0: clockTicking = true; m@0: if (ci.hasNext()) m@0: nextClockStartTime = ((Long)(ci.next())).longValue(); m@0: } m@0: m@0: if (currentOnset == nextEventOnset) { m@0: // Manipulate display depending on probe identifier m@0: switch (probe) { m@0: case NOT_PROBE: m@0: // if (clock.showClock == true) m@0: // tick(nMinutes); m@0: break; m@0: case START_CLOCK: m@0: //clock.reset(); m@0: //showClock(); m@0: //tick(nMinutes); m@0: break; m@0: case BEFORE_PROBE: m@0: //System.out.println("BEFORE_PROBE: acceptingResponses = " + m@0: // acceptingResponses); m@0: if (acceptingResponses == true) m@0: exp.getCurrentBlock().addResponse(0, System.nanoTime()); m@0: else m@0: acceptingResponses = true; m@0: //tick(nMinutes); m@0: clockTicking = false; m@0: break; m@0: case PROBE: m@0: case PROBE_EX: m@0: case PROBE_UNEX: m@0: //System.out.println("PROBE_{UN,}EX: acceptingResponses = " m@0: // + acceptingResponses); m@0: clock.showFullClock = false; m@0: clock.repaint(); m@0: break; m@0: case AFTER_PROBE: m@0: //clock.showFullClock = false; m@0: //clock.repaint(); m@0: //showFixationPoint(); m@0: break; m@0: default: m@0: System.out.println("Unexpected probe id: " + probe); m@0: break; m@0: } m@0: // Update probe identifier and onset m@0: probe = (ProbeID)pi.next(); m@0: nextEventOnset =((Long)(oi.next())).longValue(); m@0: } m@0: // sleep for a tatum m@0: try { Thread.sleep(tatumInMilliseconds); } m@0: catch (InterruptedException e) {} m@0: currentOnset += tatum; m@0: clockUnit = (clockUnit + 1) % clockUnits; m@0: } m@0: showFixationPoint(); m@0: } m@0: }