JCurses - suite
Bon finalement j'ai fait un truc assez sympa et je le met ici pour backup =)
Mon idée c'était de faire un ApplicationController sur lequel on puisse faire par exemple:
//Pour démarrer l'appli : ApplicationController.start(); //En réaction a une action : ApplicationController.action(getClass(), "back");
Pour ça il faut pourvoir définir des scénarii ... Les scnéarii définissent de ou vers ou et avec quoi comme action ! L'idéal serait de pouvoir loader les scenarii d'une DB ou d'un fichier XML peu importe, mais surtout de ne pas avoir a se préocuper de ça maintenant ... Alors premièrement :
public interface ScenarioLoader { public Scenario load() throws Exception; }
Voila ça c'est fait ... définissons notre Scenario :
public class Scenario { private String init; private Hashtable all; private boolean end; public Scenario() { all = new Hashtable(); end = false; } public void addLink(String from, String action, String to) { if (!all.containsKey(from)) { all.put(from, new Hashtable()); } Hashtable assoc = (Hashtable)all.get(from); assoc.put(action, to); } public String getLink(String from, String action) { if (!all.containsKey(from)) { return null; } Hashtable assoc = (Hashtable)all.get(from); if (!assoc.containsKey(action)) { if (assoc.containsKey("*")) { action = "*"; } else { return null; } } String to = (String)assoc.get(action); if (to == null) { return null; } if (to.toUpperCase().equals("END")) { end = true; return null; } return to; } public String getInit() { return init; } public void setInit(String init) { this.init = init; } public boolean end() { return end; } public void setEnd() { end = true; } public String toString() { StringBuffer buf = new StringBuffer(""); for (Enumeration en = all.keys(); en.hasMoreElements(); ) { String key = (String)en.nextElement(); buf.append("-- " + key + " --\n"); Hashtable assoc = (Hashtable)all.get(key); for (Enumeration enn = assoc.keys(); enn.hasMoreElements(); ) { String action = (String)enn.nextElement(); buf.append("\t"+action+" ==> "+assoc.get(action)+"\n"); } } return buf.toString(); } }
Bon la on a une panoplie d'options ... On peut terminer le scénario, l'afficher ... Lui donner un point de départ ajouter et retirer des liens ... Notez que j'ai mis des strings, on gère ça comme on veut après !
Du coup je peux faire un Scenario bidon :
public class TestScenarioLoader implements ScenarioLoader { public Scenario load() throws Exception { Scenario sc = new Scenario(); sc.setInit(StartWindow.class.getName()); sc.addLink(StartWindow.class.getName(), "export", ExportWindow.class.getName()); sc.addLink(StartWindow.class.getName(), "validate", ValidateWindow.class.getName()); sc.addLink(ExportWindow.class.getName(), "back", StartWindow.class.getName()); return sc; } }
Voila ... tout simple et je m'ocuperai de le loader une autre fois !
Reste plus qu'a définir l'ApplicationController qui va faire la glue la dedan et assurer la cohérence des vues ! Pour ça on va définir un singleton basique avec un host poure toutes les vues et un host pour le scénario ... Dans l'imédiat on load un scénar de test on verra plus tard pour les fioritures :
public class ApplicationController { private Scenario scenario = null; private Hashtable views = null; private static ApplicationController instance = null; public static ApplicationController getInstance() { if (instance == null) { instance = new ApplicationController(); } return instance; } public ApplicationController() { try { ScenarioLoader loader = new TestScenarioLoader(); scenario = loader.load(); views = new Hashtable(); } catch (Exception e) { e.printStackTrace(); } } public Scenario getScenario() { return scenario; } public Hashtable getViews() { return views; }
Voila ensuite il faut qu'on puisse le démarer facilement et que la page d'initialisation soit créée...
public static void start() { Scenario sc = getInstance().getScenario(); Hashtable views = getInstance().getViews(); try { Window w = (Window)Class.forName(sc.getInit()).newInstance(); w.show(); views.put(sc.getInit(), w); while (!sc.end()) { Thread.sleep(1000); } } catch (Exception e) { e.printStackTrace(); } }
Puis les actions doivent utiliser le scénario pour afficher les pages:
public static void action(Class from, String action) { Scenario sc = getInstance().getScenario(); Hashtable views = getInstance().getViews(); String next = sc.getLink(from.getName(), action); if (next == null) { sc.setEnd(); return; } else { try { Window w = null; /*- get next window -*/ if (views.containsKey(next)) { w = (Window)views.get(next); } else { w = (Window)Class.forName(next).newInstance(); views.put(next, w); } /*- show this window -*/ w.show(); w.moveToTheTop(); } catch (Exception e) { e.printStackTrace(); } } }
Voila tout bidon ! Ca nous donne quoi dans la vue ?
public void actionPerformed(ActionEvent event) { if (event.getSource() instanceof Button) { Button button = (Button) event.getSource(); if (button.getLabel().startsWith("Validate")) { ApplicationController.action(getClass(), "validate"); } else { ApplicationController.action(getClass(), "export"); } } }
Et notre main :
public static void main(String[] args) { ApplicationController.start(); }
Voila ... je pense pas qu'on puisse faire plus simple et plus fonctionnel à la fois ! Ou si on peut, dites moi comment j'adore en savoir davantage !!!!
