<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE Book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
 "http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
<book id="DocumentoProyectoDirigido" lang="es">
	<bookinfo id="informaciondocumento">
		<title>Tutorial para escribir un pequeño plugin para
     <application> jEdit</application>
		</title>
		<author>
			<firstname>Jairo</firstname>
			<surname>Martínez</surname>
		</author>
		<legalnotice id="noticiaLegal">
			<para>Este documento se cede al dominio público.</para>
		</legalnotice>
		<revhistory>
			<revision>
				<revnumber>1.0</revnumber>
				<date>1 Junio 2002</date>
				<authorinitials>jm</authorinitials>
				<revdescription>
					<para>Documento inicial</para>
				</revdescription>
			</revision>
			<revision>
				<revnumber>1.1</revnumber>
				<date>10 de Junio</date>
				<authorinitials>jid</authorinitials>
				<revdescription>
					<para>Correcciones menores de ortografía y marcado</para>
				</revdescription>
			</revision>
			<revision>
				<revnumber>1.2</revnumber>
				<date>12 de Junio</date>
				<authorinitials>jm</authorinitials>
				<revdescription>
					<para>Correcciones y cambios en el apéndice</para>
				</revdescription>
			</revision>
		</revhistory>
	</bookinfo>
	<chapter>
		<title>Aspectos básicos de <application>Jedit</application>
		</title>
		<sect1>
			<title>¿Qué es <application>Jedit</application>?</title>
			<para>
				<application> jEdit</application> es un editor de texto
	orientado hacia programadores y escrito en Java.  Fue
	desarrollado por Slava Pestov y otros.
      </para>
			<itemizedlist>
				<title>Sus características principales son :</title>
				<listitem>
					<para>Fácil de usar, extremadamente configurable y posee un
	  amplio conjunto de opciones, dentro de las que se encuentra
	  el coloreado de sintaxis para 70 lenguajes, tabulación 
	  automática, ilimitado deshacer/rehacer, entre muchas otras.</para>
				</listitem>
				<listitem>
					<para>Utiliza BeanShell, como lenguaje de
	      <foreignphrase>scripting</foreignphrase> que permite el
	      desarrollo de macros para
	     <application> jEdit</application>.  Pocos macros son
	      incluidos con <application>jEdit</application>; sin
	      embargo se pueden encontrar muchos más en la dirección
	      de Internet <ulink url="http://community.jedit.org">
							<citetitle>http://community.jedit.org</citetitle>
						</ulink>
					</para>
				</listitem>
				<listitem>
					<para>Soporta plugins. Mas de 50 plugins estan actualmente
	      disponibles para automatizar un amplio rango de
	      tareas. Los plugins pueden ser descargados de Internet y
	      instalados mediante el <foreignphrase> "plugin
	      manager"</foreignphrase>, el cual viene
	      incluido con <application>jEdit</application>. Para
	      encontrar más información sobre los
	      <foreignphrase>plugins</foreignphrase> de
	      <application>jEdit</application> puede consultar en esta
	      dirección de internet <ulink url="http://plugins.jedit.org">
							<citetitle>http://plugins.jedit.org</citetitle>
						</ulink>
					</para>
				</listitem>
			</itemizedlist>
			<para>Las siguientes son algunas vistas de pantalla de
      <application>jEdit</application> corriendo sobre diferentes
      plataformas: </para>
			<informalfigure>
				<screenshot>
					<mediaobject>
						<imageobject>
							<imagedata fileref="images/jedit-snap-1.gif" format="GIF"/>
						</imageobject>
						<textobject>
							<phrase>Windows</phrase>
						</textobject>
						<caption>
							<para>
								<application>jEdit</application> corriendo sobre Windows</para>
						</caption>
					</mediaobject>
				</screenshot>
				<screenshot>
					<mediaobject>
						<imageobject>
							<imagedata fileref="images/jedit-snap-2.gif" format="GIF"/>
						</imageobject>
						<textobject>
							<phrase>Linux</phrase>
						</textobject>
						<caption>
							<para>
								<application> jEdit</application> corriendo sobre Linux</para>
						</caption>
					</mediaobject>
				</screenshot>
			</informalfigure>
		</sect1>
		<sect1>
			<title>Requisitos mínimos</title>
			<para>
				<application>jEdit</application> requiere Java 2 (o Java 1.1
	con Swing 1.1).  La versión de Java recomendada para utilizar
	<application> jEdit</application> es Java 2 versión 1.3.
      </para>
		</sect1>
		<sect1>
			<title>Licencia</title>
			<para>
				<application> jEdit</application> es software libre, por lo
	que se da la libertad de distribuirlo bajo los términos de la
	Licencia Publica General <acronym>GNU</acronym> (la versión 2
	o superiores).</para>
			<para>Con respecto a los plugins disponibles para <application>
	jEdit</application>, a menos que esté especificado de manera
	diferente en la documentación, estos se encuentran licenciados
	para uso y distribución bajo los términos de la Licencia
	Publica General <acronym>GNU</acronym> (versión 2 o superiores).</para>
		</sect1>
		<sect1>
			<title>Descargar el programa desde Internet y obtener
      información adicional</title>
			<para>Para descargar el programa desde internet y encontrar
	  información detallada sobre los diferentes aspectos del
	  programa (incluyendo su código fuente) puede dirigirse a la
	  siguiente dirección de internet: <ulink url="http://www.jedit.org">
					<citetitle>http://www.jedit.org</citetitle>
				</ulink>.
      </para>
		</sect1>
		<sect1>
			<title>Explicación de la arquitectura de
      <application>jEdit</application>
			</title>
			<para>
				<application>jEdit</application> es una aplicación monousuario
	que trabaja de manera local.  Sin embargo, cuenta con algunos
	servicios para ser utilizados sobre una conexión de red como
	 lo son el descargar
	<foreignphrase>plugins</foreignphrase> y realizar
	transferencias de archivos mediante un
	<foreignphrase>plugin</foreignphrase> para manejar
	<acronym>FTP</acronym>.
      </para>
			<para>Para desarrollar macros o plugins para <application>
	  jEdit</application> es necesario conocer al
	  <acronym>API</acronym> (<foreignphrase>aplication programmer
	  interface</foreignphrase>) que se incluye con la aplicación.
	  Esta está conformada por:</para>
			<itemizedlist>
				<listitem>
					<para>Comandos de <application>BeanShell</application>
					</para>
				</listitem>
				<listitem>
					<para>Clases generales de <application>jEdit</application>
					</para>
				</listitem>
				<listitem>
					<para>Clases de <application>EditBus</application>
					</para>
				</listitem>
			</itemizedlist>
			<para>Los comandos de <application>BeanShell</application> sólo
	pueden ser usados por las macros.  Las clases generales de
	<application>jEdit</application> son usadas tanto para el
	desarrollo de macros como para el de <foreignphrase>plugins</foreignphrase>.  Las clases de
	<application>EditBus</application> cubren el manejo del
	sistema de mensajes <application>EditBus</application>, el
	cual es utilizado principalmente por los
	<foreignphrase>plugins</foreignphrase>.
      </para>
			<para>Para consultar información detallada sobre el
	<acronym>API</acronym> de <application>jEdit</application>
	puede consultar los documentos de ayuda de
	<application>jEdit</application>, a los cuales puede acceder
	mediante el menú de ayuda de <application>jEdit</application>
			</para>
		</sect1>
	</chapter>
	<chapter>
		<title>Creación de un <foreignphrase>plugin</foreignphrase> básico</title>
		<sect1 id="whatis">
			<title>¿Qué es un <foreignphrase>plugin</foreignphrase>?</title>
			<para>Un <foreignphrase>plugin</foreignphrase> es un programa
	adicional que puede ser añadido a una aplicación para
	aumentar la funcionalidad de esta.  Este programa
	adicional es cargado y corrido por la aplicación
	principal.</para>
			<para>Al igual que jEdit, sus
	<foreignphrase>plugin</foreignphrase> son escritos
	primordialmente en <application>Java</application>. Para escribir en
	<foreignphrase>plugin</foreignphrase> aunque se requiere
	cierto conocimiento del lenguaje, no se necesita ser un
	experto en <application>Java</application>.  Si usted puede escribir una aplicación útil
	en Java, usted puede escribir un
	<foreignphrase>plugin</foreignphrase>.  </para>
			<para>A continuación, desarrollaremos un pequeño
	<foreignphrase>plugin</foreignphrase> con el objetivo de
	ilustrar las aspectos básicos que debe tener un
	<foreignphrase>plugin</foreignphrase> desarrollado para
	jEdit.</para>
			<itemizedlist>
				<title>Para escribir su primer <foreignphrase>plugin</foreignphrase>, usted necesitará:</title>
				<listitem>
					<para>Java 2, Standard Edition. (se recomienda la versión 1.3)</para>
				</listitem>
				<listitem>
					<para>
						<application>jEdit</application> (ultima versión
	      estable en la fecha de escritura de este documento
	      : 4.0).  Se puede descargar del sitio: <ulink url="http://www.jedit.org">
							<citetitle>http://www..jedit.org</citetitle>
						</ulink>
					</para>
				</listitem>
			</itemizedlist>
			<para>Tambien es recomendable utilizar alguna herramienta que
	permita desarrollar aplicaciones para <application>Java</application> de manera rápida y
	eficiente, como por ejemplo <application>JBuilder</application>.  Sin embargo, esto no es
	un requisito. Se pueden desarrollar los diferentes archivos
	mediante el uso de un editor de texto como <application>emacs</application>, <application>notepad</application>,
	<application>editplus</application> o el mismo <application>jEdit</application>.</para>
		</sect1>
		<sect1 id="plugin-helloworld">
			<title>
				<foreignphrase>Plugin</foreignphrase> Hello World!</title>
			<para>Desarrollaremos un <foreignphrase>plugin</foreignphrase>
	bastante sencillo, en donde se muestran las características
	mínimas que debe tener un
	<foreignphrase>plugin</foreignphrase> para jEdit.  Este
	<foreignphrase>plugin</foreignphrase> tendrá como única
	función mostrar en un cuadro de dialogo la frase
	<wordasword>"Hello World !"</wordasword>
			</para>
			<para>Los pasos que se seguiran para desarrollar el
	<foreignphrase>plugin</foreignphrase> son los
	siguientes:</para>
			<procedure>
				<step>
					<para>Escribir la clase principal del
	  <foreignphrase>plugin</foreignphrase>, la cual llevará el
	  nombre de <classname>HelloWorldPlugin</classname>
					</para>
				</step>
				<step>
					<para>Escribir la clase encargada de la visualización del
	  <foreignphrase>plugin</foreignphrase>, a la que llamaremos
	  <classname>HelloWorld</classname>
					</para>
				</step>
				<step>
					<para>Desarrollar los archivos donde se encuentran los
	  recursos a utilizar por el
	  <foreignphrase>plugin</foreignphrase>
					</para>
				</step>
				<step>
					<para>Compilar los archivos que contienen el código fuente
	  de las clases que se han desarrollado.</para>
				</step>
				<step>
					<para>Empaquetar el <foreignphrase>plugin</foreignphrase> en
	    un archivo <acronym>JAR</acronym>
					</para>
				</step>
				<step>
					<para>Ubicar el archivo <acronym>JAR</acronym> en el
	    directorio donde <application>jEdit</application> busca
	    sus <foreignphrase>plugins</foreignphrase>
					</para>
				</step>
			</procedure>
			<sect2 id="core-class">
				<title>Escribiendo la clase principal del
	<foreignphrase>plugin</foreignphrase>
				</title>
				<para>
	  Empezaremos a desarrollar el
	  <foreignphrase>plugin</foreignphrase>, escribiendo su clase
	  principal.  Esta clase la desarrollaremos en un archivo con  el siguiente nombre: , escribiendo su clase
	  principal.  El código fuente de esta clase puede encontrarlo en: <xref linkend="HelloWorldPlugin.java"/>
				</para>
				<para>En caso de que el <foreignphrase>plugin</foreignphrase>
	  deba responder a cambios de estado de la aplicación
	  principal, la clase principal del
	  <foreignphrase>plugin</foreignphrase> debe heredar de la
	  clase <classname>EBPlugin</classname>.  Sin embargo, dado
	  que en nuestro caso el <foreignphrase>plugin</foreignphrase>
	  no necesita tanta complejidad, heredaremos de la clase
	  <classname>EditPlugin</classname>.
	</para>
				<para>
	  Para poder heredar de esta clase hay que incluir las
	  librerías de <application>jEdit</application>, por lo que
	  nuestra primera línea de código será:
	</para>
				<informalexample>
					<programlisting>import org.gjt.sp.jedit.*;</programlisting>
				</informalexample>
				<para>
	  Luego, escribiremos la siguiente parte del código en donde
	  especificaremos que la clase
	  <classname>HelloWorldPlugin</classname> hereda de la clase
	  <classname>EditPlugin</classname> y que posee una única
	  función encargada de agregar el item de menú de nuestro
	  <foreignphrase>plugin</foreignphrase> al menú de plugins de
	  jEdit.  El resultado final del código escrito para la clase
	  <classname>HelloWorldPlugin</classname> es el siguiente:
	</para>
				<informalexample>
					<programlisting>
	    import org.gjt.sp.jedit.*;
	    
	    import java.util.Vector;
	    
	    public class HelloWorldPlugin extends EditPlugin
	    {
	        public void createMenuItems(Vector menuItems)
	        {
  	            menuItems.addElement(GUIUtilities.loadMenuItem("HelloWorld"));
	         }
	    }
</programlisting>
				</informalexample>
			</sect2>
			<sect2 id="show-class">
				<title>Escribiendo la clase <classname>HelloWorld</classname>
				</title>
				<para>
	  A continuación, desarrollaremos la clase que está encargada
	  de la visualización del
	  <foreignphrase>plugin</foreignphrase>.  A esta clase le
	  daremos por nombre <classname>HelloWorld</classname>. El código fuente de esta clase puede encontrarlo en: <xref linkend="HelloWorld.java"/>
				</para>
				<para>
	  Para implementar la visualización, esta clase heredará de la
	  clase <classname>JDialog</classname> de <application>Java</application>.  Además
	  implementará dos métodos encargados de desplegar y cerrar el
	  cuadro de diálogo.
	</para>
				<para>
	  Esta clase tendrá como atributo privado un objeto de la
	  clase <classname>View</classname>, que proviene de la
	  aplicación principal y es enviado hacia el
	  <foreignphrase>plugin</foreignphrase> cuando se realiza el
	  llamado de éste.  Esto le da la posibilidad al
	  <foreignphrase>plugin</foreignphrase> de interactuar con
	  este objeto, el cual está encargado de contener la mayoría
	  de componentes visibles del programa.
	</para>
				<para>
	  El siguiente es el código para esta clase:
	</para>
				<informalexample>
					<programlisting>
	    import javax.swing.*;
	    import org.gjt.sp.jedit.*;
	    
	    public class HelloWorld extends JDialog
	    {
	    // private members
	    private View view;
	    
 	        public HelloWorld(View view)
	        {
	           super(view,jEdit.getProperty("HelloWorld.title"),false);

                   this.view = view;
	    
	           JPanel content = new JPanel();
	           setContentPane(content);
	    
	           JLabel caption = new JLabel(jEdit.getProperty("HelloWorld.caption"));
	           content.add(caption);
	    
	           pack();
	           GUIUtilities.loadGeometry(this, "HelloWorld");
	           setDefaultCloseOperation(DISPOSE_ON_CLOSE);
	           show();
	        }
	    
	    
	        public void dispose()
	        {
	           view = null;
	           GUIUtilities.saveGeometry(this, "HelloWorld");
	           super.dispose();
	        }
	    }
	  </programlisting>
				</informalexample>
			</sect2>
			<sect2 id="resources">
				<title>Recursos requeridos por el
	<foreignphrase>plugin</foreignphrase>
				</title>
				<sect3 id="acciones">
					<title>Acciones</title>
					<para>
	    El catálogo de acciones de usuario del
	    <foreignphrase>plugin</foreignphrase> es el recurso usado
	    por el <acronym>API</acronym> de
	    <foreignphrase>plugins</foreignphrase> para obtener los
	    nombres y las definiciones de las acciones del usuario. A
	    continuación, desarollaremos el archivo que contendrá las
	    acciones del <foreignphrase>plugin</foreignphrase>
	    HelloWorld. El contenido de este archivo puede encontrarlo en: <xref linkend="actions.xml"/>
					</para>
					<informalexample>
						<programlisting>
	      &lt;?xml version="1.0"?&gt;
	      
	      &lt;!DOCTYPE ACTIONS SYSTEM "actions.dtd"&gt;
	      
	      &lt;ACTIONS&gt;
	      &lt;ACTION NAME="HelloWorld"&gt;
	      &lt;CODE&gt;
	      new HelloWorld(view);
	      &lt;/CODE&gt;
	      &lt;/ACTION&gt;
	      &lt;/ACTIONS&gt;
	    </programlisting>
					</informalexample>
					<para>
	    Dentro de este archivo se define la única acción que tiene
	    el <foreignphrase>plugin</foreignphrase>, en donde se
	    llama una nueva instancia de la clase
	    <classname>HelloWorld</classname>, enviándosele por
	    parámetro el objeto <classname>view</classname> de la aplicación principal.
	  </para>
					<para>
	    El código que aparece dentro del tag &lt;CODE&gt; sigue
	    las reglas de sintaxis del código de
	    <application>BeanShell</application>.  Si desee encontrar
	    mayor información sobre la definición de
	    <filename>actions.xml</filename> o sobre
	    <application>BeanShell</application> puede consultar la
	    Guía de Usuario de <application>jEdit</application>, que
	    se encuentra dentro de la ayuda del programa.
	  </para>
				</sect3>
				<sect3 id="propiedades">
					<title>Propiedades</title>
					<para>
	    Para configurar un <foreignphrase>plugin</foreignphrase>
	    de manera externa, se fija cierta información relevante
	    para el <foreignphrase>plugin</foreignphrase> como lo
	    es el nombre
	    del <foreignphrase>plugin</foreignphrase>, el texto de los items
	    del menú, el texto desplegado en el
	    <foreignphrase>plugin</foreignphrase>, el nombre del archivo
	    de documentación, el autor, la versión, entre otros en un
	    archivo de texto.
	  </para>
					<para>
	    Esto también permite que <application>jEdit</application>
	    tenga acceso a las diferentes propiedades del
	    <foreignphrase>plugin</foreignphrase>, mediante la
	    extracción de las propiedades del éste del archivo de
	    texto.
	  </para>
					<para>
	    Para nuestro <foreignphrase>plugin</foreignphrase>
	    utilizaremos el archivo <filename>HelloWorld.props</filename>
	    , que ilustra el uso de estas propiedades. Puede encontrar su contenido en:
	  <xref linkend="HelloWorld.props"/>
					</para>
					<informalexample>
						<programlisting>
	      # Plugin properties
	      plugin.HelloWorldPlugin.name=Hello World !
	      plugin.HelloWorldPlugin.author=Jairo Martinez
	      plugin.HelloWorldPlugin.version=1.0
	      plugin.HelloWorldPlugin.docs=HelloWorld.html
	      
	      # Menu item label
	      HelloWorld.label=Hello World !
	      
	      # HelloWorld window
	      HelloWorld.title=Hello World plugin
	      HelloWorld.caption=Hello World !
