Interfaccia grafica

    Inizialmente per costruire velocemente una interfaccia per i nostri interpreti abbiamo deciso di sfruttare la shell del DOS. Ci siamo stupiti quando ci siamo accorti che già così si avevano notevoli funzionalità (almeno sotto windows NT):

Per questi ed altri motivi si è cercato di offrire alla fine del progetto anche la possibilità di eseguire i nostri interpreti da shell DOS.

    Abbiamo così creato degli interpreti che per l'input e l'output utilizzano degli stream. Se vogliamo creare un interprete per DOS è sufficiente passargli gli stream System.in e System.out. Anche l'interfaccia grafica a finestre colloquia con gli interpreti tramite stream. Per ogni interprete si hanno 3 stream: uno da cui l'interprete prende l'input e due su cui scrive l'output (standard output e messaggi di errori). Per realizzare tutto questo è stata utilizzata una pipe unidirezionale per ogni stream: l'interfaccia scrive su un lato della pipe e l'interprete legge dall'altro lato e viceversa. Quando l'interfaccia grafica deve spedire messaggi ad un interprete sono direttamente i metodi dell'applet che scrivono sulla pipe. Quando l'interprete scrive su uno stream di output, all'altro capo della pipe c'è in attesa un thread che appende i messaggi ad una text area specifica. Esistono due thread per ogni interprete, ciascuno associato ad una delle due text area di output.

    In totale, quando il programma è a regime, i thread (a parte quelli del sistema java) sono 7: uno è il main e tre ciascuno per implementare ogni interprete. Di questi tre uno esegue l'interprete vero e proprio e due sono i thread che appendono i messaggi alla text area.

    All'avvio ogni thread dovrebbe avere una priorità normale (5). Quando viene resettato un interprete, poiché il metodo dell'applet è chiamato dal sistema java che ha priorità 6, verrebbero creati nuovi thread con priorità 6, cioè più alta di quella del main. Questo lascerebbe l'interfaccia bloccata mentre l'interprete è al lavoro. Per questo motivo nei costruttori degli interpreti e degli ascoltatori viene settata manualmente la priorità.

    Per evitare ogni possibile conflitto abbiamo utilizzato il costrutto Syncronized su ogni sezione critica e precisamente sull'accesso ad ogni area di output.

    L'interfaccia grafica è stata costruita utilizzando le swing che grazie al doppio buffering permettono una maggiore stabilità visiva ed evitano le imprecisioni riscontrate nell'AWT. Nonostante tutto qualche piccolo problemino è rimasto anche nelle swing: a causa del LineWrap, java a volte non si accorge che una text area deve essere ridisegnata. Si è provveduto anche a risolvere questo problema.

In generale sono stati curati anche i particolari dell'interfaccia grafica per offrire un sistema comodamente utilizzabile. Tra le vare "facilities":

    C'è da notare che i file caricati vengono trattati differentemente nei due interpreti. In prolog questi vengono immediatamente consultati, mentre in lisp vengono caricati nella Code Area. Poi è possibile compilarli. La Code Area del lisp non viene mai "sporcata". Solo se si mette un check su Add viene aggiunto in fondo alla Code Area la stringa appena valutata (se questa non produce un errore). Questa funzionalità permette di creare in lisp del codice incrementale: si testa una nuovo comando e se funziona lo si aggiunge al codice già scritto ed alla fine si può salvare il lavoro. La Code Area in fondo può essere utilizzata anche come un semplice editor di testo, dunque è possibile scrivere qui anche i programmi per prolog, poi salvarli e caricarli dopo che si è attivato l'interprete prolog. Per questo motivo abbiamo messo la possibilità del controllo delle parentesi quadre anche nella Code Area del lisp.

    L'unico inconveniente è che ancora non esista un browser che supporti java 1.2.
 

    Mostriamo di seguito il risultato ottenuto.
 

Interpreti Scheme e Prolog con interfaccia basata sulla shell di DOS:

Interprete Scheme
 

Interprete Prolog






L'interfaccia swing è invece la seguente:



    Una visione d'insieme con tutte le finestre aperte è la seguente: