package StevensLevel; import StevensLevel.events.ScreenChange; import StevensLevel.listeners.ScreenChangeListener; import StevensLevel.listeners.ScreenNotificationListener; import interaction.ExperimentInteraction; import interaction.InteractionReactor; import java.lang.Class; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import static StevensLevel.EventBusHelper.*; import screens.AbstractStrictScreen; import screens.Screen; /** * * @author Tristan Goffman(tgoffman@gmail.com) Jul 17, 2011 */ public class ViewControl extends WithInterationReactorImpl implements InteractionReactor, ScreenChangeListener { protected View view; public static enum UIInteraction implements ExperimentInteraction { Screen, Close } public View getView() { return view; } private Map<Class, AbstractStrictScreen> screens = new HashMap<Class, AbstractStrictScreen>(); private AbstractStrictScreen currScreen = null; //The screen currently showing to the testee/participant public ViewControl() { this.view = new View(); //Single Jframe where viewable portions of experiment will be rendered listen(this, ScreenChangeListener.class); } boolean addScreen(AbstractStrictScreen scr) { //NOTE: Only allowing for one screen for each class to be added (singleon screens as you would) -- forcing update of pre-existing screen instead //of addition of new screen if (!screens.containsValue(scr)) { screens.put(scr.getClass(), scr); } return false; } Collection<AbstractStrictScreen> getScreens() { return screens.values(); } void setScreen(Class<? extends AbstractStrictScreen> aClass) { AbstractStrictScreen scr = screens.get(aClass); if (scr == null) { throw new RuntimeException("Tried to switch to non-existing screen in ViewControl"); } this.view.setScreen(scr); } boolean isVisible() { return getScreen() != null; } protected AbstractStrictScreen getScreen() { return currScreen; } @Override public void changeScreen(ScreenChange chg) { changeScreen(chg.getScreenClass()); } public void changeScreen(Class<? extends Screen> clazz){ setNewScreen(clazz); pb(this, ScreenNotificationListener.class).screenIsReady(clazz); } /** * Takes a payload attempts to cast to a class (AbstractStrictScreen class), creates a new instance if current screen is already of type supplied, and then updates the screen *Otherwise does nothing. * @param payload */ private void setNewScreen(Object payload) { Class<? extends AbstractStrictScreen> scrClazz = (Class<? extends AbstractStrictScreen>) payload; try { if (currScreen == null || !(scrClazz == currScreen.getClass())){ currScreen = scrClazz.newInstance(); view.setScreen(currScreen); view.update(); } } catch (Exception ex) { Logger.getLogger(ViewControl.class.getName()).log(Level.SEVERE, null, ex); } } }