</programlisting>
					</informalexample>
				</sect3>
			</sect2>
			<sect2 id="compiling">
				<title>Compilando el <foreignphrase>plugin</foreignphrase>
				</title>
				<para>
	  A la hora de compilar hay que tener cuidado en que se haya
	  incluido dentro de la variable del sistema, <varname>CLASSPATH</varname> la ruta
	  de las librerias de <application>jEdit</application>.  Las librerias de <application>jEdit</application> se
	  pueden encontrar en el directorio de instalación del
	  programa en un archivo <acronym>jar</acronym> llamado <filename>jedit.jar</filename>.
	</para>
				<para> Compile los archivos
	  <filename>HelloWorld.java</filename> y
	  <filename>HelloWorldPlugin.java</filename>, para obtener los
	  archivos <filename>HelloWorld.class</filename> y
	  <filename>HelloWorldPlugin.class</filename>.
	</para>
			</sect2>
			<sect2 id="makejar">
				<title>Empaquetar en un archivo <acronym>JAR</acronym>
				</title>
				<para>Ahora empaquetaremos los archivos que conformaran el
	  plugin en un archivo <acronym>JAR</acronym>, al que denominaremos
	  <filename>HelloWorld.jar</filename>.
	</para>
				<itemizedlist>
					<title>Estos son los archivos que empaquetaremos dentro del archivo <acronym>JAR</acronym>:</title>
					<listitem>
						<para>
							<filename>HelloWorld.class</filename>
						</para>
					</listitem>
					<listitem>
						<para>
							<filename>HelloWorldPlugin.class</filename>
						</para>
					</listitem>
					<listitem>
						<para>
							<filename>actions.xml</filename>
						</para>
					</listitem>
					<listitem>
						<para>
							<filename>HelloWorld.props</filename>
						</para>
					</listitem>
				</itemizedlist>
				<para> Una forma fácil de crear este archivo puede ser poner
	  los archivos citados anteriormente en un directorio y luego
	  utilizar el siguiente comando en ese directorio:
	</para>
				<informalexample>
					<screen>
						<userinput>jar cf HelloWorld.jar *</userinput>
					</screen>
				</informalexample>
				<para>El archivo <acronym>JAR</acronym> terminado lo puede
	  encontrar en este archivo: <ulink url="HelloWorld1/HelloWorld.jar">
						<filename>HelloWorld.jar</filename>
					</ulink>
				</para>
			</sect2>
			<sect2 id="movejar">
				<title>Ubicar el archivo <acronym>JAR</acronym>
				</title>
				<para>Para terminar, se debe ubicar el archivo <filename>HelloWorld.jar</filename>
	  en la carpeta: <filename class="directory">
						<replaceable>[directorio de instalacion de
	  JEdit]</replaceable>/jars</filename>
				</para>
				<informalfigure>
					<screenshot>
						<mediaobject>
							<imageobject>
								<imagedata fileref="images/jedit-tree.gif" format="GIF"/>
							</imageobject>
							<textobject>
								<phrase>jedit tree</phrase>
							</textobject>
						</mediaobject>
					</screenshot>
				</informalfigure>
			</sect2>
			<sect2 id="end">
				<title>Resultado final</title>
				<para>Para observar el <foreignphrase>plugin</foreignphrase>,
	  solo debemos ejecutar jEdit y luego hacer clic en el menú

	  <guimenu>Plugins</guimenu>
					<guisubmenu>Hello World!</guisubmenu>
				</para>
				<informalfigure>
					<screenshot>
						<mediaobject>
							<imageobject>
								<imagedata fileref="images/menu-plugin.gif" format="GIF"/>
							</imageobject>
							<textobject>
								<phrase>menu-plugin</phrase>
							</textobject>
						</mediaobject>
					</screenshot>
				</informalfigure>
				<para>Ahora debe aparecer una ventana de este estilo:
	</para>
				<informalfigure>
					<screenshot>
						<mediaobject>
							<imageobject>
								<imagedata fileref="images/hw1sc1.gif" format="GIF"/>
							</imageobject>
							<textobject>
								<phrase>HelloWorld window</phrase>
							</textobject>
						</mediaobject>
					</screenshot>
				</informalfigure>
				<para>¡Felicitaciones! ha terminado de desarrollar su primer
	  <foreignphrase>plugin</foreignphrase> para <application>jEdit</application>.
	</para>
				<important>
					<para>Hasta este punto se puede tener ya una buena idea de
	  cómo se desarrolla un
	  <foreignphrase>plugin</foreignphrase>, sin embargo, vale la
	  pena especificar claramente cuales son los requerimientos
	  básicos para un <foreignphrase>plugin</foreignphrase>.
	  Estos son:
	</para>
					<itemizedlist>
						<listitem>
							<para>Debe estar empaquetado en uno o más archivos <acronym>JAR</acronym> y
	      contener un archivo de clase que termine con el prefijo
	      Plugin y que herede de la clase abstracta
	      <classname>EditPlugin</classname>. Si el plugin debe
	      responder a cambios de estado en la aplicación <application>jEdit</application>,
	      esta clase debe ser heredar de la clase
	      <classname>EBPPlugin</classname>.</para>
						</listitem>
						<listitem>
							<para>El archivo <acronym>JAR</acronym> debe contener, por lo menos, un
	      archivo de propiedades que tenga como extensión <filename>.props</filename>.
	      Estas propiedades deben dar información sobre como el
	      <foreignphrase>plugin</foreignphrase> está
	      definido.</para>
						</listitem>
						<listitem>
							<para>El archivo <acronym>JAR</acronym> debe contener las
	      acciones que podrá realizar el
	      <foreignphrase>plugin</foreignphrase> para que estas
	      sean desplegadas dentro de la barra de menú de
	      <application>jEdit</application>.  Estas serán
	      especificadas en un archivo de nombre
	      <filename>actions.xml</filename>.</para>
						</listitem>
					</itemizedlist>
				</important>
			</sect2>
		</sect1>
	</chapter>
	<chapter>
		<title>Agregando funcionalidad al
    <foreignphrase>plugin</foreignphrase>
		</title>
		<para>A continuación buscaremos aumentar la funcionalidad del
      <foreignphrase>plugin</foreignphrase>
			<foreignphrase> Hello World !</foreignphrase> dando la
      posibilidad de mostrarse al estilo de un <foreignphrase>"wizard"</foreignphrase> o "asistente".
      Esto significa que el usuario será guiado paso a paso en el
      desarrollo de el proceso para realizar la tarea que cumple el
      <foreignphrase>plugin</foreignphrase>, mediante el uso de
      ventanas consecutivas, sobre las que le usuario podrá avanzar o
      retroceder haciendo uso de los botones "Siguiente o "Anterior",
      respectivamente.</para>
		<para>Anteriormente la función que realizaba el
      <foreignphrase>plugin</foreignphrase> era imprimir el mensaje
      <computeroutput>Hello World !</computeroutput> en pantalla . Esta vez, en vez imprimir el mensaje
      en pantalla, este será escrito en un archivo, el cual será
      escogido por el usuario. </para>
		<para>El <foreignphrase>plugin</foreignphrase> contará con tres
      ventanas que se desplegaran, en forma consecutiva, a medida que
      se haga clic en los botones citados anteriormente.</para>
		<para>Estas son las tres ventanas que desplegará el
      <foreignphrase>plugin</foreignphrase>:</para>
		<informalfigure>
			<screenshot>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/hw2sc1.jpg" format="JPG"/>
					</imageobject>
					<textobject>
						<phrase>Presentación</phrase>
					</textobject>
					<caption>
						<para>Presentación del <foreignphrase>plugin</foreignphrase>
						</para>
					</caption>
				</mediaobject>
			</screenshot>
		</informalfigure>
		<informalfigure>
			<screenshot>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/hw2sc2.jpg" format="JPG"/>
					</imageobject>
					<textobject>
						<phrase>Escoger un archivo</phrase>
					</textobject>
					<caption>
						<para>Escoger el archivo sobre el que se hará la esctritura de la frase "Hello World"</para>
					</caption>
				</mediaobject>
			</screenshot>
		</informalfigure>
		<informalfigure>
			<screenshot>
				<mediaobject>
					<imageobject>
						<imagedata fileref="images/hw2sc3.jpg" format="JPG"/>
					</imageobject>
					<textobject>
						<phrase>Mensaje final</phrase>
					</textobject>
					<caption>
						<para>Mensaje indicando que el proceso ha sido completado</para>
					</caption>
				</mediaobject>
			</screenshot>
		</informalfigure>
		<para>El <foreignphrase>plugin</foreignphrase> completo lo puede
    encontrar en el siguiente archivo: <ulink url="HelloWorld2/HelloWorld.jar">
				<filename>HelloWorld.jar</filename>
			</ulink>
		</para>
		<para>Para agregarle mayor funcionalidad al
      <foreignphrase>plugin</foreignphrase> se modificó la clase
      <classname>HelloWorld</classname> y se crearon nuevas clases.
      El proceso completo será explicado a continuación:</para>
		<sect1>
			<title>Modificar la clase <classname>HelloWorld</classname>
			</title>
			<para>Debido a que deseamos manejar el despliegue visual del
	<foreignphrase>plugin</foreignphrase> al estilo de un
	<foreignphrase>"wizard"</foreignphrase>, modificaremos la
	clase <classname>HelloWorld</classname> para que su única
	responsabilidad sea crear la clase
	<classname>WizardManager</classname>, a la cual delegaremos la
	responsabilidad del manejo de ventanas del
	<foreignphrase>plugin</foreignphrase>.</para>
			<para>El codigo final de esta clase quedó de la siguiente
	manera:</para>
			<programlisting>import org.gjt.sp.jedit.*;
	
	public class HelloWorld
	{
    	    public HelloWorld(View view)  {
	      WizardManager wizardManager = new WizardManager(view);
	    }
	}
