________________________________________________________________________________ 0........10........20........30........40........50........60........70.......79 |_________|_________|_________|_________|_________|_________|_________|________| ________________________________________________________________________________ XML-Forms 0.0.2 [04/08/2005] [MAN ver 0.0.1] [rev 16] Giansante Gabriele (c) 2004, 2005 ________________________________________________________________________________ [EN] This document is in Italian language. Sorry, but I have no time to translate it in other languages. [IT] Questo documento e' scritto in italiano. Mi dispiace, ma non ho il tempo di tradurlo o farlo tradurre in altre lingue. ________________________________________________________________________________ -------------------------------------------------------------------------------- INDICE -------------------------------------------------------------------------------- NOMENCLATURA INTRODUZIONE STRUTTURA DEI FILE XML FILE DI CORRISPONDENZA FILE DI DEFINIZIONE DELLE FORM COSTRUZIONE DI UN COMPONENTE TIPI DI LAYOUT SUPPORTATI DA XML-FORMS TIPI DI DATO PERSONALIZZATI AGGIUNTA DI NUOVI TIPI DI ELEMENTI LOCALIZZAZIONE API XML-FORM AGGIORNARE LA PROPRIA APPLICAZIONE CON UNA NUOVA VERSIONE DI XML-FORMS ESEMPI (JAVA E XML) BUG FAQ & TIPS -------------------------------------------------------------------------------- NOMENCLATURA -------------------------------------------------------------------------------- COMPONENTE: E' un qualsiasi oggetto grafico (bottone, pannello, testo, ecc.). E' in corrispondenza con le classi Java derivanti da Component. Un componente puo' contenere al proprio interno altri componenti. Ha delle proprieta' configurabili tramite tipi di dato esistenti o tipi di dato definiti dall'utente. Puo' accettare un "layout" per il posizionamento di altri componenti al proprio interno. FORM: E' un oggetto grafico principale, adatto a contenere un insieme di altri oggetti. E' in corrispondenza con i container Java, cioe' JWindow, JFrame, ecc. Puo' essere considerato come un tipo particolare di componente. Ha delle proprieta' configurabili tramite tipi di dato esistenti o tipi di dato definiti dall'utente. Puo' accettare un "layout" per il posizionamento di altri componenti al proprio interno. LAYOUT: Posizionatore automatico di componenti all'interno di un form o di un altro componente. Ha delle proprieta' configurabili tramite tipi di dato esistenti o tipi di dato definiti dall'utente. TIPI DI DATO DEFINITI DALL'UTENTE: Tipi di dato non supportati direttamente dalla libreria, ma definibili dall'utente implementando opportune "classi manager" per tale tipo. N.B. Tali "classi manager" possono supportare anche piu' tipi di dato diversi. ENTITA': Nome "umano" assegnato ad un tipo di oggetto grafico, ad un tipo di dato, ad un tipo di layout, ecc. Deve sempre avere una corrispondenza con una classe implementante. CLASSE IMPLEMENTANTE: Classe Java che rappresenta una particolare entita' e ne implementa il comportamento. Ad esempio, l'entita' "LABEL" ha come classe implementante "javax.swing.JLabel". STANDARD ERROR: Stream di default su cui vengono indirizzati i messaggi di errore. Accessibile con "System.err". STANDARD OUTPUT: Stream di default su cui vengono indirizzati i messaggi normali. Accessibile con "System.out". -------------------------------------------------------------------------------- INTRODUZIONE -------------------------------------------------------------------------------- XML-Forms e' una libreria che consente di creare delle form Java (JFrame, Frame, JInternalFrame, ecc.) a partire da una descrizione XML. Il sistema e' studiato per supportare * internazionalizzazione * tipi di dato definiti dall'utente * tipi di componenti definiti dall'utente * al momento solo pochi tipi di layout predefiniti * inclusione di altri file XML-Forms Elaborazione XML testata (e consigliata) con "xalan" e "xerces" (www.apache.org). -------------------------------------------------------------------------------- STRUTTURA DEI FILE XML -------------------------------------------------------------------------------- Escludendo i file di internazionalizzazione (vedere la sezione "LOCALIZZAZIONE"), esistono sostanzialmente due tipi di file XML usati: a) quelli di corrispondenza fra i nomi delle entita' e le classi implementanti b) quelli di definizione delle form Appartengono alla categoria a) i file "componentTypes.xml", "formTypes.xml", "layoutTypes.xml", "dataTypes", "xustomComponentTypes.xml", "customFormTypes.xml", "customDataTypes.xml" mentre appartengono alla categoria b) tutti i file di definizione delle form, come quello di esempio "testForm.xml". Tutti i file ad eccezione dei "custom" hanno una struttura generale fissa: [definizione_file] dove [tipo_file] dipende dal file in oggetto: "form", "types". I file custom sono file che vengono inclusi in quelli di definizione dei tipi e servono a supportare tipi di elementi definiti dall'utente (propri tipi di dati, estensioni di componenti, ecc.). Il "dtd" da utilizzare dipende dal tipo di file: "form.dtd" per i file di tipo "form" e "types.dtd" per i file di corrispondenza ("types"). I file custom devono sottostare alle regole descritte in "types.dtd". -------------------------------------------------------------------------------- FILE DI CORRISPONDENZA -------------------------------------------------------------------------------- Tutti i file di corrispondenza hanno una definizione fissa, ovvero ogni corrispondenza assume la forma seguente (vedere la nomenclatura per il significato di "entita'" e di "classe implementante"): ad esempio, per le corrispondenze dei tipi di componenti: I nomi cosi' definiti sono utilizzabili per la scrittura di file della categoria b), ovvero quelli che definiscono il form da creare. Vedere "types.dtd" per la definizione esatta del file. -------------------------------------------------------------------------------- FILE DI DEFINIZIONE DELLE FORM -------------------------------------------------------------------------------- La definizione di una form segue la seguente struttura: ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... La divisione principale e' fra "form" e "componenti" da inserire nel form. In una form possono essere specificati i sottocomponenti, il layout, le proprieta', i listener (supporto limitato a listener con costruttore vuoto) e chiamate a metodi dei componenti. In un componente possono essere specificati i sottocomponenti, il layout, le proprieta', il vincolo (constraint) che lo posiziona nel padre (variabile a seconda del tipo di layout del padre), i listener (sempre con costruttore vuoto) e le chiamate a metodi. Opzionalmente i tag "xf:component-property" e "xf:call-parameter" supportano gli attributi booleani "err" ed "out" che servono rispettivamente a stampare la coppia (nome, valore) sullo "standard error" e sullo "standard output". Vedere "form.dtd" per la definizione esatta del file. -------------------------------------------------------------------------------- COSTRUZIONE DI UN COMPONENTE -------------------------------------------------------------------------------- Un componente viene introdotto tramite il tag dove il "nome_componente" rappresenta il nome dato alla particolare istanza del tipo di componente scelto. Tale nome e' utilizzabile per la ricerca del componente a runtime (viene usato il metodo "setName(String name)" per impostarlo). Il "tipo_componente" indica una corrispondenza nel file XML "componentTypes.xml". Ad esempio, -- L'aspetto del componente e' definito dalle sue proprieta' per mezzo di zero o piu' tag del tipo Il "nome_proprieta'" indica il nome di una proprieta' gia' esistente nell'implementazione del componente e impostabile tramite metodo "set[nome_proprieta'](valore)". A causa della mia pigrizia, al momento il nome della proprieta' deve rispecchiare esattamente il nome del metodo senza il prefisso "set" (quindi con la prima lettera maiuscola). Il "valore_proprieta'" e' una rappresentazione in stringa del valore della proprieta'. Tale rappresentazione viene interpretata a seconda del "tipo_proprieta'". Il parametro "tipo" non e' obbligatorio, in quanto per default la proprieta' viene considerata come una Stringa. Il tipo di proprieta' puo' essere uno di quelli supportati di default dalla libreria XML-Forms oppure un tipo definito dall'utente (vedere la sezione "TIPI DI DATO SUPPORTATI DA XML-FORMS" e "TIPI DI DATO CUSTOM"). La proprieta' di un componente puo' essere opzionalmente stampata sullo "standard output" o sullo "standard error" tramite gli attributi booleani "out" ed "err". Es. "" stampa sullo "standard error" la stringa "XML-Form debug: =". -- Oltre alle proprieta', opzionalmente puo' essere indicato un layout (se si specificano piu' layout, verra' usato solo l'ultimo). Se non viene specificato, verra' usato quello di default del componente. ... Il "tipo_layout" indica il nome del layout come imposto in "layoutTypes.xml". L'uso dei layout e' limitato a quelli supportati dalla libreria (vedere "TIPI DI LAYOUT SUPPORTATI DA XML-FORMS"). Nella indicazione del layout possono essere fornite oppure no delle proprieta'. L'utilizzo delle proprieta' del layout e' assolutamente identico a quello delle proprieta' del componente. -- Prima del layout, puo' (e a volte deve...) essere specificato il vincolo di posizionamento del componente all'interno del layout del padre (attenzione! non all'interno del layout di questo componente). Il "tipo_layout" ha lo stesso significato che assume nel tag "xf:layout", mentre per le proprieta' dipendenti dal layout e' necessario vedere la sezione "TIPI DI LAYOUT SUPPORTATI DA XML-FORMS". -- Per definire meglio il componente, viene data la possibilita' di chiamare dei metodi del componente stesso, passandogli opportuni parametri. Tali metodi possono essere chiamati sia prima della definizione dei sottocomponenti che dopo. Ad esempio, se in un JFrame si volesse chiamare il metodo "pack()" per ottenere una impostazione graficamente "compatta" del frame, si dovrebbe usare alla fine della definizione della form, in modo da inserire prima tutti i sottocomponenti. Con la chiamata ai metodi, si possono sorpassare praticamente la maggior parte delle limitazioni del sistema XML-Forms. Ad esempio, tutti i tag "xf:component-property" possono essere sostituiti da "xf:call" aggiungendo "set" al nome della proprieta'. Ad esempio, puo' essere sostituito con Lo svantaggio e' che "xf:call" e' meno leggibile, il vantaggio e' che consente di chiamare metodi con piu' di un parametro. ... Come nel caso delle proprieta' del componente, se il tipo del parametro non viene specificato, viene assunto per default il tipo "String". Il parametro di una chiamata a metodo puo' essere opzionalmente stampato sullo "standard output" o sullo "standard error" tramite gli attributi booleani "out" ed "err". Es. "" stampa sullo "standard error" la stringa "XML-Form debug: parameter=". -- Un componente puo' contenere altri componenti. La modalita' di definizione di tali sottocomponenti e' assolutamente identica a quanto descritto in questa sezione. L'ordine corretto degli elementi all'interno di un componente e': "constraint", "layout", "component-properties", "listeners", "calls", "components", "calls" (vedere "form.dtd"). Nel caso in cui esista la necessita' di aggiungere un componente realizzato in un altro file "XML-FORMS", si puo' usare dove il nome file rappresenta il path del file da includere. Attenzione, l'elaborazione del file incluso avviene in modo ricorsivo alla fine dell'elaborazione di quello che lo contiene. Possono essere inoltre specificati gli attributi "prefix", "suffix" (utili in caso di inclusione ripetuta dello stesso file) e "cached" (disabilita la cache prima dell'inclusione, comportamento ereditato delle ulteriori ed eventuali sotto-inclusioni). -------------------------------------------------------------------------------- TIPI DI LAYOUT SUPPORTATI DA XML-FORMS -------------------------------------------------------------------------------- ATTENZIONE!!! Il sistema dei layout potrebbe variare notevolmente in futuro! Al momento sono supportati solamente i layout: BORDER (BorderLayout), GRID (GridLayout), GRIDBAG (GridBagLayout), FLOW (FlowLayout). Un componente puo' assumere un BorderLayout usando il seguente tag: dal momento che tipicamente non c'e' bisogno di passare parametri a questo tipo di layout. Un componente puo' essere posizionato in un altro avente un BorderLayout con il seguente tag: dove "orientamento" puo' assumere i valori "CENTER", "EAST", "WEST", "SOUTH", "NORTH". Un componente puo' assumere un GridLayout usando il seguente tag: Non tutte le proprieta' sono obbligatorie, anzi potrebbero essere omesse anche tutte. E' anche possibile specificare ulteriori proprieta', se necessario. Non c'e' bisogno di specificare alcun vincolo nei sottocomponenti perche' il posizionamento avviene automaticamente a seconda delle proprieta' indicate nella definizione del layout. Un componente puo' assumere un FlowLayout usando il seguente tag: dal momento che tipicamente non c'e' bisogno di passare parametri a questo tipo di layout. Un componente puo' assumere un GridBagLayout usando il seguente tag: dal momento che tipicamente non c'e' bisogno di passare parametri a questo tipo di layout. TODO: aggiungere il funzionamento del GRIDBAG (vedi XML per spiegazione gia' scritta) -------------------------------------------------------------------------------- TIPI DI DATO SUPPORTATI DA XML-FORMS -------------------------------------------------------------------------------- I tipi di default direttamente supportati sono i seguenti: String, boolean, short, int, long, double, Rectangle, Dimension. Tramite la definizione di tipi di dato custom sono supportati di default anche: Color, SystemColor, Image -- - Il tipo boolean e' supportato nella forma "true" o "false". - Il tipo Dimension e' supportato solo nella forma "width,height", ad esempio ... value="300,200" type="Dimension"/> - Il tipo Rectangle e' supportato solo nella forma "x,y,width,height", ad esempio ... value="10,10,300,200" type="Rectangle"/> - Il tipo String viene usato per default, quindi, per specificare una proprieta' di tipo stringa, si puo' omettere il campo "type". Ad esempio ... value="questa e' una stringa"/> ... value="questa e' una stringa" type="String"/> - Il tipo Color e' supportato nella forma "r,g,b" oppure "r,g,b,a". I valori possono essere sia "float" (0.0-1.0) che "int" (0-255). Nel caso di valori float, il primo valore deve essere preceduto dalla chiave "float:" (vedere gli esempi). "r" rappresenta il canale rosso, "g" rappresenta il canale verde, "b" rappresenta il canale blu, "a" rappresenta il canale alpha (trasparenza). Ad esempio: ... value="200,200,245" type="Color"/> ... value="float:1.0,0.5,0.1" type="Color"/> ... value="200,200,245,100" type="Color"/> ... value="float:1.0,0.5,0.1,0.9" type="Color"/> Sono anche supportate le costanti di tipo Color, ad esempio ... value="RED" type="Color"/> ... value="red" type="Color"/> ... value="DARK_GRAY" type="Color"/> ... value="darkGray" type="Color"/> - Il tipo SystemColor e' supportato come nome di una qualsiasi costante della classe java.awt.SystemColor che sia di tipo SystemColor, ad esempio ... value="activeCaption" type="SystemColor"/> ... value="window" type="SystemColor"/> ... value="control" type="SystemColor"/> ... value="menuText" type="SystemColor"/> Non possono essere specificate le costanti proprie di java.awt.Color (usare il tipo "Color"). - Il tipo Image e' supportato nelle seguenti forme: [cache,][(file|jar),] "cache" e' opzionale ed indica che l'immagine viene prima cercata nella cache interna (Hashtable statica) e, se non presente, caricata nel metodo opportuno. Una volta caricata, l'immagine, viene messa nella cache. Se "cache" non viene indicato, allora l'immagine viene caricata sempre senza passare dalla cache. "file" indica che l'immagine verra' caricata come se il path indicasse un file. "jar" indica che l'immagine deve essere caricata come risorsa (utilizzo di URL). Se non viene specificato "file" oppure "jar", l'effetto e' lo stesso del caso in cui si usi "jar". -- Vista l'implementazione attuale della libreria, il supporto ad altri tipi di dati puo' essere aggiunto esclusivamente attraverso i tipi di dati custom. -------------------------------------------------------------------------------- AGGIUNTA DI NUOVI TIPI DI ELEMENTI -------------------------------------------------------------------------------- La libreria XML-Forms viene fornita con alcuni tipi di elementi predefiniti (form, componenti, layout e tipi di dato). A tutti questi tipi di elementi, con l'eccezione dei layout) possono esserne aggiunti altri a seconda delle proprie esigenze tramite i file "custom". Accanto a "formTypes.xml", "componentTypes.xml" e "dataTypes.xml" ci sono i corrispondenti "customFormTypes.xml", "customComponentTypes.xml", "customDataTypes" che servono ad aggiungere elementi alla libreria. Se non e' presente un tipo di elemento necessario ai propri scopi, lo si puo' aggiungere nei file custom, che verranno inclusi all'interno di quelli principali. La sintassi degli elementi di ognuno di questi file e' la seguente: Se per i componenti e le form basta aggiungere righe di questo tipo, il discorso e' leggermente piu' complicato per i tipi di dati, come spiegato nella sezione "TIPI DI DATO CUSTOM". I file custom dovrebbero essere sempre posizionati nello stesso percorso dei file principali. -------------------------------------------------------------------------------- TIPI DI DATO CUSTOM -------------------------------------------------------------------------------- I tipi di dato custom sono tipi di dato non direttamente supportati da questa libreria. Possono essere tipi standard di Java, possono essere classi standard di Java o possono essere classi definite dall'utente. Personalmente non ho perso troppo tempo ad inserire il supporto a tutti i tipi possibili, lasciando pero' aperte le porte all'utente per aggiungerne di nuovi. L'aggiunta di un tipo custom avviene in due passi: 1) la scrittura di un manager per tale tipo (e probabilmente anche per altri) 2) l'inserimento della corrispondenza fra tipo custom e classe implementante Il manager del tipo custom, per poter essere accettato dalla libreria XML-Forms, deve implementare la classe com.feelinglinux.xmlform.types.CustomTypeManagerIF In particolare deve essere implementato il metodo Object parseCustomObject(Object value) Il valore in ingresso non e' altro che il valore di una proprieta' all'interno del file XML di definizione della form. L'oggetto da restituire dovra' essere del tipo opportuno e adatto ad essere usato nel metodo "set" relativo alla proprieta' da impostare. La corrispondenza fra tipo di dato custom e manager che lo gestisce viene specificata nel file XML "customDataTypes.xml". Ad esempio, nella riga il nome della proprieta' e' "Text", il valore in pasto a "parseCustomObect" e' "prova!", il nome del tipo custom e' "ExtendedString". -------------------------------------------------------------------------------- LOCALIZZAZIONE -------------------------------------------------------------------------------- Esistono sostanzialmente tre modi per internazionalizzare le form. 1) Una volta che il form e' stato creato, scorrere tutti i componenti per individuare quelli in cui cambiare il testo. 2) Usare il metodo "parseForm()" passando un sorgente XML gia' internazionalizzato (internazionalizzazione esterna). 3) Usare il meccanismo presente in XML-Forms (internazionalizzazione interna). Il terzo metodo e' quello che verra' descritto. Dalla versione 0.0.2, e' stato introdotto il foglio di stile "style.xsl" contenente regole di trasformazione per la sostituzione di codici particolari all'interno di un file XML. L'output e' rappresentato dallo stesso XML di partenza con i codici sostituiti dai testi associati. Il processo di internazionalizzazione si basa sull'utilizzo di codici (nomi dei messaggi) al posto dei testi (messaggi). Tali messaggi vengono inseriti in un file xml chiamato "localizedMessages-.xml" dove "" e' una stringa del tipo "it_IT", "en_US", "de_DE", ecc., ovvero "_". Nel form, invece, vengono inseriti i nomi dei messaggi nella forma "##" (es. "##appliction.name"). __________________________________________________ | ___________ ____________________________ | __________ | | | | | | | | | | style.xsl | << | localizedMessages-... .xml | | | form XML | | |___________| |____________________________| | |__________| |__________________________________________________| \ / \________ _________/ \/ ______________________ | | | form XML localizzata | |______________________| Il meccanismo di supporto e' semplice. Supponiamo di avere nel form XML la seguenre riga e di volerla internazionalizzare: 1) Scegliere la lingua ed il paese. Es. "it", "IT". 2) Non modificare "style.xsl"!!! 3) Sostituire nel form XML il testo con un codice. Es. Scegliendo "##appName" si avra' 3) Creare "localizedMessages-it_IT.xml" se non lo si e' gia' creato ed aggiungere la corrispondenza nome-messaggio come segue: ...> ... Nome applicazione ... 4) All'interno del codice Java, indicare il "locale" da usare (ricavabile in mille modi diversi...) usando: com.feelinglinux.xmlforms.locale. LocaleSelection.setLocale(...) Es. Volendo ricavare il locale con "new Locale(lingua, paese)", LocaleSelection.setLocale(new Locale("it", "IT"); Se non viene impostato il "locale", il file utilizzato per la traduzione e' quello di default, ovvero "localizedMessages-.xml", gia' presente in XML-Forms. 5) All'interno del codice Java, usare: XmlFormParser.getLocalizedForm(...) per creare la form internazionalizzata (swing JFrame, awt Frame, ...) 6) Si puo' cambiare lingua e paese al limite anche per ogni form! Il file "style.xls" ed il file dei messaggi dovrebbero essere messi nella stessa directory contenente "form.dtd". Nel foglio di stile vengono usate delle estensioni di "xalan" (web: apache.org) che quindi dovrebbe essere usato per la trasformazione. -------------------------------------------------------------------------------- API XML-FORM -------------------------------------------------------------------------------- Il punto di accesso al sistema e' costituito dalla classe com.feelinglinux.xmlform.XmlFormParser Per inizializzare la libreria e creare le form, procedere come segue: //Impostare il parser SAX preferito (se la proprieta' e' gia' impostata //non e' necessario). System.setProperty( "org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser"); XmlFormParser parser = new XmlFormParser(); JFrame mioFrame1 = (JFrame)parser.getForm("mioJFrame1.xml"); JFrame mioFrame2 = (JFrame)parser.getForm("mioJFrame2.xml"); JDialog miaDialog1= (JDialog)parser.getForm("miaJDialog1.xml"); ... E' abbastanza semplice. Con il costruttore e' stato inizializzato il motore, caricando tutti i file di descrizione delle entita', mentre con il metodo getForm e' stata realizzato il form. Se per motivi di sicurezza non e' possibile impostare e/o leggere le proprieta' di sistema, allora e' necessario usare la riga seguente prima di creare l'istanza di XmlFormParser: XmlFormParser.setSaxDriver("org.apache.xerces.parsers.SAXParser"); al posto di "System.setProperty...". Attenzione! La directory con i file XML della libreria deve essere nel classpath dell'applicazione (filesystem o jar). Nel caso si utilizzino dei file jar per contenere anche i dati di XML-Forms, il costruttore dovrebbe essere chiamato in una delle forme public XmlFormParser(boolean fromResources) throws SAXException public XmlFormParser(boolean fromResources, String prefix) throws SAXException con il parametro "fromResources" impostato a "true" (succesivamente le form possono comunque essere caricate a scelta da file di risorse o normalmente). Altre funzioni utili sono "getComponentTypes", "getCustomDataTypes", "getFormTypes" e "getLayoutTypes" che restituiscono le corrispondenze fra entita' e classi implementanti. Volendo, la mappe restituite possono essere usate per aggiungere/rimuovere a runtime le corrispondenze. com.feelinglinux.xmlform.XmlFormParser -------------------------------------- public XmlFormParser() throws SAXException public XmlFormParser(String prefix) throws SAXException public XmlFormParser(boolean fromResources) throws SAXException public XmlFormParser(boolean fromResources, String prefix) throws SAXException ----- public static void setSaxDriver(String saxDriverClass) public String getPrefix() public void setUseResources(boolean fromResources) public boolean getUseResources() public XMLReader getReader(); ----- public HashMap getCustomDataTypes() public HashMap getFormTypes() public HashMap getLayoutTypes() public HashMap getComponentTypes() ----- public Object getForm(InputStream formDescriptionInputStream) throws SAXException public Object getForm(String formDescriptionFileName) throws SAXException public Object getForm(boolean fromResources, String formDescriptionFileName) throws SAXException public Object parseForm(String formDescription) throws SAXException public Object getLocalizedForm(String formDescriptionFileName) throws Exception public Object getLocalizedForm(boolean fromResources, String formDescriptionFileName) throws Exception ----- public void setCached(boolean cached) public boolean isCached() ----- public void addComponentListener(ComponentListener listener) public void removeComponentListener(ComponentListener listener) public void removeAllComponentListeners() ----- public void close() -------------------------------------------------------------------------------- AGGIORNARE LA PROPRIA APPLICAZIONE CON UNA NUOVA VERSIONE DI XML-FORMS -------------------------------------------------------------------------------- L'aggiornamento della libreria XML-Forms in una applicazione che la usa prevede due passi principali: sostituzione del jar e sostituzione della configurazione base. 1) Sostituzione jar. Individuare il path ove e' posizionato il jar di XML-Forms e sostituire il jar stesso con la nuova versione. 2) Sostituzione configurazione base. Individuare il path ove e' posizionata la configurazione di XML-Forms (file di base + file utente). Andranno sostituiti solamente i file di base, non quelli con le definizioni custom: - .../XML-Forms-Data/forms/form.dtd - .../XML-Forms-Data/forms/style.xsl - .../XML-Forms-Data/types/componentTypes.xml - .../XML-Forms-Data/types/dataTypes.xml - .../XML-Forms-Data/types/formTypes.xml - .../XML-Forms-Data/types/layoutTypes.xml - .../XML-Forms-Data/types/types.dtd Questi file non dovrebbero essere mai modificati dall'utente. -------------------------------------------------------------------------------- ESEMPI -------------------------------------------------------------------------------- Esempio 1: a) La directory "XML-Forms-Data" viene messa nel path relativo "data/". b) I file dati, ad esclusione delle form risiedono in uno o piu' jar c) Le form sono messe nel path relativo "data/XML/forms //Impostare il parser SAX preferito (se la proprieta' e' gia' impostata //non e' necessario). System.setProperty( "org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser"); XmlFormParser parser = new XmlFormParser(true, "data/"); JFrame mioFrame1 = (JFrame)parser.getForm(false, "data/XML/forms/mioJFrame1.xml"); JFrame mioFrame2 = (JFrame)parser.getForm(false, "data/XML/forms/mioJFrame2.xml"); JDialog miaDialog1= (JDialog)parser.getForm(false, "data/XML/forms/miaJDialog1.xml"); ... ------------------ Esempio 2: a) La directory "XML-Forms-Data" viene messa nel path relativo "data/". b) I file dati e le form risiedono in uno o piu' jar c) Le form sono messe nel path relativo "data/XML/forms //Impostare il parser SAX preferito (se la proprieta' e' gia' impostata //non e' necessario). System.setProperty( "org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser"); XmlFormParser parser = new XmlFormParser(true, "data/"); JFrame mioFrame1 = (JFrame)parser.getForm("data/XML/forms/mioJFrame1.xml"); JFrame mioFrame2 = (JFrame)parser.getForm("data/XML/forms/mioJFrame2.xml"); JDialog miaDialog1= (JDialog)parser.getForm("data/XML/forms/miaJDialog1.xml"); ... ------------------ Esempio 3: a) La directory "XML-Forms-Data" viene messa nel path relativo "data/". b) I file dati risiedono fuori dai jar dell'applicazione c) Le form sono messe nel path relativo "data/XML/forms. Le prime due all'interno di opportuni jar, l'ultima, invece, fuori. //Impostare il parser SAX preferito (se la proprieta' e' gia' impostata //non e' necessario). System.setProperty( "org.xml.sax.driver", "org.apache.xerces.parsers.SAXParser"); XmlFormParser parser = new XmlFormParser(false, "data/"); JFrame mioFrame1 = (true, (JFrame)parser.getForm("data/XML/forms/mioJFrame1.xml"); JFrame mioFrame2 = (true, (JFrame)parser.getForm("data/XML/forms/mioJFrame2.xml"); JDialog miaDialog1= (false, (JDialog)parser.getForm("data/XML/forms/miaJDialog1.xml"); ... ------------------ Esempio 4: a) Si vuole aggiungere un nuovo tipo di componente chiamato "MyChart" b) Si vuole aggiungere un proprio tipo di form chiamato "ChartFrame" Premesso che un form dovrebbe essere un discendente della classe "java.awt.Container" e che dovrebbe supportare il costruttore senza parametri, i file da toccare sono 2: 1) "XML-Forms-Data/types/customComponentTypes.xml" (per i componenti) 2) "XML-Forms-Data/types/customFormTypes.xml" (per le form) In 1) inserire la riga In 2) inserire la riga I nomi possono essere qualsiasi, con il vincolo che siano univoci per elementi simili (ad esempio, un nome di form deve essere unico fra tutti i nomi di form ma non interessa che sia uguale al nome di un componente o altro tipo di elemento). ------------------ Esempio 5: a) Si vuole aggiungere un nuovo tipo di dato chiamato "Rgb" b) Il tipo "Rgb" dovra' supportare valori del tipo "r,g,b". Come primo passo va implementato il manager del tipo, quindi il manager va associato al tipo nel file "customDataTypes.xml". package com.feelinglinux.xmlform.types.custom; import com.feelinglinux.xmlform.types.CustomTypeManagerIF; public class RgbManager implements CustomTypeManagerIF{ public RgbManager() { } public Object parseCustomObject(Object value) { String[] rgb = ((String)value).split(",", 3); System.out.println("R="+rgb[1]+" G="+rgb[2]+" B="+rgb[3]); ... //Ad esempio potrebbe restituire un "Color" o qualsiasi altra //cosa... return ...; } } La riga di corrispondenza in "customDataTypes.xml" potrebbe essere la seguente: Se il manager di esempio restituisse un oggetto di tipo Color, per un componente che supporta la proprieta' "Color" ("setColor"), si potrebbe scrivere -------------------------------------------------------------------------------- BUG -------------------------------------------------------------------------------- Non ce ne sono di particolari. Il sistema e' ancora in fase embrionale, sebbene sia gia' utilizzabile in modo efficace. Per ulteriori note vedere il file README.txt - La codifica per il momento e' solamente UTF-8. Mettere una funzione sul foglio di stile per leggere l'encoding da usare... dovrebbe essere lo stesso del file dei messaggi localizzati. -------------------------------------------------------------------------------- FAQ & TIPS -------------------------------------------------------------------------------- *"XML-Forms" puo' essere usato per creare solo "frame" e simili? No. Sebbene lo scopo iniziale fosse la sola creazione di "frame" e simili, possono essere creati componenti di qualsiasi tipo, sempre che estendano la classe Container. Quindi possono essere creati pannelli (JPanel), pannelli con scrollbar (JScrollPane), ecc. Quindi il nodo "" puo' rappresentare qualsiasi componente Java o scritto dall'utente che estenda "java.awt.container". Ovviamente i componenti non previsti vanno mappati nel file "customFormTypes.xml". *Usare il JTabbedPane Il JTabbedPane e' supportato in modo particolare. Un modo di creare le pagine e' usare il metodo "add(Component)". Il titolo della pagina (testo nella linguetta del JTabbedPane) risulta essere uguale al nome del componente. Quindi si puo' decidere di inserire tutti i componenti di una pagina all'interno di un pannello con nome uguale al titolo della pagina stessa. *Internazionalizzazione form Tramite la trasformazione XSLT e' possibile anche convertire un file XML in un altro. E' quindi possibile trasformare all'esterno della libreria il file XML che descrive il form per poi darlo in pasto al metodo "parseForm", in tutto e per tutto analogo ai "getForm". Oppure e' sempre possibile usare il metodo integrato. descritto nella sezione sulla localizzazione. *java.lang.RuntimeException: java.lang.NullPointerException Se si riscontra un errore del seguente tipo: java.lang.RuntimeException: java.lang.NullPointerException at org.apache.xalan.transformer.TransformerImpl.run(TransformerImpl. java:3407) at org.apache.xalan.transformer.TransformerHandlerImpl.endDocument (TransformerHandlerImpl.java:433) at org.apache.xerces.parsers.AbstractSAXParser.endDocument (Unknown Source) at org.apache.xerces.impl.dtd.XMLDTDValidator.endDocument (Unknown Source) at org.apache.xerces.impl.XMLDocumentScannerImpl.endEntity (Unknown Source) at org.apache.xerces.impl.XMLEntityManager.endEntity(Unknown Source) at org.apache.xerces.impl.XMLEntityScanner.load(Unknown Source) at org.apache.xerces.impl.XMLEntityScanner.skipSpaces(Unknown Source) at org.apache.xerces.impl.XMLDocumentScannerImpl$TrailingMiscDispatcher. dispatch(Unknown Source) at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument (Unknown Source) at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source) at org.apache.xerces.parsers.DTDConfiguration.parse(Unknown Source) at org.apache.xerces.parsers.XMLParser.parse(Unknown Source) at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source) at org.apache.xalan.transformer.TrAXFilter.parse(TrAXFilter.java:134) at org.apache.xalan.transformer.TrAXFilter.parse(TrAXFilter.java:159) at com.feelinglinux.xmlform.XmlFormParser.getLocalizedForm(XmlFormParser .java:392) at com.feelinglinux.xmlform.XmlFormParser.getLocalizedForm(XmlFormParser .java:334) ... verificare che tutti i componenti siano di tipo conosciuto (predefiniti o custom), ovvero che siano state create le relazioni "nome->oggetto". Nel caso in cui si utilizzino anche tipi di dato custom, verificare che i relativi manager gestiscano i valori "null": tale errore si puo' verificare quando un manager restituisce un oggetto nullo sul parsing del valore passato.