package edu.harvard.econcs.turkserver.client; import java.rmi.RemoteException; import javax.swing.JOptionPane; import edu.harvard.econcs.turkserver.Codec; import edu.harvard.econcs.turkserver.LobbyUpdateResp; import edu.harvard.econcs.turkserver.Messages; import edu.harvard.econcs.turkserver.QuizFailException; import edu.harvard.econcs.turkserver.QuizMaterials; import edu.harvard.econcs.turkserver.SessionCompletedException; import edu.harvard.econcs.turkserver.SessionExpiredException; import edu.harvard.econcs.turkserver.SessionOverlapException; import edu.harvard.econcs.turkserver.SessionUnknownException; import edu.harvard.econcs.turkserver.SimultaneousSessionsException; import edu.harvard.econcs.turkserver.TooManyFailsException; import edu.harvard.econcs.turkserver.TooManySessionsException; import edu.harvard.econcs.turkserver.api.ClientError; import edu.harvard.econcs.turkserver.api.ClientLobbyController; import edu.harvard.econcs.turkserver.api.ExperimentClient; import edu.harvard.econcs.turkserver.api.FinishExperiment; import edu.harvard.econcs.turkserver.api.JoinLobby; import edu.harvard.econcs.turkserver.api.QuizAttempt; import edu.harvard.econcs.turkserver.api.RequestUsername; import edu.harvard.econcs.turkserver.api.StartExperiment; import edu.harvard.econcs.turkserver.api.UpdateLobby; /** * Base GUI client for old stuff such as graph coloring. * TODO needs to be rethought. * * @author mao * */ @ExperimentClient public abstract class AbstractGraphicalClient<GC extends GUIController> { protected ClientLobbyController cont; protected GC gc; public AbstractGraphicalClient(ClientLobbyController cont) { this.cont = cont; } public void setGC(GC gc) { this.gc = gc; } @QuizAttempt public void takeQuiz(QuizMaterials qm) { QuizResults qr = gc.doQuiz(qm); cont.sendQuizResults(qr); } @RequestUsername public void requestUsername() { gc.setStatus("Waiting for nickname..."); String username = null; do { username = gc.questionMsg("Enter a nickname for yourself:"); } while ( "".equals(username) ); gc.setStatus("Sending nickname to server..."); cont.sendUsername(username); } @JoinLobby public void joinLobby() { gc.setStatus("Connected to lobby"); } @UpdateLobby public void updateLobby(Object data) { // TODO update the format of this for new data format LobbyUpdateResp lup = (LobbyUpdateResp) data; gc.getLobby().updateModel(lup); gc.setStatus(lup.joinEnabled ? StatusBar.lobbyReadyMsg : StatusBar.lobbyWaitingMsg ); } @StartExperiment public void startExperiment() { gc.setStatus("Connecting to game"); gc.setStatus(StatusBar.enteringExpMsg); gc.experimentRedraw(); } @FinishExperiment public void finishExperiment() { gc.setStatus(StatusBar.finishedExpMsg); } @ClientError public void gotError(String msg) { if( Codec.status_expfinished.equals(msg) ) { // Connected to exp that is already finished. Enable the submit. // TODO fix this if want to allow view graph for finished exp gc.blankRedraw("Experiment already finished"); gc.setStatus("Experiment already finished."); gc.popMsg("This experiment is already finished.\n" + "Please submit the HIT below."); enableSubmit(); } else if( Codec.startExpError.equals(msg) ) { // Server unilaterally disabled due to error, disable join button gc.getLobby().setJoinEnabled(false); gc.popMsg("Unable to start experiment!" + "There might be a problem with the server." + "You may try again, or just return the HIT.", "Internal Server Error", JOptionPane.ERROR_MESSAGE); } else if( Codec.status_batchfinished.equals(msg) ) { gc.blankRedraw("All games finished"); gc.setStatus(StatusBar.batchFinishedMsg); gc.popMsg("All games for this batch have been completed.\n" + "If you have signed up for notifications, we will let you know\n" + "when we post more games. Please return the HIT.", "Game Batch Completed", JOptionPane.WARNING_MESSAGE); } // TODO connect/handshake error gc.blankRedraw("Unable to connect"); gc.setStatus("Unable to connect to server"); gc.popMsg(Messages.CONNECT_ERROR, "Connection Error", JOptionPane.ERROR_MESSAGE); // TODO if the server disconnects gc.blankRedraw("Server disconnected"); gc.setStatus("Server disconnected"); gc.popMsg(Messages.SERVER_DISCONNECTED, "Server Disconnected", JOptionPane.WARNING_MESSAGE); // TODO arbitrary errors gc.blankRedraw("Connection Error"); gc.setStatus("Connection Error."); gc.popMsg("There was an error connecting to the server.\n" + "Please refresh the page to try again, or return the HIT."); // Random error messages for later refactoring // Get the cause of the server-side Remote Exception Throwable t = new RemoteException().getCause().getCause(); gc.blankRedraw("Authentication error"); gc.setStatus("Session authentication error"); if( t instanceof SessionUnknownException ) { gc.popMsg(Messages.UNRECOGNIZED_SESSION, "Unrecognized Session ID", JOptionPane.ERROR_MESSAGE); } else if (t instanceof SimultaneousSessionsException) { gc.popMsg(Messages.SIMULTANEOUS_SESSIONS, "Too Many Games Open", JOptionPane.WARNING_MESSAGE); } else if (t instanceof SessionExpiredException ) { // TODO this message is the same as above, except on connect gc.popMsg(Messages.EXPIRED_SESSION, "Game Batch Completed", JOptionPane.INFORMATION_MESSAGE); } else if (t instanceof TooManySessionsException) { gc.popMsg(Messages.TOO_MANY_SESSIONS, "Game Limit Hit", JOptionPane.INFORMATION_MESSAGE); } else if (t instanceof SessionOverlapException ) { gc.popMsg(Messages.SESSION_OVERLAP, "Session Already Used", JOptionPane.WARNING_MESSAGE); } else if (t instanceof SessionCompletedException) { gc.popMsg(Messages.SESSION_COMPLETED, "Session Already Completed", JOptionPane.WARNING_MESSAGE); gc.setStatus("Experiment already finished!"); enableSubmit(); } else if (t instanceof QuizFailException) { gc.popMsg(Messages.QUIZ_FAILED, "Quiz Failed!", JOptionPane.WARNING_MESSAGE); gc.blankRedraw("Quiz Failed!"); gc.setStatus("Quiz Failed!"); } else if (t instanceof TooManyFailsException) { gc.blankRedraw("Too Many Failed Quizzes!"); gc.popMsg(Messages.TOO_MANY_FAILS, "Too Many Fails!", JOptionPane.WARNING_MESSAGE); gc.setStatus("Too many times failed, please come back later!"); } else { t.printStackTrace(); gc.popMsg("Unknown error, please report this and return the HIT, " + "or try a different HIT: \n" + t.toString(), "Unknown error", JOptionPane.ERROR_MESSAGE); } // After connect to server, Draw the lobby gc.lobbyRedraw(); } /** * Enable the HIT to be submitted */ protected abstract void enableSubmit(); }