</programlisting>
			<para>El código de esta clase lo puede encontrar en: <xref linkend="HelloWorld.java2"/>
			</para>
		</sect1>
		<sect1>
			<title>Creación de la clase <classname>WizardManager</classname>
			</title>
			<para>Esta clase será la encargada de desplegar la visualización
	correspondiente al paso de la tarea en que se encuentre el
	<foreignphrase>plugin</foreignphrase>.</para>
			<para>La información sobre el paso de la tarea donde se
	encuentra el <foreignphrase>plugin</foreignphrase> será
	almacenada en una variable de la clase llamada <classname>panelNumber</classname>.
	Esta variable podrá ser modificada mediante los métodos
	<methodname>next()</methodname> y
	<methodname>back()</methodname>, dependiendo de si se quiere
	avanzar o retroceder un paso.</para>
			<para>El código completo
	de esta clase lo puede encontrar en: <xref linkend="WizardManager.java"/>
			</para>
			<para>La variable <varname>panelNumber</varname> será
	inicializada en 0, cuando se cree por primera vez el objeto
	<classname>WizardManager</classname>.  Los metodos
	<methodname>next()</methodname> y
	<methodname>back()</methodname> se encargaran de incrementar o
	decrementar esta variable y luego mostrar el panel
	correspondiente.  La implementación de estos métodos es la
	siguiente:</para>
			<programlisting>
