Per chi si avvicina al mondo della programmazione, disegnare Interfacce utente non è proprio semplicissimo: la libreria Swing di Java serve proprio a questo. Il processo, comunque, viene reso più semplice grazie a SwiXml, API Java per creare Interfacce grafiche. SwiXml permette di creare una GUI in modo perfetto attraverso la modifica di un file XML. Vediamo come sia possibile tutto ciò.
Introduzione
Swing è un framework Java, composto da classi e componenti e appartenente alle JFC (Java Foundation Classes), che viene utilizzato per lo sviluppo di interfacce grafiche. Swing consente di creare finestre in cui vengono posti diversi componenti come caselle di testo, etichette, “combobox”, caselle di controllo di vario tipo, tabelle, pulsanti e così via. A differenza di AWT, inizialmente utilizzata come libreria Java per le GUI, Swing rende il look and feel dell’applicazione indipendente dal sistema operativo sui cui essa sta girando [1]. Per quegli sviluppatori principianti che non conoscessero tutti i componenti Swing, ricordiamo che, nella pagina ad essi dedicata [3], che invitiamo comunque a visitare, è pubblicato un riassunto visuale che riportiamo in figura 1.
Figura 1 – Un compendio dei principali componenti Swing.
I componenti di Swing consentono di creare delle finestre e dei controlli (e molto altro) per realizzare l’interfaccia grafica della nostra applicazione. Chiaramente, ad ognuno dei componenti, può essere associata opportunamente una azione (o anche più di una). Una “lista della spesa” dei componenti Swing vede la presenza di JCheckBox, JComboBox, JList, JMenu, JRadioButton, JSlider, JSpinner, JTextField, JPasswordField. Ribadiamo ai programmatori principianti di fare riferimento ai titoli indicati nella bibliografia in coda all’articolo.
SwiXml
Costruire un’interfaccia grafca utente basata su documenti XML non è un’idea completamente nuova. Progetti comeThinlet [4], XUL, XULUX, Jelly e SwingML, per citarne alcuni, hanno avuto un discreto successo.[2]
SwiXml è un motore che genera interfacce grafiche, sia per applicazioni che per applet. Il meccanismo di funzionamento è piuttosto lineare:
- l’interfaccia viene strutturata in un file XML;
- il file viene sottoposto a parsing a tempo di esecuzione;
- viene eseguito il rendering in oggetti di tipo javax.swing.
Nulla impedisce di caricare in modo dinamico un documento XML che descrive la GUI dell’applicazione.
Chiaramente, SwiXml non fa tutto da solo: lo sviluppatore deve comunque conoscere il package javax.swing, la sua strutturazione, i suoi componenti e il modo corretto di usarli nella creazione di un’interfaccia, specie in relazione alle azioni cui i componenti vengono associati. Ciò che SwiXml compie al meglio, invece, è ridurre la quantità di lavoro ripetitivo (in quanto tale soggetto a errori) per la realizzazione di interfacce grafiche complesse.
Prerariamo l’ambiente di lavoro
Per prima cosa apriamo il nostro browser e andiamo nella home page [2] del progetto SwiXML (figura 2).
Figura 2 – La home page del progetto SwiXml.
Clicchiamo sulla voce Inside e, in fondo alla pagina, dovremmo trovare la sezione download per scaricare il file che ci interessa.
Figura 3 – Ecco da dove effettuare il downolad.
Apriamo il file ZIP appena scaricato e copiamo la cartella swixml_149lib nella directory del nostro progetto Java. Inoltre all’interno della cartella dobbiamo anche copiare il file JAR swixml contenuto in swixml_149 uild. Il pathclass del nostro progetto apparirà simile a quello mostrato in figura 4.
Figura 4 – Il pathclass del nostro progetto.
Un ulteriore passo importante nella creazione del nostro ambiente di lavoro è il seguente: nella cartella src, dovremo creare anche una cartella xml, dove verrano salvati i file XML che andremo a scrivere per le nostre applicazioni.
Figura 5 – Occorre creare una cartella xml dentro src. In essa salveremo i file XML.
HelloWorld
Bene, adesso che abbiamo sistemato il nostro ambiente di lavoro, siamo pronti per scrivere la nostra prima interfaccia con SwiXml; come ogni prima prova che si rispetti, scriviamo dentro una finestra il nostro immancabile “Hello World”!
Es1.java
Secondo i principi di SwiXml, il file .java in questo caso ci serve solo da contenitore per far partire l’interfaccia grafica: in realtà il codice che definisce la GUI è descritto nell’XML.
import org.swixml.SwingEngine; import javax.swing.*; import java.awt.event.ActionEvent; public class Es1 { private Es1() throws Exception { new SwingEngine( this ).render( "xml/Es1.xml" ).setVisible( true ); } public static void main( String[] args ) throws Exception { new Es1(); } }
Es1.xml
Nel file .xml scriviamo il codice per generare la GUI. Come potete notare, abbiamo definito la grandezza della finestra, il titolo e l’operazione di chiusura. In questa Gui al centro potete trovare la scritta “Hello World! MokaByte”
defaultCloseOperation="JFrame.EXIT_ON_CLOSE"> foreground="blue" text="Hello World!"/> foreground="green" text="MokaByte">
Figura 6 – Ecco la nostra finestra JFrame, con l’immancabile “Hello World!”.
JLabel, JTextField e JButton
Dopo aver stampato una stringa a vdeo, proviamo a creare qualcosa di più complicato. In questo esempio si vuole scrivere il proprio nome in una JTextField e premendo un pulsante più in basso comparirà un saluto con la stringa “Ciao” (descritta nell’xml) accanto al nome che abbiamo inserito precedentemente.
Es2.java
import org.swixml.SwingEngine; import javax.swing.*; import java.awt.event.ActionEvent; public class Es2 { public JTextField tf; public JLabel stampa; // Definisco l'azione invia che ci consente di stampare // nella JLabel creata il saluto public Action invia= new AbstractAction() { public void actionPerformed( ActionEvent e ) { stampa.setText( tf.getText() ); } }; // Costruttore per far elaborare il file xml private Es2() throws Exception { new SwingEngine( this ).render( "xml/Es2.xml" ).setVisible( true ); } // Main public static void main( String[] args ) throws Exception { new Es2(); } }
Es2.xml
Nella parte superiore di questa GUI abbiamo inserito una etichetta, un campo di testo e un pulsante al quale è collegata l’azione invia. Nella parte inferiore invece possiamo notare due label: la prima stampa “Ciao!”, la seconda invece visualizza il contenuto del textfield.
foreground="blue" text="Come ti Chiami??"/>
Figura 7 – Ecco la visualizzazione dell’esempio appena riportato.
JComboBox
Con SwiXml è possibile creare anche delle ComboBox: vediamo insieme come farlo. Prima di tutto bisogna creare una classe ComboModel per inserire i valori nella nostra ComboBox.
// ComboModel.java import javax.swing.*; /** * Combobox Model used in the InitClass sample. */ public class ComboModel extends DefaultComboBoxModel { /** * Constructs a DefaultComboBoxModel object. */ public ComboModel() { super( new Object[]{"Item1", "Item2", "Item3", "Item4", "Item5"} ); } }
Es3.java
A questo punto possiamo passare alla creazione della classe Java.
import org.swixml.SwingEngine; import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class Es3 extends WindowAdapter implements ActionListener { private SwingEngine swix; public Action azione = new AbstractAction() { public void actionPerformed(ActionEvent e) { System.out.println( ((JComboBox) e.getSource()) .getSelectedItem().toString() ); } }; private Es3() { try { swix = new SwingEngine( this ); swix.render( "xml/Es3.xml" ); swix.getRootComponent().setVisible(true); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new Es3(); } @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub } }
Es3.xml
Foreground="blue">ComboBox PrototypeDisplayValue="1234567890|1234567890"/>
Figura 8 – Ed ecco la nostra ComboBox dell’Es3.
Alcuni Layout Manager
Di seguito mostriamo alcune implementazioni usate da SwiXml per gestire i layout delle applicazioni. Ancora una volta gli esempi saranno autoesplicativi: per questo set di esempi però useremo una sola classe Java. I diversi file XML, invece, sono sempre denominati Es4.xml, ma cambiano nella loro formulazione: accanto al nome viene riportato ciò che fanno, ossia il layout cui danno origine quando accoppiati alla classe Es4.java.
Es4.java
import org.swixml.SwingEngine; public class Es4 extends SwingEngine { private Es4() { try {
render( "xml/Es4.xml" ).setVisible( true );
} catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { new Es4(); } }
Es4.xml = FlowLayout
background="FFFFFF" layout="FlowLayout"> Layout="FlowLayout(FlowLayout.CENTER)" Visible="true" Resizable="true">
Figura 9 – L’implementazione del FlowLayout.
Es4.xml = GridLayout
layout="GridLayout"> Layout="GridLayout(2,2)" Visible="true" Resizable="true">
Figura 10 – L’implementazione del GridLayout.
Es4.xml = GridBagLayout
layout="GridBagLayout"> Layout="GridBagLayout" Visible="true" Resizable="true">
Figura 11 – L’implementazione del GridBagLayout.
Es4.xml = BorderLayout
background="FFFFFF" layout="Borderlayout"> Layout="borderlayout" Visible="true" Resizable="true">
Figura 12 – L’impementazione del BorderLayout.
Applet
SwiXml, ci permette di creare anche delle semplici applet, semplicemente aggiungendo un descrittore (descriptor) all’interno del file .java. Rispetto alle classi precedenti, non è che cambi molto.
Es8.java
public class Es8 extends JApplet { public JTextField tf; public AbstractAction azione = new AbstractAction() { public void actionPerformed( ActionEvent e ) { tf.setText( tf.getText() + '@' ); } }; public void init() { super.init(); try { String descriptorfile = this.getParameter( "xml" ); if (descriptorfile == null) { descriptorfile = "xml/Es8.xml"; } new SwingEngine( this ).insert( new URL( getCodeBase(), descriptorfile ), this ); this.setVisible( true ); } catch (Exception e) { e.printStackTrace(); } } }
Es8.xml
Figura 13 – L’applet dell’esempio Es8.
CustomTag
Grazie a questa funzionalità, contenuta in SwiXml, possiamo utilizzare degli oggetti già inclusi: ad esempio, di seguito viene mostrato il modo in cui creare un calendario.
Es9.java
import com.toedter.calendar.*; import org.swixml.SwingEngine; import org.swixml.ConverterLibrary; import org.jvnet.substance.SubstanceLookAndFeel; import org.jvnet.substance.theme.SubstanceEbonyTheme; import javax.swing.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; public class Es9 extends WindowAdapter { public Es9() throws Exception { SwingEngine swix = new SwingEngine(this); swix.getTaglib().registerTag("Calendar", JCalendar.class); swix.render("xml/Es9.xml").setVisible(true); } public void windowClosing(WindowEvent e) { super.windowClosing(e); System.exit(0); } public static void main(String[] args) throws Exception { new Es9(); } }
Es9.xml
defaultCloseOperation="JFrame.EXIT_ON_CLOSE"> background="white" constraints="BorderLayout.NORTH"> foreground="black">Calendario
Figura 14 – L’esempio Es9 con il calendario.
Conclusioni
SwiXml è indubbiamente un buono strumento per chi ha poca familiarità con le API swing di Java. Con la modifica del solo file XML si possono realizzare ottime interfacce grafiche in Java, soprattutto quando si ha poco tempo a disposizione: magari non è la soluzione per realizzare l’applicazione “definitiva” (ma per quello ci sono altri strumenti), ma di certo, per creare le nostre utility potrebbe essere proprio quello che ci serviva. Abbiamo fornito alcuni esempi proprio per mettere in luce come sia possibile creare delle semplici GUI standard da poter riutilizzare più volte per le proprie applicazioni, anche in un’ottica di uniformità dell’esperienza utente. Insomma, uno strumento semplice che fa cose semplici, ma in modo rapido e affidabile.
Riferimenti
[1] Andrea Gini, capp. 12-17 in AAVV, “Manuale pratico di Java. Dalla teoria alla programmazione”, Hops – Tecniche Nuove, 2003
[2] Il sito ufficiale di SwiXml
[3] La pagina dedicata ai componenti Swing
http://download.oracle.com/javase/tutorial/ui/features/components.html
[4] Thinlet, un analogo progetto per la realizzazione di interfacce grafiche a partire da XML
http://thinletweb.appspot.com/
Yuri Cervoni si è laureato alla facoltà di Ingegneria Informatica dell’Università “La Sapienza” di Roma nel maggio 2009 con la tesi: “Implementazione e realizzazione di un metodo per l’animazione dell’algoritmo di Dijkstra”. Dall’Aprile 2009, prima come stagista e poi come sviluppatore software, lavora nella Società degli Studi di Settore. Nel tempo libero cerca di ampliare le sue conoscenze informatiche partecipando a progetti software presenti su SourceForge.net come “FlaQuizTV” e la documentazione italiana di “Argo UML”.