view ExperimentController.java @ 39:796b3e3e053f

Changed MidiPlayer.java to allow the use of external sequencer programs (e.g. Garageband). Changed Experiment.java to allow user to specify in commandline whether to use default MidiDevice (true), specified MidiDevice (0<variable<MidiDevs.length), or list the available devices on start up. Changed ExperimentGui.java and SubjectDataPanel.java to add familiarity question if familiarity question isn't included at the presentation of each stimuli.
author CBussey
date Fri, 31 May 2013 17:40:59 +0100
parents 0e030f32a6e2
children d3977e825d91
line wrap: on
line source
/*=============================================================================
 * File:       ExperimentController.java
 * Author:     Marcus Pearce <m.pearce@gold.ac.uk>
 * Created:    <2007-12-14 12:06:10 marcusp>
 * Time-stamp: <2011-11-10 19:08:45 marcusp>
 *=============================================================================
 */

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class ExperimentController implements ActionListener, KeyListener { 
    
    /* variables */ 
    ExperimentGui gui;

    Experiment exp; 
    SubjectResults results; 

    InstructionsPanel ip; 
    StimulusPanel sp; 
    SubjectDataPanel sdp; 
    InterBlockPanel ibp;
    
    /* constructor */ 
    public ExperimentController(ExperimentGui eg) { 
        gui = eg; 
        exp = gui.getExperiment(); 
        results = exp.getSubjectResults(); 

        ip = gui.getInstructionsPanel(); 
        ibp = gui.getInterBlockPanel(); 
        sp = gui.getStimulusPanel();         
        sdp = gui.getSubjectDataPanel(); 

        ip.addNextButtonListener(this); 
        sp.addAllListeners(this);
        sdp.addFinishButtonListener(this); 
        ibp.addContinueButtonListener(this); 

        sp.setFocusable(true);
        sp.addKeyListener(this);
        sp.addAllKeyListeners(this);
        gui.setFocusable(true);
        gui.addKeyListener(this);
    }

    /* report erroneous input */ 
    protected void reportError (String msg) {
        JOptionPane.showMessageDialog (gui, msg);
    }

    /* actionPerformed */ 
    public void actionPerformed(ActionEvent e) {
        long time = System.nanoTime(); 
        Object source = e.getSource();

        ip = gui.getInstructionsPanel(); 
        ibp = gui.getInterBlockPanel(); 
        sp = gui.getStimulusPanel();         
        sdp = gui.getSubjectDataPanel(); 
 
        Block block = exp.getCurrentBlock(); 

        // InstructionsPanel 
        if (source == ip.getNextButton()) { 
            String subjID = ip.getSubjectID(); 
            if (subjID.equals(ip.INVALID_SUBJECT_ID))
                reportError("The participant ID should contain only letters and numbers.");
            // TODO: check that subjID doesn't already exist
            else { 
                exp.setSubjectID(subjID); 
                gui.showCard("stimulus");
                exp.runExperiment();  
            }
        }

        // InterBlockPanel
        else if (source == ibp.getContinueButton()) { 
            block.initialiseBlock();
            sp.setSongNumberText(); 
            sp.defaultAnswers(); 
            gui.setAcceptingResponses(false); 
            gui.showCard("stimulus"); 
            exp.runExperiment();  
        }
         
       // SubjectDataPanel
        else if (e.getSource() == sdp.getFinishButton()) { 
            if (exp.getFinalQuestionnaire()) {
                if (sdp.allDataEntered()) { 
                    sdp.storeData(); 
                    results.writeSubjectData(); 
                    System.exit(0); 
                } else 
                    reportError("You have not filled in all the information."); 
            } else 
                System.exit(0); 
        }

        // StimulusPanel
        else if (source == sp.getPlayButton()) {
//             if (!exp.isRunning() && !exp.hasRun())
//                 exp.runExperiment(); 
//             else 
//                 reportError("You have already played the melody.");
        } else if (source == sp.getNextButton()) { 
            if (!exp.hasRun() || exp.isRunning()) {
		//System.out.println(!exp.hasRun());
		//System.out.println(exp.isRunning());
		//System.out.println(exp.getCurrentBlock().getMidiPlayer().getSequencer().isRunning());
                reportError("You haven't finished playing the melody yet."); 

            } else if (exp.getCurrentBlock().getMelodyResults().countResponses() == 0) {
                reportError("Please select a number."); 

            } else if (sp.unansweredQuestions())
                reportError("There are unanswered questions."); 
            else {  
                // store results (and write to file)
                if (exp.getAskFamiliarity()) {
                    String answer1 = (String)(sp.getQ1Box().getSelectedItem()); 
                    block.addMelodyQA("known", answer1); 
                } else 
                    block.addMelodyQA("known", "-1");
                if (exp.getAskLiking()) {
                    String answer2 = (String)(sp.getQ2Box().getSelectedItem()); 
                    block.addMelodyQA("liked", answer2); 
                } else 
                    block.addMelodyQA("liked", "-1");
                block.storeMelodyResult();
                results.writeResults();
                // close the midi player
                block.getMidiPlayer().stop();
                // proceed to ... 
                
                String nextFile = block.nextFile();
                if (nextFile == null) { 
                    boolean nb = exp.nextBlock(); 
                    if (nb) { 
                        // ... next block of trials 
                        gui.getInterBlockPanel().setText(); 
                        gui.getInterBlockPanel().updateMessageDisplay(); 
                        gui.showCard("interblock"); 
                        sp.resetButtonBackgrounds();
                    } else {
                        // ... write results and subject questionnaire 
                        results.writeResults();
                        gui.showCard("subject"); 
                    }
                } else { 
                    // ... next melody within block
                    sp.resetButtonBackgrounds();
                    sp.setSongNumberText(); 
                    sp.defaultAnswers(); 
                    gui.setAcceptingResponses(false); 
                    block.initialiseBlock(); 
                    exp.runExperiment(); 

                }
            }
        } 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++) { 
                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)  {
        if (exp.getDebug())
	    System.out.println("Key pressed: " + e.getKeyChar());
        long time = System.nanoTime();

        Block block = exp.getCurrentBlock();
        sp = gui.getStimulusPanel();
        JButton[] rButtons = sp.getResponseButtons();

        if ((exp.isRunning() || exp.hasRun()) && gui.getAcceptingResponses()) {
            if (exp.getScaleLength() == 2) {
                char key = e.getKeyChar();                
                switch(key) {
                case 'q': block.addResponse(1, time); break;
                case 'p': block.addResponse(2, time); break;
                default: System.out.println("No Response at " + time); break;
                }
            } else {
                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);
                }
            }
        }
    }

    public void keyReleased(KeyEvent e)  {
        // System.out.println("Key released: " + e.getKeyChar());
    }
    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); 
    }
}