public void back() {
   panelNumber--; 
   showPanel(); 
}
	
public void next() {
   panelNumber++;
   showPanel();
}
</programlisting>
			<para>El método <methodname>showPanel()</methodname> es el
	encargado de mostrar el panel correspondiente al paso de la
	tarea en que se encuentra el
	<foreignphrase>plugin</foreignphrase>.  Este esta implementado
	así:</para>
			<programlisting>
public void showPanel() { 
   JPanel content=null;
	
   if(panelNumber==1)
	content = (JPanel) new HelloWorldPanel1();
   if(panelNumber==2)
	content = (JPanel) new HelloWorldPanel2();
   if(panelNumber==3)
	content = (JPanel) new HelloWorldPanel3();
	
   setContentPane(content);
   this.pack();
   this.repaint();
   this.show();
}
</programlisting>
			<para>Buscando obtener una mayor flexibilidad, facilidad de uso
      y claridad al hacer los llamados a los métodos de la clase
      <classname>WizardManager</classname> desde otras clases, se le
      aplicó a esta clase un patrón de construcción de software
      conocido como <foreignphrase>Singleton</foreignphrase>, que
      permite hacer llamados a los métodos de esta clase desde otras
      clases, como los paneles, sin que estas otras clases deban tener
      como atributo el objeto
      <classname>WizardManager</classname>. Para ello basta usar una
      línea como la siguiente</para>
			<programlisting>WizardManager.getInstance().<replaceable>metodo</replaceable>();
