Mercurial > hg > mep
view ExperimentGui.java @ 45:351b0c8b34ac
Fixed issue where error message was shown every time the user chose to move continue using the keyboard.
Fixed issue where data wasn't saving to file after questionaire.
Changed SubjectData output filename to "<Participant ID>_qu.dat" (previously was "subjects.dat". Would have been overwritten as wasn't dynamic.
author | Carl Bussey <c.bussey@se10.qmul.ac.uk> |
---|---|
date | Sun, 09 Jun 2013 22:06:52 +0100 |
parents | 75354c638975 |
children | be66ee2fe9fe |
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; /* 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; } /* 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); 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(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(); } }