Mercurial > hg > mep
view ExperimentGui.java @ 47:be66ee2fe9fe
Added abstract class EndBlockPanel to deliver end of block messages (e.g. end of practice block).
Added and implemented EndTestPanel which gives "thank you for participating" etc message at end of test.
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Thu, 13 Jun 2013 18:33:34 +0100 |
parents | 75354c638975 |
children | 67ab1d1f9a87 |
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: <2011-11-04 17:41:45 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); //tick(nMinutes); clockTicking = false; break; case PROBE: case PROBE_EX: case PROBE_UNEX: debug("PROBE_{UN,}EX: acceptingResponses = " + acceptingResponses); clock.showFullClock = false; clock.repaint(); break; case AFTER_PROBE: showFixationPoint(); 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(); } }