</programlisting>
		</sect1>
		<sect1>
			<title>Creación de la clase <classname>HelloWorldPanel1</classname>
			</title>
			<para>Esta clase contiene el panel correspondiente al primer
	paso del <foreignphrase>plugin</foreignphrase>.  Aquí se
	especifica tanto el componente gráfico del panel como su manejo
	de eventos.</para>
			<para>El código completo de esta clase lo puede encontrar en:  <xref linkend="HelloWorldPanel1.java"/>
			</para>
			<para>Para este panel, dado que es el primero, el botón
	"Anterior" será desactivado.</para>
			<para>Dentro del manejo de eventos de este panel se harán
	llamados a métodos de la clase <classname>WizardManager</classname>.  Por ejemplo,
	cuando se presiona el botón "Siguiente >" se llamará el método
	<methodname>next()</methodname> de la siguiente manera:</para>
			<programlisting>WizardManager.getInstance().next();</programlisting>
		</sect1>
		<sect1>
			<title>Creación de la clase <classname>HelloWorldPanel2</classname>
			</title>
			<para>Esta clase manejará el panel correspondiente al segundo
	paso del <foreignphrase>plugin</foreignphrase>, que se encarga
	de escoger el archivo en el que se hará la escritura.  </para>
			<para>El código completo de esta clase lo puede encontrar en:  <xref linkend="HelloWorldPane2.java"/>
			</para>
			<para>Para la selección del archivo utilizaremos la clase
	<classname>JFIleChooser</classname> de
	<application>Java</application>, la cual nos permitirá
	desplegar un cuadro de diálogo de selección de archivos y
	luego de que el usuario seleccione el archivo, podremos
	obtener las características del archivo seleccionado.</para>
			<para>Al presionar el botón "Examinar..." , se realizará el
	siguiente manejo del evento, que incluye el despliegue del
	cuadro de diálogo de selección de archivos y la obtención del
	archivo seleccionado:</para>
			<programlisting>
 void jButton4_actionPerformed(ActionEvent e) {
     JFileChooser jFileChooser1 = new JFileChooser();
     jFileChooser1.setDialogTitle("Ubicación del archivo resultante"); 

     int returnVal = jFileChooser1.showSaveDialog(WizardManager.getInstance()); 

     if	(returnVal == JFileChooser.APPROVE_OPTION) {
	 resultFile = jFileChooser1.getSelectedFile();
	 String path = new String (resultFile.getPath().toString());
	this.jTextField1.setText(path); 
     } else {
	jFileChooser1.setVisible(false); 
     } 
 }
</programlisting>
			<para>Luego, para imprimir en el archivo seleccionado se utilizará
   el método que posee el siguiente código:</para>
			<programlisting>
 public void printContentInFile(){
     String path = resultFile.getPath();
     FileWriter fw = null;
     PrintWriter pw = null;
     
     try {
	 File out = new File(path);
	 fw = new FileWriter(out);
	 pw = new PrintWriter(fw);
     }
     catch(Exception e){
	 JOptionPane.showMessageDialog(WizardManager.getInstance(),
				       e.getMessage(),    
				       "Error", JOptionPane.ERROR_MESSAGE);
     }
     
     pw.print("Hello World !");
     
     try {
	 pw.close();
	 fw.close();
     }
     catch(Exception e){
	 JOptionPane.showMessageDialog(WizardManager.getInstance(),
				       e.getMessage(),
				       "Error", JOptionPane.ERROR_MESSAGE);
     }
 } 
</programlisting>
		</sect1>
		<sect1>
			<title>Creación de la clase
      <classname>HelloWorldPanel3</classname>
			</title>
			<para>Por último, la clase <classname>HelloWorldPanel3</classname>
      manejará el panel correspondiente al paso final del
      <foreignphrase>plugin</foreignphrase>. Este panel solo estará
      encargado de desplegar el mensaje correspondiente al final del
      proceso.</para>
			<para>El código completo de esta clase lo puede encontrar en:  <xref linkend="HelloWorldPane3.java"/>
			</para>
		</sect1>
	</chapter>
	<appendix>
		<title/>
		<sect1 id="listing1">
			<title>Listado de archivos del <foreignphrase>plugin Hello World</foreignphrase>
			</title>
			<sect2 id="HelloWorldPlugin.java">
				<title>Archivo <filename>HelloWorldPlugin.java</filename>
				</title>
				<para>
					<programlisting>import org.gjt.sp.jedit.*;

import java.util.Vector;

public class HelloWorldPlugin extends EditPlugin
{
	public void createMenuItems(Vector menuItems)
	{
		menuItems.addElement(GUIUtilities.loadMenuItem("HelloWorld"));
	}
}</programlisting>
				</para>
			</sect2>
			<sect2 id="HelloWorld.java">
				<title>Archivo <filename>HelloWorld.java</filename>
				</title>
				<para>
					<programlisting>iimport javax.swing.*;
import org.gjt.sp.jedit.*;

public class HelloWorld extends JDialog
{
        // private members
        private View view;

        public HelloWorld(View view)
        {
                super(view,jEdit.getProperty("HelloWorld.title"),false);

                this.view = view;

                JPanel content = new JPanel();
                setContentPane(content);

                JLabel caption = new JLabel(jEdit.getProperty("HelloWorld.caption"));
                content.add(caption);

                pack();
                GUIUtilities.loadGeometry(this, "HelloWorld");
                setDefaultCloseOperation(DISPOSE_ON_CLOSE);
                show();
        }


        public void dispose()
        {
                view = null;
                GUIUtilities.saveGeometry(this, "HelloWorld");
                super.dispose();
        }
}</programlisting>
				</para>
			</sect2>
			<sect2 id="actions.xml">
				<title>Archivo <filename>actions.xml</filename>
				</title>
				<para>
					<programlisting>
	      &lt;?xml version="1.0"?&gt;
	      
	      &lt;!DOCTYPE ACTIONS SYSTEM "actions.dtd"&gt;
	      
	      &lt;ACTIONS&gt;
	      &lt;ACTION NAME="HelloWorld"&gt;
	      &lt;CODE&gt;
	      new HelloWorld(view);
	      &lt;/CODE&gt;
	      &lt;/ACTION&gt;
	      &lt;/ACTIONS&gt;
	    </programlisting>
				</para>
			</sect2>
			<sect2 id="HelloWorld.props">
				<title>Archivo <filename>HelloWorld.props</filename>
				</title>
				<para>
					<programlisting># Plugin properties
plugin.HelloWorldPlugin.name=Hello World !
plugin.HelloWorldPlugin.author=Jairo Martinez
plugin.HelloWorldPlugin.version=1.0
plugin.HelloWorldPlugin.docs=HelloWorld.html

# Menu item label
HelloWorld.label=Hello World !

# HelloWorld window
HelloWorld.title=Hello World plugin
HelloWorld.caption=Hello World !</programlisting>
				</para>
			</sect2>
		</sect1>
		<sect1 id="listing2">
			<title>Listado de archivos del <foreignphrase>plugin Hello World</foreignphrase> modificado para agregarle mayor funcionalidad
			</title>
			<sect2 id="HelloWorld.java2">
				<title>Archivo <filename>HelloWorld.java</filename>
				</title>
				<para>
					<programlisting>import org.gjt.sp.jedit.*;

public class HelloWorld
{
  public HelloWorld(View view)  {
    WizardManager wizardManager = new WizardManager(view);
  }
}</programlisting>
				</para>
			</sect2>
			<sect2 id="WizardManager.java">
				<title>Archivo <filename>WizardManager.java</filename>
				</title>
				<para>
					<programlisting>import javax.swing.*;
import org.gjt.sp.jedit.*;

public class WizardManager extends JDialog  {

  private View view;
  private int panelNumber = 0;
  private static WizardManager instance = null;

  public WizardManager(View view) {
    super(view,jEdit.getProperty("HelloWorld.title"),false);
    this.view = view;
    this.instance = this;
    GUIUtilities.loadGeometry(this, "HelloWorld");
    setDefaultCloseOperation(DISPOSE_ON_CLOSE);
    next();
  }

  public static  WizardManager getInstance () {
    return instance;
  }

  public void dispose() {
    view = null;
    GUIUtilities.saveGeometry(this, "HelloWorld");
    super.dispose();
  }

  public void back()  {
    panelNumber--;
    showPanel();
  }

  public void next() {
    panelNumber++;
    showPanel();
  }

  public void showPanel()  {
    JPanel content=null;

    if(panelNumber==1)
      content = (JPanel) new HelloWorldPanel1();
    if(panelNumber==2)
      content = (JPanel) new HelloWorldPanel2();
    if(panelNumber==3)
      content = (JPanel) new HelloWorldPanel3();

    setContentPane(content);
    this.pack();
    this.repaint();
    this.show();
  }

}</programlisting>
				</para>
			</sect2>
			<sect2 id="HelloWorldPanel1.java">
				<title>Archivo <filename>HelloWorldPanel1.java</filename>
				</title>
				<para>
					<programlisting>import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class HelloWorldPanel1 extends JPanel {
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel jPanel1 = new JPanel();
  JPanel jPanel2 = new JPanel();
  JButton jButton1 = new JButton();
  JButton jButton2 = new JButton();
  JButton jButton3 = new JButton();
  GridLayout gridLayout1 = new GridLayout();
  JLabel jLabel1 = new JLabel();
  JLabel jLabel2 = new JLabel();
  JLabel jLabel3 = new JLabel();
  JLabel jLabel4 = new JLabel();

  public HelloWorldPanel1() {
    try {
      jbInit();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
  }

  void jbInit() throws Exception {
    this.setLayout(borderLayout1);
    jButton1.setEnabled(false);
    jButton1.setText("&lt; Anterior");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton1_actionPerformed(e);
      }
    });
    jButton2.setText("Siguiente &gt;");
    jButton2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton2_actionPerformed(e);
      }
    });
    jButton3.setText("Cancelar");
    jButton3.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton3_actionPerformed(e);
      }
    });
    jPanel1.setLayout(gridLayout1);
    jLabel1.setFont(new java.awt.Font("Dialog", 1, 16));
    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel1.setText("Bienvenido al plugin Hello World !");
    jLabel2.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel2.setText("Este plugin le permitira escribir en un archivo");
    gridLayout1.setRows(4);
    gridLayout1.setColumns(1);
    jLabel3.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel3.setText("escogido la frase \"Hello World !\"");
    jLabel4.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel4.setText("Presione el boton \"Siguiente &gt;\" para continuar");
    this.add(jPanel1,  BorderLayout.CENTER);
    jPanel1.add(jLabel1, null);
    jPanel1.add(jLabel2, null);
    jPanel1.add(jLabel3, null);
    jPanel1.add(jLabel4, null);
    this.add(jPanel2, BorderLayout.SOUTH);
    jPanel2.add(jButton1, null);
    jPanel2.add(jButton2, null);
    jPanel2.add(jButton3, null);

  }

  void jButton1_actionPerformed(ActionEvent e) {
    WizardManager.getInstance().back();
  }

  void jButton2_actionPerformed(ActionEvent e) {
    WizardManager.getInstance().next();
  }

  void jButton3_actionPerformed(ActionEvent e) {
     WizardManager.getInstance().dispose();
  }
}s.CENTER);
    jLabel3.setText("escogido la frase \"Hello World !\"");
    jLabel4.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel4.setText("Presione el boton \"Siguiente >\" para continuar");
    this.add(jPanel1,  BorderLayout.CENTER);
    jPanel1.add(jLabel1, null);
    jPanel1.add(jLabel2, null);
    jPanel1.add(jLabel3, null);
    jPanel1.add(jLabel4, null);
    this.add(jPanel2, BorderLayout.SOUTH);
    jPanel2.add(jButton1, null);
    jPanel2.add(jButton2, null);
    jPanel2.add(jButton3, null);

  }

  void jButton1_actionPerformed(ActionEvent e) {
    WizardManager.getInstance().back();
  }

  void jButton2_actionPerformed(ActionEvent e) {
    WizardManager.getInstance().next();
  }

  void jButton3_actionPerformed(ActionEvent e) {
     WizardManager.getInstance().dispose();
  }
}</programlisting>
				</para>
			</sect2>
			<sect2 id="HelloWorldPane2.java">
				<title>Archivo <filename>HelloWorldPane2.java</filename>
				</title>
				<para>
					<programlisting>import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class HelloWorldPanel2 extends JPanel {
  File resultFile;
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel jPanel1 = new JPanel();
  JPanel jPanel2 = new JPanel();
  JButton jButton1 = new JButton();
  JButton jButton2 = new JButton();
  JButton jButton3 = new JButton();
  GridLayout gridLayout1 = new GridLayout();
  JLabel jLabel1 = new JLabel();
  JLabel jLabel2 = new JLabel();
  JPanel jPanel3 = new JPanel();
  JButton jButton4 = new JButton();
  JLabel jLabel3 = new JLabel();
  JTextField jTextField1 = new JTextField();
  JLabel jLabel4 = new JLabel();

  public HelloWorldPanel2() {
    try {
      jbInit();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
  }

  void jbInit() throws Exception {
    this.setLayout(borderLayout1);
    jButton1.setText("&lt; Anterior");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton1_actionPerformed(e);
      }
    });
    jButton2.setText("Siguiente >");
    jButton2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton2_actionPerformed(e);
      }
    });
    jButton3.setText("Cancelar");
    jButton3.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton3_actionPerformed(e);
      }
    });
    jPanel1.setLayout(gridLayout1);
    jLabel1.setFont(new java.awt.Font("Dialog", 1, 16));
    jLabel1.setToolTipText("");
    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel1.setText("Escoja el archivo");
    jLabel2.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel2.setText("Presione el boton \"Examinar...\" para escoger");
    gridLayout1.setRows(3);
    gridLayout1.setColumns(1);
    jButton4.setText("Examinar...");
    jButton4.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton4_actionPerformed(e);
      }
    });
    jLabel3.setToolTipText("");
    jLabel3.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel3.setText("el nombre y ubicación del archivo");
    jTextField1.setColumns(15);
    jLabel4.setText("Ubicación");
    this.add(jPanel1, BorderLayout.NORTH);
    jPanel1.add(jLabel1, null);
    jPanel1.add(jLabel2, null);
    jPanel1.add(jLabel3, null);
    this.add(jPanel2,  BorderLayout.SOUTH);
    jPanel2.add(jButton1, null);
    jPanel2.add(jButton2, null);
    jPanel2.add(jButton3, null);
    this.add(jPanel3,  BorderLayout.CENTER);
    jPanel3.add(jLabel4, null);
    jPanel3.add(jTextField1, null);
    jPanel3.add(jButton4, null);

  }

  void jButton1_actionPerformed(ActionEvent e) {
    WizardManager.getInstance().back();
  }

  void jButton2_actionPerformed(ActionEvent e) {
    printContentInFile();
    WizardManager.getInstance().next();
  }

  void jButton3_actionPerformed(ActionEvent e) {
     WizardManager.getInstance().dispose();
  }

  void jButton4_actionPerformed(ActionEvent e) {
    JFileChooser jFileChooser1 = new JFileChooser();
    jFileChooser1.setDialogTitle("Ubicación del archivo resultante");
    int returnVal = jFileChooser1.showSaveDialog(WizardManager.getInstance());
    if (returnVal == JFileChooser.APPROVE_OPTION) {
      resultFile = jFileChooser1.getSelectedFile();
      String path = new String (resultFile.getPath().toString());
      this.jTextField1.setText(path);
    } else {
        jFileChooser1.setVisible(false);
    }
  }

  public void printContentInFile(){
    String path = resultFile.getPath();
    FileWriter fw = null;
    PrintWriter pw = null;

    try {
      File out = new File(path);
      fw = new FileWriter(out);
      pw = new PrintWriter(fw);
    }
    catch(Exception e){
      JOptionPane.showMessageDialog(WizardManager.getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
    }

    pw.print("Hello World !");

    try {
          pw.close();
          fw.close();
    }
    catch(Exception e){
      JOptionPane.showMessageDialog(WizardManager.getInstance(), e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
    }
  }
}</programlisting>
				</para>
			</sect2>
			<sect2 id="HelloWorldPane3.java">
				<title>Archivo <filename>HelloWorldPane3.java</filename>
				</title>
				<para>
					<programlisting>import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class HelloWorldPanel3 extends JPanel {
  BorderLayout borderLayout1 = new BorderLayout();
  JPanel jPanel1 = new JPanel();
  JPanel jPanel2 = new JPanel();
  JButton jButton1 = new JButton();
  JButton jButton2 = new JButton();
  JButton jButton3 = new JButton();
  GridLayout gridLayout1 = new GridLayout();
  JLabel jLabel1 = new JLabel();
  JLabel jLabel2 = new JLabel();
  JLabel jLabel3 = new JLabel();
  JLabel jLabel4 = new JLabel();

  public HelloWorldPanel3() {
    try {
      jbInit();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
  }

  void jbInit() throws Exception {
    this.setLayout(borderLayout1);
    jButton1.setText("&lt; Anterior");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton1_actionPerformed(e);
      }
    });
    jButton2.setText("Terminar");
    jButton2.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton2_actionPerformed(e);
      }
    });
    jButton3.setText("Cancelar");
    jButton3.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(ActionEvent e) {
        jButton3_actionPerformed(e);
      }
    });
    jPanel1.setLayout(gridLayout1);
    jLabel1.setFont(new java.awt.Font("Dialog", 1, 16));
    jLabel1.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel1.setText("Gracias por utilizar el plugin Hello World !");
    jLabel2.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel2.setText("La frase \"Hello World !\" ha quedado escrita");
    gridLayout1.setRows(4);
    gridLayout1.setColumns(1);
    jLabel3.setHorizontalAlignment(SwingConstants.CENTER);
    jLabel3.setText("en el archivo que usted ha escogido. ");
    jLabel4.setToolTipText("");
    jLabel4.setHorizontalAlignment(SwingConstants.CENTER);
    this.add(jPanel1,  BorderLayout.CENTER);
    jPanel1.add(jLabel1, null);
    jPanel1.add(jLabel2, null);
    jPanel1.add(jLabel3, null);
    jPanel1.add(jLabel4, null);
    this.add(jPanel2, BorderLayout.SOUTH);
    jPanel2.add(jButton1, null);
    jPanel2.add(jButton2, null);
    jPanel2.add(jButton3, null);

  }

  void jButton1_actionPerformed(ActionEvent e) {
    WizardManager.getInstance().back();
  }

  void jButton2_actionPerformed(ActionEvent e) {
    WizardManager.getInstance().dispose();
  }

  void jButton3_actionPerformed(ActionEvent e) {
     WizardManager.getInstance().dispose();
  }
}</programlisting>
				</para>
			</sect2>
		</sect1>
	</appendix>
</book>
