implementación en el lenguaje java de una

Anuncio
IMPLEMENTACIÓN EN EL LENGUAJE
JAVA DE UNA HERRAMIENTA DE
EDICIÓN PARA XML SCHEMA
CÓDIGO
Departamento de Ingeniería de Sistemas y Automática. Área de Ingeniería Telemática.
Escuela Superior de Ingenieros. Universidad de Sevilla
PROYECTO FIN DE CARRERA
REALIZADO POR: María del Pilar Jiménez Guijarro
DIRIGIDO POR: D. Antonio J. Sierra Collado
Sevilla, Febrero 2007
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
Annotation.java
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
/** Clase encargada de la creación de un cuadro de
* diálogo para la inserción de un elemento Annotation.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class Annotation extends JDialog {
/* Esta clase crea el diálogo, pero no realiza la llamada a setVisible(true).
* Esto es debido a que, si la llamada se hace desde dentro de esta clase
* (ver linea de código comentada más adelante), y al utilizar setModal(true),
* al pulsar los botones del diálogo, no se detectan los eventos que deberían
* producirse. Para evitar esto, hay que crear el objeto y llamar a
* setVisible(true) en el punto de creación del objeto. */
JRadioButton doc;
JRadioButton app;
ButtonGroup group;
JTextField jtf;
JTextField lenguaje ;
boolean cerrado = false;
/** Constructor de la clase. */
Annotation(){
setTitle("WIZARD: Annotation.");
-3-
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
setModal(true);
inicializar();
}
/** Método encargado de la creación de los elementos
* que forman el cuadro de diálogo. */
public void inicializar(){
/* Clase anonima para que la aplicacion se cierre al
* pulsar la X (boton esquina superior derecha). */
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
cerrado = true;
}
});
/* Creación de los elementos JPanel. */
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
JPanel pan1 = new JPanel();
JPanel pan2 = new JPanel();
BorderLayout bl1 = new BorderLayout();
pan1.setLayout(bl1);
BoxLayout bl2 = new BoxLayout(pan2,BoxLayout.Y_AXIS);
pan2.setLayout(bl2);
pan2.setBorder(new EmptyBorder(10, 30, 20, 10));
/* Creación de los Radio Button y del grupo de botones. */
String docString = "documentation";
doc = new JRadioButton(docString);
doc.setMnemonic('d');
doc.setActionCommand(docString);
doc.setSelected(true);
String appString = "appinfo";
app = new JRadioButton(appString);
app.setActionCommand(appString);
app.setMnemonic('a');
/* Creación de la etiqueta y el campo de texto para el lenguaje. */
JLabel jl = new JLabel("
xml:lang = ");
lenguaje = new JTextField (2);
lenguaje.setPreferredSize(new Dimension(10,5));
group = new ButtonGroup();
group.add(doc);
-4-
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
group.add(app);
AnnotationRL myListener = new AnnotationRL(lenguaje);
doc.addActionListener(myListener);
app.addActionListener(myListener);
/* Añadimos los elementos al panel. */
pan1.add(new JLabel(" Select one of the following elements:"));
pan1.add(doc, BorderLayout.NORTH);
pan1.add(jl, BorderLayout.WEST);
pan1.add(lenguaje, BorderLayout.CENTER);
pan1.add(app, BorderLayout.SOUTH);
/* Campo de texto y etiqueta para el texto del elemento Annotation. */
jtf = new JTextField();
jtf.setPreferredSize(new Dimension(150,50));
JLabel lab = new JLabel("Insert your annotation´s text: ");
/* Añadimos los elementos al panel. */
pan2.add(lab);
pan2.add(jtf);
/* Introducimos los dos JPanel en el JSplitPane. */
sp.setLeftComponent(pan1);
sp.setRightComponent(pan2);
sp.setDividerLocation(200);
/* Se crea el array de objetos con el texto
* introductorio y el splitPane anterior. */
JLabel intro = new JLabel("Fill in the following fields, please.");
Object[] array = {intro, sp};
/* Se crea el JOptionPane y se establece como
* contenido del cuadro de diálogo. */
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
Object[] options = {btnString1, btnString2};
JOptionPane jop = new JOptionPane(array, JOptionPane.
PLAIN_MESSAGE,JOptionPane.YES_NO_OPTION,
null, options, options[0]);
setContentPane(jop);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setSize(450, 200);
-5-
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
setLocation(525,375);
/* NO PONER setVisible(true); AQUI!!! Si se pone aquí en vez de desde
* donde creamos el objeto, cuando se pone setModal(true) se produce
* un error: no reconoce las pulsaciones de botón.*/
/* Listeners para eventos Action y PropertyChange. */
TextFieldAL tfal = new TextFieldAL(jop);
jtf.addActionListener(tfal);
lenguaje.addActionListener(tfal);
AnnotationPCL pcl = new AnnotationPCL(this, jop, jtf, lenguaje);
jop.addPropertyChangeListener(pcl);
}
}
-6-
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
AnnotationPCL.java
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
/** Clase que escucha cambios en las propiedades del cuadro
* de diálogo creado por la clase Annotation.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class AnnotationPCL implements PropertyChangeListener {
JDialog d;
JOptionPane jop;
JTextField jtf;
JTextField lenguaje;
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
String typedText = null;
String typedText2 = null;
/** Constructor de la clase. */
AnnotationPCL(JDialog dialogo, JOptionPane option,
JTextField textField, JTextField lang){
d = dialogo;
jop = option;
jtf = textField;
lenguaje = lang;
}
/* Se ejecuta si se produce un evento PropertyChange.
* Hereda comentario de documentación. */
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
-7-
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
if (d.isVisible() && (e.getSource() == jop) &&
(prop.equals(JOptionPane.VALUE_PROPERTY) || prop.
equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
Object value = jop.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
return;
}
if (value.equals(btnString1)) {
typedText = jtf.getText();
typedText2 = lenguaje.getText();
/* Miramos si el campo de texto de lenguaje está activado
* y si tiene texto, así como si el otro campo de texto
* no esta vacio. Si se cumple, quitamos el diálogo de
* pantalla. */
if (!typedText.equals("") && lenguaje.isEnabled()
&& !typedText2.equals("")) {
d.setVisible(false);
}
/* Si el campo de lenguaje no está activado, miramos
* que el segundo campo de texto no esté vacío. */
else if (!typedText.equals("") && !lenguaje.isEnabled()){
d.setVisible(false);
}
else {
/* Falta algún elemento de texto de los necesarios*/
JOptionPane.showMessageDialog(d,"
There"+
" is some text missing. \n
Fill in " +
"all the fields, please.","ERROR",
JOptionPane.ERROR_MESSAGE);
/* Reseteamos el valor del JOptionPane. */
jop.setValue(JOptionPane.
UNINITIALIZED_VALUE);
}
}
else {
/*Si cancelamos, no hacemos nada*/
jtf.setText("");
d.setVisible(false);
}
}
}
}
-8-
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
AnnotationRL.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JTextField;
/** Clase que escucha las acciones realizadas sobre los
* botones de radio de la clase Attribute.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class AnnotationRL implements ActionListener {
String docString = "documentation";
JTextField jtf;
/** Constructor de la clase. */
AnnotationRL(JTextField lenguaje){
jtf=lenguaje;
}
/** Activa o desactiva el campo de texto correspondiente
* al lenguaje, asociado a la opción documentation de la
* clase Attribute. */
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals(docString)){
jtf.setEnabled(true);
}
else
jtf.setEnabled(false);
}
}
-9-
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Attribute.java
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/** Clase encargada de la creación de un cuadro de
* diálogo para la inserción de un elemento Attribute.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class Attribute extends JDialog {
JTextField jtf1;
JTextField jtf2;
JTextField jtf3;
JTextField jtf4;
JTextField jtf5;
JLabel jl1;
JLabel jl2;
JLabel jl3;
JLabel jl4;
JLabel jl5;
JTextField lenguaje;
boolean annotation;
boolean cancelado = false;
boolean cerrado = false;
/** Constructor de la clase. */
Attribute(){
setTitle("WIZARD: Attribute.");
setModal(true);
inicializar();
}
- 10 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/** Método encargada de la creación de los elementos
* que forman el cuadro de diálogo. */
public void inicializar(){
/* Clase anonima para que la aplicacion se cierre al
* pulsar la X (boton esquina superior derecha). */
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
cerrado = true;
}
});
/* Se crean los elementos y se añaden al panel. */
JPanel pan1 =new JPanel();
GridLayout gl = new GridLayout(7,2);
pan1.setLayout(gl);
jl1 = new JLabel("name : ");
jl2 = new JLabel("type : ");
jl3 = new JLabel("id ? : ");
jl4 = new JLabel("use ? : ");
jl5 = new JLabel("value ? : ");
jtf1 = new JTextField();
jtf2 = new JTextField();
jtf3 = new JTextField();
jtf4 = new JTextField();
jtf5 = new JTextField();
pan1.add(jl1);
pan1.add(jtf1);
pan1.add(jl2);
pan1.add(jtf2);
pan1.add(jl3);
pan1.add(jtf3);
pan1.add(jl4);
pan1.add(jtf4);
pan1.add(jl5);
pan1.add(jtf5);
pan1.add(new JLabel (""));
pan1.add(new JLabel (""));
JCheckBox jcb = new JCheckBox("Add Annotation");
pan1.add(jcb);
/* Se crea el array de objetos con el texto
* introductorio y el panel anterior. */
- 11 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
JLabel intro = new JLabel("Fill in the following" +
" fields, please. ( ? = optional )");
Object[] array = {intro, pan1};
/* Se crea el JOptionPane y se establece como
* contenido del cuadro de diálogo. */
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
Object[] options = {btnString1, btnString2};
JOptionPane jop = new JOptionPane(array, JOptionPane.
PLAIN_MESSAGE,JOptionPane.YES_NO_OPTION,
null, options, options[0]);
setContentPane(jop);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setSize(260, 270);
setLocation(525,375);
/* Listeners para eventos Action y PropertyChange. */
TextFieldAL tfal = new TextFieldAL(jop);
jtf1.addActionListener(tfal);
jtf2.addActionListener(tfal);
jtf3.addActionListener(tfal);
jtf4.addActionListener(tfal);
jtf5.addActionListener(tfal);
AttributePCL pcl = new AttributePCL(this, jop, jtf1, jtf2, jcb);
jop.addPropertyChangeListener(pcl);
}
}
- 12 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
AttributeGroup.java
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
/** Clase encargada de la creación de un cuadro de diálogo
* para la inserción de un elemento AttributeGroup.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class AttributeGroup extends JDialog {
JTextField jtf1;
JTextField jtf2;
JLabel jl1;
JLabel jl2;
boolean annotation;
boolean cancelado = false;
boolean cerrado = false;
/** Constructor de la clase. */
AttributeGroup(){
setTitle("WIZARD: AttributeGroup.");
setModal(true);
inicializar();
}
/** Método encargado de la creación de los elementos
* que forman el cuadro de diálogo. */
public void inicializar(){
- 13 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/* Clase anonima para que la aplicacion se cierre al
* pulsar la X (boton esquina superior derecha). */
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
cerrado = true;
}
});
/* Se crean los elementos y se añaden al panel. */
JPanel pan1 =new JPanel();
GridLayout gl = new GridLayout(4,2);
pan1.setLayout(gl);
JLabel jl1 = new JLabel("Group´s name : ");
JLabel jl2 = new JLabel("Number of attributes : ");
jtf1 = new JTextField();
jtf2 = new JTextField();
pan1.add(jl1);
pan1.add(jtf1);
pan1.add(jl2);
pan1.add(jtf2);
pan1.add(new JLabel (""));
pan1.add(new JLabel (""));
JCheckBox jcb = new JCheckBox("Add Annotation");
pan1.add(jcb);
/* Se crea el array de objetos con el texto
* introductorio y el panel anterior. */
JLabel intro = new JLabel("Fill in the following " +
"fields, please. ( ? = optional )");
Object[] array = {intro, pan1};
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
Object[] options = {btnString1, btnString2};
/* Se crea el JOptionPane y se establece como
* contenido del cuadro de diálogo. */
JOptionPane jop = new JOptionPane(array, JOptionPane.
PLAIN_MESSAGE,JOptionPane.YES_NO_OPTION,
null, options, options[0]);
setContentPane(jop);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
- 14 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
setSize(270, 190);
setLocation(525,375);
/* Listeners para eventos Action y PropertyChange. */
TextFieldAL tfal = new TextFieldAL(jop);
jtf1.addActionListener(tfal);
jtf2.addActionListener(tfal);
AttributeGroupPCL pcl = new AttributeGroupPCL(
this, jop, jtf1, jtf2, jcb);
jop.addPropertyChangeListener(pcl);
}
}
- 15 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
AttributeGroupPCL.java
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
/** Clase que escucha cambios en las propiedades del cuadro
* de diálogo creado por la clase AttributeGroup.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class AttributeGroupPCL implements PropertyChangeListener {
AttributeGroup d;
JOptionPane jop;
JTextField name;
JTextField number;
JCheckBox jcb;
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
String typedText = null;
String typedText2 = null;
/** Constructor de la clase. */
AttributeGroupPCL(AttributeGroup dialogo, JOptionPane option,
JTextField nombre, JTextField num_att, JCheckBox box){
d = dialogo;
jop = option;
name = nombre;
number = num_att;
jcb = box;
}
/* Se ejecuta si se produce un evento PropertyChange.
* Hereda comentario de documentación.*/
public void propertyChange(PropertyChangeEvent e) {
- 16 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
String prop = e.getPropertyName();
if (d.isVisible() && (e.getSource() == jop)&&
(prop.equals(JOptionPane.VALUE_PROPERTY) || prop.
equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
Object value = jop.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
return;
}
if (value.equals(btnString1)) {
typedText = name.getText();
typedText2 = number.getText();
/* Miramos si los campos obligatorios contienen texto. */
if (!typedText.equals("") && !typedText2.equals("")) {
if(jcb.isSelected())
d.annotation = true;
d.setVisible(false);
}
else {
/* Falta algún elemento de texto de los necesarios*/
JOptionPane.showMessageDialog(d,"
There"+
" is some text missing. \n
Fill in " +
"all the fields, please.","ERROR",
JOptionPane.ERROR_MESSAGE);
jop.setValue(JOptionPane.
UNINITIALIZED_VALUE);
}
}
else {
/*Si cancelamos, no hacemos nada*/
d.cancelado = true;
d.setVisible(false);
}
}
}
}
- 17 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
AttributePCL.java
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
/** Clase que escucha cambios en las propiedades del cuadro
* de diálogo creado por la clase Attribute.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class AttributePCL implements PropertyChangeListener {
Attribute d;
JOptionPane jop;
JTextField name;
JTextField type;
JCheckBox jcb;
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
String typedText = null;
String typedText2 = null;
/** Constructor de la clase. */
AttributePCL(Attribute dialogo, JOptionPane option, JTextField nombre,
JTextField tipo, JCheckBox box){
d = dialogo;
jop = option;
name = nombre;
type = tipo;
jcb = box;
}
/* Se ejecuta si se produce un evento PropertyChange.
* Hereda comentario de documentación. */
public void propertyChange(PropertyChangeEvent e) {
- 18 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
String prop = e.getPropertyName();
if (d.isVisible() && (e.getSource() == jop) &&
(prop.equals(JOptionPane.VALUE_PROPERTY) ||prop.
equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
Object value = jop.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
return;
}
if (value.equals(btnString1)) {
typedText = name.getText();
typedText2 = type.getText();
/* Miramos si los campos obligatorios contienen texto. */
if (!typedText.equals("") && !typedText2.equals("")) {
if(jcb.isSelected())
d.annotation = true;
d.setVisible(false);
}
else {
/* Falta algún elemento de texto de los necesarios*/
JOptionPane.showMessageDialog(d,"
There"+
" is some text missing. \n
Fill in " +
"all the fields, please.","ERROR",
JOptionPane.ERROR_MESSAGE);
jop.setValue(JOptionPane.
UNINITIALIZED_VALUE);
}
}
else {
/*Si cancelamos, no hacemos nada*/
d.cancelado = true;
d.setVisible(false);
}
}
}
}
- 19 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
CodeDocument.java
import java.util.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
/** Clase encargada del tratamiento del texto
* que se inserta en un panel de edición.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class CodeDocument extends DefaultStyledDocument{
/* Almacena el valor del prefijo asignado al
* espacio de nombres de XML Schema.*/
String prefijo;
MyJEditorPane jep;
/* Variable booleana para saber si estamos leyendo de un archivo, en cuyo
* caso usaremos el insertString de la clase padre, sin hacer ningún tipo
* de comparación y con el AttributeSet que nos pasan como parametro. Si
* no estamos leyendo de un archivo sino insertando caracteres por teclado
* sí haremos las comprobaciones. */
boolean leer = false;
/* Para almacenar las palabras clave a insertar. */
private String word = "";
/* Posición actual de inserción de texto. */
private int currentPos = 0;
/* Vector que contiene las palabras clave de XML Schema. */
private Vector keywords = new Vector();
/* Modos en los que podemos encontrarnos al tratar el texto y variable
* (mode) que almacena el modo en que estamos en cada instante.*/
public static int STRING_MODE = 10;
public static int TEXT_MODE = 11;
public static int PI_MODE = 12;
public static int COMMENT_MODE = 13;
private int mode = TEXT_MODE;
- 20 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
boolean insertando_varios = false;
/* Se utiliza para, al poner un signo ">", no poner la etiqueta de
* cierre salvo si lo que tenemos previamente es una palabra clave. */
boolean palabra_clave = false;
/* Variables para almacenar el punto en que se encuentra el Caret y
* ver si ha sido desplazado a un punto no contiguo a donde estaba.*/
int posicion_previa = 0;
int posicion_aux;
/* Variable para indicar que es el caracter ">", para que cuando sea cierre de
* comentario o PI y vengamos de otro renglón NO LO PONGA EN ROJO. */
boolean cierre = false;
boolean cierre_com = false;
boolean cierre_pi = false;
/* Cuentan el número de etiquetas de apertura y cierre de PI o comentario. */
int abre_comment = 0;
int cierra_comment = 0;
int abre_PI = 0;
int cierra_PI = 0;
/* ****************************************************** */
/* ****************** CONSTRUCTOR ******************* */
/* ****************************************************** */
/** Constructor de la clase. */
public CodeDocument(MyJEditorPane j) {
jep = j;
}
/* ****************************************************** */
/* **************** INSERCIÓN DE TEXTO **************** */
/* ****************************************************** */
/** Método sobrescrito:acepta cualquier longitud de
* cadena y realiza el procesamiento de caracteres. */
public void insertString(int offs, String str,
AttributeSet a) throws BadLocationException{
posicion_previa = currentPos;
if(!leer){
- 21 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
super.insertString(offs, str, jep.normal);
int strLen = str.length();
if(strLen > 1)
insertando_varios = true;
int endpos = offs + strLen;
int strpos;
for (int i=offs;i<endpos;i++){
currentPos = i;
strpos = i - offs;
processChar(str.charAt(strpos));
}
currentPos = offs;
insertando_varios= false;
}
else
super.insertString(offs, str, a);
}
/* ****************************************************** */
/* ********* PROCESAMIENTO DE CARACTERES ********** */
/* ****************************************************** */
/** Método que convierte el char que se le pasa como parámetro
* a String y llama a proccessChar(String str). */
public void processChar(char strChar){
char[] chrstr = new char[1];
chrstr[0] = strChar;
String str = new String(chrstr);
processChar(str);
}
/** Método que procesa cada caracter para ver en qué modo estamos,
* a qué modo hay que pasar y cuales son las acciones a realizar. */
public void processChar(String str){
char strChar = str.charAt(0);
posicion_aux=posicion_previa + 1;
/* CUIDADO: Lo que viene ahora se encarga de buscar comentarios
* o PIs si hemos cambiado la posición del cursor. Estas
* comprobaciones no las haremos cuando estamos insertando
- 22 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* varios elementos a la vez, es decir, un string completo
* (mediante un copy-paste por ejemplo), ya que insertString
* se encarga, en este caso, de que se compruebe si hay PI
* o comentario al insertar así. */
if(!insertando_varios){
if(posicion_aux != currentPos){
/* Reinicializamos estas variables antes de hacer
* el tratamiento. */
cierre = false;
cierre_com = false;
cierre_pi = false;
if (strChar == '>')
cierre = true;
/* Sólo válido para que, en el caso de tener "<!-" e
* introducir "-", se retire lo anterior y se ponga
* todo "<!--" de color verde. */
if (strChar == '-')
checkForComment();
buscar_comment();
if (mode == TEXT_MODE)
buscar_PI();
else{
/* Si el caracter es ">", saldremos de la función
* buscar_comment()en modo comentario. En ese
* caso, si no se hace lo que sigue, escribiriamos
* en verde (comentario). Con las lineas siguientes
* se consigue que pasemos a ver si ese cierre
* pertenece al cierre de un PI (?>), o si sólo
* forma parte de un comentario o de un PI. */
if(!cierre_com && cierre_pi)
buscar_PI();
}
}
}
if(mode == COMMENT_MODE){
switch (strChar){
case('>'):{
/* Ponemos ya a false la variable cierre. */
cierre = false;
/*Para ver cuando cambiar el modo comentario. */
checkForComment();
/* Si después de esta función seguimos en modo
- 23 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* comentario es porque no era cierre, entonces
* hay que escribir el ">" en color verde. Como
* en el método insertString ya ha sido insertado
* el elemento, lo sustituimos en color verde
* mediante insertCommentString(). */
if(mode==COMMENT_MODE){
insertCommentString(str, this.currentPos);
}
break;
}
default:
insertCommentString(str, this.currentPos);
}
}
else if(mode == PI_MODE){
switch (strChar){
case('>'):{
/* Ponemos ya a false la variable cierre. */
cierre = false;
/*Para ver cuando cambiar el modo PI*/
checkForPI();
/* Si después de esta función seguimos en modo PI es
* porque no era cierre, entonces hay que escribir el ">" en
* color celeste. Como en el método insertString ya ha sido
* insertado el elemento, lo sustituimos en color celeste. */
if(mode==PI_MODE){
insertPIString(str, this.currentPos);
}
break;
}
default:
insertPIString(str, this.currentPos);
}
}
else{
switch (strChar){
case('<'):case('/'):{
char[] chrstr = new char[1];
chrstr[0] = strChar;
insertOpenSign(new String(chrstr),currentPos);
break;
}
case (' '): case('\n'):case('>'):{
checkForKeyword();
- 24 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
if(strChar == '>'){
char[] chrstr = new char[1];
chrstr[0] = strChar;
insertCloseSign(new String(chrstr),currentPos);
}
if (mode == STRING_MODE && strChar == '\n'){
mode = TEXT_MODE;
}
break;
}
case ('-'):{
checkForComment();
break;
}
case ('?'):{
checkForPI();
break;
}
case ('"'):case('\''):{
insertTextString(str, currentPos);
checkForString();
break;
}
default:
break;
}
if (mode == TEXT_MODE){
checkForString();
}
if (mode == STRING_MODE){
insertTextString(str, this.currentPos);
}
}
}
/* ****************************************************** */
/* ************** FUNCIONES DE BÚSQUEDA ************* */
/* ****************************************************** */
/** Método que cuenta el número de comillas simples o dobles en la línea
- 25 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* en que nos encontramos y activa el modo String si es necesario.*/
public void checkForString(){
int offs = currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
/* Esta es la forma de obtener el texto que nos
* interesa (una línea) desde el elemento párrafo. */
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}catch(Exception ex){
System.err.println("no text");
}
int strLen = elementText.length();
if (strLen == 0)
return;
int i = 0;
if (element.getStartOffset() > 0){
/* Traducimos hacia atrás si es necesario: sólo comprobaremos
* de donde empieza el elemento hasta el punto de inserción.*/
offs = offs - element.getStartOffset();
}
int quoteCount = 0;
int aposCount = 0;
if ((offs >= 0) && (offs <= strLen-1)){
i = offs;
while (i >0){
/* El bucle chile camina hacia atrás hasta y mientras
* vamos contando las comillas simples y dobles. */
char charAt = elementText.charAt(i);
if ((charAt == '"')){
quoteCount ++;
}
if ((charAt == '\'')){
aposCount ++;
}
i--;
}
int rem = quoteCount % 2;
int rem2 = aposCount % 2;
mode = (rem == 0 && rem2==0)
? TEXT_MODE: STRING_MODE;
}
}
- 26 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/** Método que busca si hay palabras clave en la línea y
* la escribe en color azul en caso de encontrar alguna.*/
public void checkForKeyword(){
if (mode != TEXT_MODE) {
return;
}
int offs = currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
/* Esta es la forma de obtener el texto que nos
* interesa (una línea) desde el elemento párrafo. */
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}catch(Exception ex){
System.err.println("no text");
}
int strLen = elementText.length();
if (strLen == 0)
return;
int i = 0;
if (element.getStartOffset() > 0){
/* Traducimos hacia atrás si es necesario: sólo comprobaremos
* de donde empieza el elemento hasta el punto de inserción.*/
offs = offs - element.getStartOffset();
}
if ((offs >= 0) && (offs <= strLen-1)){
i = offs;
while (i >0){
/* El bucle chile camina hacia atrás hasta hasta que se
* encuentre un elemento de los que buscamos. */
i--;
char charAt = elementText.charAt(i);
if ((charAt==' ') | (i==0) | charAt=='<'|charAt==('/')){
if ((charAt==' ') | charAt=='<' | charAt==('/')){
/* Para no coger el caracter limite: i++. */
i++;
}
word = elementText.substring(i, offs);
String s = word.trim();
/* Aquí es donde realmente se compara con las
* palabras clave almacenadas en el vector. */
- 27 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
if (keywords.contains(s)){
palabra_clave = true;
insertKeyword(word, currentPos);
}
break;
}
}
}
}
/** Método que cambia a modo comentario o modo texto si es necesario, y
* sustituye cierto texto en color verde mediante insertCommentString(). */
public void checkForComment(){
int offs = currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
/* Esta es la forma de obtener el texto que nos
* interesa (una línea) desde el elemento párrafo. */
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}catch(Exception ex){
System.err.println("no text");
}
int strLen = elementText.length();
if (strLen == 0)
return;
int i = 0;
if (element.getStartOffset() > 0){
/* Traducimos hacia atrás si es necesario: sólo comprobaremos
* de donde empieza el elemento hasta el punto de inserción.*/
offs = offs - element.getStartOffset();
}
/* Offset mayor o igual que tres para no tener elementos
* negativos al tomar los elementos commentStartChar.*/
if ((offs >= 3) && (offs <= strLen-1)){
i = offs;
char commentStartChar1 = elementText.charAt(i-3);
char commentStartChar2 = elementText.charAt(i-2);
char commentStartChar3 = elementText.charAt(i-1);
char commentStartChar4 = elementText.charAt(i);
if (commentStartChar1 == '<' && commentStartChar2 == '!' &&
commentStartChar3 == '-' && commentStartChar4 == '-'){
- 28 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
mode = COMMENT_MODE;
insertCommentString("<!--", currentPos-3);
}
else if (commentStartChar2 == '-' && commentStartChar3 == '-'
&& commentStartChar4 == '>'){
mode = TEXT_MODE;
insertCommentString("-->", currentPos-2);
}
}
}
/** Método que cambia a modo PI o modo texto si es necesario, y
* sustituye cierto texto en color rojo mediante insertPIString(). */
public void checkForPI(){
int offs = currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
/* Esta es la forma de obtener el texto que nos
* interesa (una línea) desde el elemento párrafo. */
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}catch(Exception ex){
ex.printStackTrace();
}
int strLen = elementText.length();
if (strLen == 0)
return;
int i = 0;
if (element.getStartOffset() > 0){
/* Traducimos hacia atrás si es necesario: sólo comprobaremos
* de donde empieza el elemento hasta el punto de inserción.*/
offs = offs - element.getStartOffset();
}
/* Offset mayor o igual que uno para no tener elementos
* negativos al tomar los elementos PIStartChar.*/
if ((offs >= 1) && (offs <= strLen-1)){
i = offs;
char PIStartChar1 = elementText.charAt(i-1);
char PIStartChar2 = elementText.charAt(i);
if (PIStartChar1 == '<' && PIStartChar2 == '?'){
mode = PI_MODE;
- 29 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
this.insertPIString("<?", currentPos-1);
}
else if (PIStartChar1 == '?' && PIStartChar2 == '>'){
mode = TEXT_MODE;
this.insertPIString(">", currentPos);
}
}
}
/** Método que busca comentario. Se utiliza en el caso
* en que hayamos cambiado el cursor de posición.*/
public void buscar_comment(){
abre_comment = 0;
cierra_comment = 0;
int offs = currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}catch(Exception ex){
System.err.println("no text");
}
int strLen = elementText.length();
if (strLen == 0)
return;
int i = 0;
if (element.getStartOffset() > 0){
offs = offs - element.getStartOffset();
}
/*Offset mayor o igual que tres para no tener elementos negativos al
* almacenar los elementos commentStartChar.*/
if ((offs >= 3) && (offs <= strLen-1)){
i = offs;
while (i>=3){
char commentStartChar1 = elementText.charAt(i-3);
char commentStartChar2 = elementText.charAt(i-2);
char commentStartChar3 = elementText.charAt(i-1);
char commentStartChar4 = elementText.charAt(i);
if (commentStartChar1 == '<' && commentStartChar2
- 30 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
== '!' && commentStartChar3 == '-' &&
commentStartChar4 == '-'){
abre_comment ++;
}
else if (commentStartChar2 == '-' && commentStartChar3
== '-' && commentStartChar4 == '>'){
cierra_comment ++;
}
i--;
}
if(cierre){
/* Retomo el texto, para ver si el cierre pertenece a la
* etiqueta de cierre de un PI, a la de un comentario o
* forma parte de alguno del PI o el comentario. Para ello
* utilizaré dos variables, cierre_com y cierre_pi.*/
i = offs;
char c1 = elementText.charAt(i-2);
char c2 = elementText.charAt(i-1);
char c3 = elementText.charAt(i);
if (c1 == '-' && c2 == '-' && c3 == '>'){
cierre_com = true;
cierre_pi = false;
}
else if(c2 == '?' && c3 == '>'){
cierre_pi = true;
cierre_com = false;
}
else{
/* Caso en que el simbolo de cierre forma parte
* de la PI o del comentario, pero no cierra
* ninguno de esos elementos. */
cierre_com = false;
cierre_pi = false;
}
}
if ((abre_comment == cierra_comment) && !cierre)
mode = TEXT_MODE;
else{
/* En el caso de que sea cierre, pero no cierre de
* comentario, por ejemplo, insertar una etiqueta
* de cierre a un elemento que hubiésemos olvidado
* cerrar, no estaremos en modo comentario sino en
* modo texto para cerrar la etiqueta en rojo y
* añadir la etiqueta de cierre. (Ver buscar_PI(),
* que realiza una comprobación más concreta. */
if(cierre && !cierre_com)
mode = TEXT_MODE;
else
- 31 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
mode = COMMENT_MODE;
}
}
else
mode = TEXT_MODE;
}
/** Método que busca PIs. Se utiliza en el caso
* en que hayamos cambiado el cursor de posición.*/
public void buscar_PI(){
abre_PI = 0;
cierra_PI = 0;
int offs = currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}catch(Exception ex){
System.err.println("no text");
}
int strLen = elementText.length();
if (strLen == 0)
return;
int i = 0;
if (element.getStartOffset() > 0){
offs = offs - element.getStartOffset();
}
/* Offset mayor o igual que uno para no tener elementos
* negativos al almacenar los elementos PIStartChar.*/
if ((offs >= 1) && (offs <= strLen-1)){
i = offs;
while(i>=1){
char PIStartChar1 = elementText.charAt(i-1);
char PIStartChar2 = elementText.charAt(i);
if (PIStartChar1 == '<' && PIStartChar2 == '?'){
abre_PI++;
}
else if (PIStartChar1 == '?' && PIStartChar2 == '>'){
cierra_PI ++;
}
- 32 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
i--;
}
if ((abre_PI == cierra_PI) && !cierre)
mode = TEXT_MODE;
else{
if(cierre && !cierre_pi && !cierre_com){
/* Tenemos el elemento ">", pero no cierra
* ni un comentario ni un PI. Entonces:*/
if(abre_PI != cierra_PI)
/* Estamos dentro de un PI*/
mode = PI_MODE;
else if(abre_comment != cierra_comment)
/* ¡Estamos dentro de un comentario!*/
mode = COMMENT_MODE;
else
/* Lo insertaremos en rojo. */
mode = TEXT_MODE;
}
else if(cierre && !cierre_pi)
mode = TEXT_MODE;
else
mode = PI_MODE;
}
}
else
mode = TEXT_MODE;
}
/* ****************************************************** */
/* ************* FUNCIONES DE INSERCIÓN ************* */
/* ****************************************************** */
/** Método para insertar palabras clave en color azul. */
public void insertKeyword(String str, int pos){
try{
/* Eliminamos la palabra antigua y formateamos */
this.remove(pos - str.length(), str.length());
/* Reemplazamos con la misma palabra, pero con nuevo formato.
* Debemos llamar al método de la superclase insertString aqui,
* ¡de otro modo acabaríamos en un bucle infinito!*/
super.insertString(pos - str.length(), str, jep.etiqueta);
}
catch (Exception ex){
- 33 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
ex.printStackTrace();
}
}
/** Método para insertar texto entrecomillado en color rosa. */
public void insertTextString(String str, int pos){
try{
this.remove(pos,str.length());
super.insertString(pos, str, jep.valorAtributo);
}catch (Exception ex){
ex.printStackTrace();
}
}
/** Método para insertar comentarios en color verde. */
public void insertCommentString(String str, int pos){
try{
this.remove(pos,str.length());
super.insertString(pos, str, jep.comentario);
}catch (Exception ex){
ex.printStackTrace();
}
}
/** Método para insertar PIs en color rojo. */
public void insertPIString(String st, int pos){
try{
this.remove(pos,st.length());
super.insertString(pos, st, jep.declaracion_pi);
}catch (Exception ex){
ex.printStackTrace();
}
}
/** Método para insertar el símbolo de apertura de etiqueta en color rojo. */
public void insertOpenSign(String str, int pos){
try{
this.remove(pos,str.length());
- 34 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
super.insertString(pos, str, jep.apertura);
}catch (Exception ex){
ex.printStackTrace();
}
}
/** Método para insertar el símbolo de cierre de etiqueta en color rojo. */
public void insertCloseSign(String str, int pos){
try{
this.remove(pos,str.length());
super.insertString(pos, str, jep.apertura);
/* Si estoy insertando varios caracteres a la vez (paste),
* no quiero que, si se trata de una etiqueta correcta,
* se inserte el elemento de cierre de dicha etiqueta. */
if(!insertando_varios && palabra_clave){
etiqueta_cierre();
palabra_clave = false;
}
mode = TEXT_MODE;
}catch (Exception ex){
ex.printStackTrace();
}
}
/** Método para insertar la etiqueta de cierre
* para una etiqueta de apertura (si procede). */
public void etiqueta_cierre(){
/* Realizamos la búsqueda del texto que forma la etiqueta
* (obviando todos los atributos que pueda haber). */
String st = "";
int offs = this.currentPos;
Element element = this.getParagraphElement(offs);
String elementText = "";
try{
elementText = this.getText(element.getStartOffset(),
element.getEndOffset() - element.getStartOffset());
}catch(Exception ex){
ex.printStackTrace();
}
int strLen = elementText.length();
if (strLen == 0)
return;
- 35 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
int i = 0;
if (element.getStartOffset() > 0){
offs = offs - element.getStartOffset();
}
if ((offs >= 0) && (offs <= strLen-1)){
i = offs;
while (i >0){
i--;
char charAt = elementText.charAt(i);
if(charAt == '/')
break;
if(charAt == ' ')
/* Cuando encuentro un espacio, modifico la
* variable offs que es el punto máximo del
* elemento que tomaré en st para añadir
* dentro de la etiqueta de cierre */
offs = i;
if (charAt == '<'){
i++;
st = elementText.substring(i, offs);
try{
offs = this.currentPos+1;
String apert = "</";
String cierre = ">";
super.insertString(offs,apert, jep.apertura);
offs += apert.length();
super.insertString(offs, st, jep.etiqueta);
offs += st.length();
super.insertString(offs, cierre, jep.apertura);
}
catch (Exception ex){
ex.printStackTrace();
}
break;
}
}
}
}
/* ****************************************************** */
/* ***************** OTRAS FUNCIONES ***************** */
/* ****************************************************** */
/** Método que asigna el vector pasado como
* parámetro a la variable keywords. */
- 36 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
public void setKeywords(Vector aKeywordList){
if (aKeywordList != null){
this.keywords = aKeywordList;
}
}
}
- 37 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
EventHandler.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
/** Clase que escucha las acciones que el usuario realiza en la GUI.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class EventHandler implements ActionListener {
Inicial i;
/** Constructor de la clase. */
EventHandler(Inicial application) {
i = application;
}
/* Se ejecuta cuando se produce algún evento Action por las
* acciones del usuario. Hereda comentario de documentación. */
public void actionPerformed(ActionEvent e) {
/* Salir. */
if (e.getSource() == i.exitMenu) {
i.exit();
}
/* Abrir fichero (tanto en menú File como botón del toolbar). */
else if (e.getSource() == i.openMenu || e.getSource() == i.openButton) {
i.openFile(false, null);
}
/* Abrir fichero nuevo (tanto en menú File como botón del toolbar). */
else if (e.getSource() == i.newMenu || e.getSource() == i.newButton) {
i.newFile();
}
/* Salvar. */
else if (e.getSource() == i.saveMenu || e.getSource() == i.saveButton) {
- 38 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
i.saveFile();
}
/* Salvar Como. */
else if (e.getSource() == i.saveAsMenu) {
i.saveFileAs();
}
/* Cerrar un fichero. */
else if (e.getSource() == i.closeMenu || e.getSource() == i.closeP) {
i.closeFile();
}
/* Cerrar todos. */
else if (e.getSource() == i.closeAllMenu || e.getSource() == i.closeAllP){
i.closeAllFiles();
}
/* Cerrar todos menos éste. */
else if (e.getSource() == i.closeAllExceptMenu ||
e.getSource() == i.closeAllExceptP) {
i.closeAllExceptThis();
}
/* Refrescar. */
else if (e.getSource() == i.refreshTabMenu ||
e.getSource() == i.refreshButton) {
i.refresh();
}
/* Refrescar y Salvar. */
else if (e.getSource() == i.refreshAndSaveMenu) {
i.refreshAndSave();
}
/* Si queremos ver el about del editor. */
else if (e.getSource() == i.aboutEditorMenu) {
JOptionPane.showMessageDialog(i,
"
Lyon Editor 1.0\n" +
"Realizado por Pilar Jiménez Guijarro",
"About Lyon Editor",
JOptionPane.INFORMATION_MESSAGE);
}
/* Código añadido para "abrir reciente" */
else if (e.getSource() == i.jmi1) {
i.openRecentFile(i.jmi1.getText());
}
else if (e.getSource() == i.jmi2) {
i.openRecentFile(i.jmi2.getText());
- 39 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
}
else if (e.getSource() == i.jmi3) {
i.openRecentFile(i.jmi3.getText());
}
else if (e.getSource() == i.jmi4) {
i.openRecentFile(i.jmi4.getText());
}
/* Código añadido para la inserción de elementos. */
else if (e.getSource() == i.annotationMenu ||
e.getSource() == i.annotationButton) {
i.annotation();
}
else if (e.getSource() == i.attributeMenu ||
e.getSource() == i.attributeButton) {
i.attribute();
}
else if (e.getSource() == i.attributeGroupMenu ||
e.getSource() == i.attributeGroupButton) {
i.attributeGroup();
}
else if (e.getSource() == i.importMenu ||
e.getSource() == i.importButton) {
i.importar();
}
else if (e.getSource() == i.includeMenu ||
e.getSource() == i.includeButton) {
i.include();
}
}
}
- 40 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Import.java
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
/** Clase encargada de la creación de un cuadro de
* diálogo para la inserción de un elemento Import.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class Import extends JDialog {
JTextField jtf1;
JTextField jtf2;
JTextField jtf3;
boolean annotation;
boolean cancelado = false;
boolean cerrado = false;
/* Constructor de la clase. */
Import(){
setTitle("WIZARD: Import.");
setModal(true);
inicializar();
}
/** Método encargado de la creación de los elementos
* que forman el cuadro de diálogo. */
public void inicializar(){
- 41 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* Clase anonima para que la aplicacion se cierre al
* pulsar la X (boton esquina superior derecha). */
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
cerrado = true;
}
});
/* Creamos un JSplitPane, pues tendremos dos partes diferenciadas. */
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
sp.setPreferredSize(new Dimension(450,150));
/* Creamos los paneles y añadimos los elementos. */
JPanel pan1 =new JPanel();
JPanel pan2 =new JPanel();
GridLayout gl = new GridLayout(3,2);
pan1.setLayout(gl);
JLabel jl1 = new JLabel("id? : ");
JLabel jl2 = new JLabel("namespace? : ");
JLabel jl3 = new JLabel("schemaLocation? : ");
jtf1 = new JTextField();
jtf2 = new JTextField();
jtf3 = new JTextField();
pan1.add(jl1);
pan1.add(jtf1);
pan1.add(jl2);
pan1.add(jtf2);
pan1.add(jl3);
pan1.add(jtf3);
JCheckBox jcb = new JCheckBox("Add Annotation");
pan2.add(jcb);
/* Añadimos los paneles al JSplitPane. */
sp.setLeftComponent(pan1);
sp.setRightComponent(pan2);
sp.setDividerLocation(250);
/* Se crea el array de objetos con el texto
* introductorio y el splitPane anterior. */
JLabel intro = new JLabel("Fill in the following " +
"fields, please. ( ? = optional )");
Object[] array = {intro, sp};
/* Se crea el JOptionPane y se establece como
- 42 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
* contenido del cuadro de diálogo. */
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
Object[] options = {btnString1, btnString2};
JOptionPane jop = new JOptionPane(array, JOptionPane.
PLAIN_MESSAGE,JOptionPane.YES_NO_OPTION,
null, options, options[0]);
setContentPane(jop);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setSize(450, 200);
setLocation(525,375);
/* Listeners para eventos Action y PropertyChange. */
TextFieldAL tfal = new TextFieldAL(jop);
jtf1.addActionListener(tfal);
jtf2.addActionListener(tfal);
jtf3.addActionListener(tfal);
ImportPCL pcl = new ImportPCL(this, jop, jcb);
jop.addPropertyChangeListener(pcl);
}
}
- 43 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
ImportPCL.java
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
/** Clase que escucha cambios en las propiedades del cuadro
* de diálogo creado por la clase Import.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class ImportPCL implements PropertyChangeListener {
String id;
String namespace;
String schemaLoc;
Import d;
JOptionPane jop;
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
JCheckBox jcb;
/* Constructor de la clase. */
ImportPCL(Import dialogo, JOptionPane option, JCheckBox box){
d = dialogo;
jop = option;
jcb = box;
}
/* Se ejecuta si se produce un evento PropertyChange.
* Hereda comentario de documentación. */
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
if (d.isVisible() && (e.getSource() == jop) &&
(prop.equals(JOptionPane.VALUE_PROPERTY) ||prop.
equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
- 44 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Object value = jop.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
return;
}
if (value.equals(btnString1)) {
if(jcb.isSelected()){
d.annotation = true;
/* d.cancelado vale false ->
* realizaremos las acciones! */
}
d.setVisible(false);
}
else {
/*Si cancelamos, no hacemos nada*/
d.annotation = false;
d.cancelado = true;
d.setVisible(false);
}
}
}
}
- 45 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Include.java
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
/** Clase encargada de la creación de un cuadro de
* diálogo para la inserción de un elemento Include.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class Include extends JDialog {
JTextField jtf1;
JTextField jtf2;
boolean annotation;
boolean cancelado = false;
boolean cerrado = false;
/** Constructor de la clase. */
Include(){
setTitle("WIZARD: Include.");
setModal(true);
inicializar();
}
/** Método encargado de la creación de los elementos
* que forman el cuadro de diálogo. */
public void inicializar(){
- 46 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* Clase anonima para que la aplicacion se cierre al
* pulsar la X (boton esquina superior derecha). */
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
cerrado = true;
}
});
/* Creamos un JSplitPane, pues tendremos dos partes diferenciadas. */
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
sp.setPreferredSize(new Dimension(450,150));
/* Creamos los paneles y añadimos los elementos. */
JPanel pan1 =new JPanel();
JPanel pan2 =new JPanel();
GridLayout gl = new GridLayout(2,2);
pan1.setLayout(gl);
JLabel jl1 = new JLabel("id? : ");
JLabel jl2 = new JLabel("schemaLocation : ");
jtf1 = new JTextField();
jtf2 = new JTextField();
pan1.add(jl1);
pan1.add(jtf1);
pan1.add(jl2);
pan1.add(jtf2);
JCheckBox jcb = new JCheckBox("Add Annotation");
pan2.add(jcb);
/* Añadimos los paneles al JSplitPane. */
sp.setLeftComponent(pan1);
sp.setRightComponent(pan2);
sp.setDividerLocation(250);
/* Se crea el array de objetos con el texto
* introductorio y el splitPane anterior. */
JLabel intro = new JLabel("Fill in the following" +
" fields, please. ( ? = optional )");
Object[] array = {intro, sp};
/* Se crea el JOptionPane y se establece como
* contenido del cuadro de diálogo. */
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
Object[] options = {btnString1, btnString2};
- 47 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
JOptionPane jop = new JOptionPane(array, JOptionPane.
PLAIN_MESSAGE,JOptionPane.YES_NO_OPTION,
null, options, options[0]);
setContentPane(jop);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
pack();
setSize(450, 150);
setLocation(525,375);
/* Listeners para eventos Action y PropertyChange. */
TextFieldAL tfal = new TextFieldAL(jop);
jtf1.addActionListener(tfal);
jtf2.addActionListener(tfal);
IncludePCL pcl = new IncludePCL(this, jop, jcb, jtf2);
jop.addPropertyChangeListener(pcl);
}
}
- 48 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
IncludePCL.java
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JCheckBox;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
/** Clase que escucha cambios en las propiedades del cuadro
* de diálogo creado por la clase Include.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class IncludePCL implements PropertyChangeListener {
String id;
String schemaLoc;
Include d;
JOptionPane jop;
JTextField jtf;
String text;
final String btnString1 = "Enter";
final String btnString2 = "Cancel";
JCheckBox jcb;
/** Constructor de la clase. */
IncludePCL(Include dialogo, JOptionPane option,
JCheckBox box, JTextField jtf_schema){
d = dialogo;
jop = option;
jcb = box;
jtf = jtf_schema;
}
/* Se ejecuta si se produce un evento PropertyChange.
* Hereda comentario de documentación. */
public void propertyChange(PropertyChangeEvent e) {
String prop = e.getPropertyName();
- 49 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
if (d.isVisible() && (e.getSource() == jop) &&
(prop.equals(JOptionPane.VALUE_PROPERTY) ||prop.
equals(JOptionPane.INPUT_VALUE_PROPERTY))) {
Object value = jop.getValue();
if (value == JOptionPane.UNINITIALIZED_VALUE) {
return;
}
if (value.equals(btnString1)) {
/* Sólo compruebo el texto de schemaLocation. */
text = jtf.getText();
/* En este caso, si el campo de texto correspondiente al
* schemaLocation está vacío, mostraremos un diálogo de
* error ya que es un campo obligatorio. */
if (!text.equals("")) {
if(jcb.isSelected()){
d.annotation = true;
/* d.cancelado vale false ->
* realizaremos las acciones! */
}
d.setVisible(false);
}
else {
/* Falta el elemento de texto de schemaLocation*/
JOptionPane.showMessageDialog(d," The field " +
"schemaLocation is REQUIRED. \n " +
"Fill in at least this field, please.",
"ERROR",
JOptionPane.ERROR_MESSAGE);
jop.setValue(JOptionPane.
UNINITIALIZED_VALUE);
}
}
else {
/*Si cancelamos, no hacemos nada*/
d.annotation = false;
d.cancelado = true;
d.setVisible(false);
}
}
}
}
- 50 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Inicial.java
import javax.swing.Action;
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.undo.UndoManager;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Hashtable;
- 51 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/** Clase que inicializa la GUI, y se encarga de la realización de
* acciones de apertura, cierre, salvaguarda, etc. de ficheros.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class Inicial extends JFrame{
static Inicial application;
/* Diálogo de elección de archivos y Barra de Menu.*/
JFileChooser fileChooser = null;
JMenuBar menuBar;
/* Menus e Items de Menus para el Menu Inicial.*/
JMenu fileMenu;
JMenu aboutMenu;
JMenuItem newMenu;
JMenuItem openMenu;
JMenu openRecentMenu;
JMenuItem exitMenu;
JMenuItem aboutEditorMenu;
/* Menu e items para completar el menu inicial. ¡¡¡ATENCIÓN!!! No se
* inicializan aqui; aqui se definen para poderlos usar a lo largo de
* todo el programa.*/
JMenuItem closeMenu;
JMenuItem closeAllMenu;
JMenuItem closeAllExceptMenu;
JMenuItem saveMenu;
JMenuItem saveAsMenu;
/* Lo mismo que lo anterior, pero para refresh.*/
JMenu refreshMenu;
JMenuItem refreshTabMenu;
JMenuItem refreshAndSaveMenu;
JButton refreshButton;
/* Similar pero para Insert. */
JMenu insertMenu;
JMenuItem annotationMenu;
JMenuItem attributeMenu;
JMenuItem attributeGroupMenu;
JMenuItem complexTypeMenu;
JMenuItem elementMenu;
JMenuItem groupMenu;
JMenuItem importMenu;
JMenuItem includeMenu;
JMenuItem notationMenu;
JMenuItem redefineMenu;
- 52 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
JMenuItem simpleTypeMenu;
/* Menú Edit. */
JMenu editMenu;
/* Parte correspondiente al ToolBar. */
JToolBar toolBar;
JButton newButton;
JButton openButton;
JButton saveButton;
JButton cutButton;
JButton pasteButton;
JButton copyButton;
/* El jep está inicializado aqui para poder utilizar las actions del
* DefaultEditotKit. Si no estaba asi, daba problemas de null pointer
* exception. Asi se puede usar createActionTable sin problemas.*/
MyJEditorPane jep = new MyJEditorPane(null, false);
JScrollPane jsp;
JScrollPane tree_jsp;
/* Variable que almacena el número de pestañas abiertas. */
int count = 0;
/* Variable que indica si el menú está actualizado, es decir,completo.*/
boolean actualizado = false;
/* Variable global que se utiliza para salir o no del programa en caso
* de que se cancele la operación de salida y para anular la opción de
* cierre de múltiples pestañas en caso de Cancelación por parte del
* usuario (closeAll y closeAllExcept). */
boolean cancelado;
String fileName;
String absoluteName;
/* Elementos para dar al programa su forma(pestañas, splitPanes...)*/
JSplitPane split;
JSplitPane split2;
JPanel bp;
JTabbedPane pestana;
/* Elementos para el PopupMenu. */
JPopupMenu p;
MouseListener popupListener;
JMenuItem closeP;
JMenuItem closeAllP;
JMenuItem closeAllExceptP;
/* Cuenta el número de pestañas nuevas desde que se lanzó la aplicación.
* Se añade a "Untitled" para dar título a los archivos nuevos. */
- 53 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
int count_pest = 1;
/* Almacena la posición de la pestaña con respecto a las abiertas.*/
int tab_index = 0;
/*Para exit() y closeFile()*/
boolean salir = false;
/* Para implementar deshacer y rehacer. */
UndoAction undoAction;
RedoAction redoAction;
UndoManager undo = new UndoManager();
/* Para obtener acciones ya implementadas en Java. */
Hashtable actions;
/* Apuntará a una instancia de la clase CodeDocument.*/
Document doc;
/* Constante que indica el número de elementos que habrá en el menú
* de apertura de archivos recientes, en este caso cuatro. A continuación
* otros elementos para trabajar con este menú. */
final int SIZE = 4;
String recentFile[] = new String [SIZE];
int cuenta_recent = 0;
JMenuItem jmi1;
JMenuItem jmi2;
JMenuItem jmi3;
JMenuItem jmi4;
/* Variables para TabListener*/
boolean nuevo = false;
boolean abriendo = false;
boolean cerrando = false;
/* Variables para tratar el menu de archivos abiertos recientemente.*/
BufferedReader bf;
BufferedWriter bw;
String linea;
StringBuffer sb;
/* Botones para el Toolbar, correspondientes al menú Insert. */
JButton annotationButton;
JButton attributeButton;
JButton attributeGroupButton ;
JButton complexTypeButton;
JButton elementButton;
JButton groupButton;
JButton importButton;
JButton includeButton;
- 54 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
JButton notationButton;
JButton redefineButton;
JButton simpleTypeButton;
/* Listener para los eventos Action que se producan en nuetro programa.
* Es un ejemplar de la clase EventHandler. */
ActionListener eventHandler = new EventHandler(this);
/* ****************************************************** */
/* ****************** CONSTRUCTOR ******************* */
/* ****************************************************** */
/** Constructor de la clase.
* @param s Nombre que se dará al marco de la aplicación. */
public Inicial (String s){
super (s);
/* Para que no se cierre cuando cancelamos, razón teórica explicada
* en la memoria, en la función exit. */
this.setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
}
/* ****************************************************** */
/* ***** ARRANQUE/INICIALIZACIÓN DEL PROGRAMA **** */
/* ****************************************************** */
/** Método main de la aplicación. */
public static void main(String[] args) {
application = new Inicial ("Lyon Editor");
application.initialize();
application.initConnections();
application.pack();
application.setSize(1400, 1020);
application.setLocation(0, 0);
application.setVisible(true);
}
- 55 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/** Método que añade los ActionListeners de los menús que
* aparecen en el estado inicial de la aplicación.*/
public void initConnections(){
newMenu.addActionListener(eventHandler);
openMenu.addActionListener(eventHandler);
exitMenu.addActionListener(eventHandler);
aboutEditorMenu.addActionListener(eventHandler);
/* Aqui ya no se inicializan save, saveAs, close...etc. RAZÓN:
* Recordar el fallo: cada vez que se cerraban todas las pestañas y
* se llegaba al "estado inicial",surgían problemas con save, saveAs,
* close, closeAll y closeAllExcept.La razón era que por ejemplo, si
* era la segunda vez que habíamos vuelto al estado inicial, al
* utilizar después alguno de éstos, lo que se hacía es llamar tres
* veces a la función correspondiente. Esto es porque las variables
* las inicializabamos en las primeras lineas de código, es decir, en
* las declaraciones y además, cada vez que se reseteaba, se llama a
* este metodo--initConections, y se "añadía" por decirlo de alguna
* manera, un nuevo manejador de eventos al item. Es decir, cada vez
* que reseteabamos, estas funciones anteriormente nombradas se
* realizarían una vez más cada una de ellas. Con el código actual,
* el problema queda solucionado, ya que cada vez que se llama a
* actualizarMenu() se crean nuevos menuItem, se le añade el manejador
* y estos son los que se añaden al menu. Por tanto, no irán
* "acumulando" manejadores y realizarán su función una única vez que
* es lo que queremos.*/
}
/** Método que realiza una serie de acciones para inicializar ciertos
* elementos necesarios para el buen funcionamiento del programa. */
public void initialize(){
/* Define que el Layout del contenedor sea de tipo BorderLayout.
* Lo especificamos, pero no sería necesario ya que BorderLayout
* es el controlador de distribución por defecto para Frames. */
this.getContentPane().setLayout(new BorderLayout());
/* Clase anonima para que la aplicacion se cierre al apretar la X
* (boton esquina superior derecha), pero realizando antes lo que
* especificamos en la función exit().*/
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
exit();
}
- 56 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
});
/* Creación del menú correspondiente al Estado Inicial. */
crearMenuInicial();
/* Asignación del JTabbedPAne al Contenedor de la clase. Si hay
* demasiadas pestañas no crearán distintas filas. sino que tendremos
* un scroll (SCROLL_TAB_LAYOUT). */
Container c = getContentPane();
pestana = new JTabbedPane();
c.add(pestana);
pestana.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
TabListener tl = new TabListener(this);
pestana.addChangeListener(tl);
/* Elección del Look and Feel.*/
try {
UIManager.setLookAndFeel(
"com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
}catch (Exception e) {
System.err.println("Could not load LookAndFeel");
}
/* Creación de Open Recent File a partir de archivo de configuración.
* Hay que leer el fichero en la etapa de inicialización del programa,
* ya que debemos poner los archivos que abrimos anteriormente (en las
* últimas utilizaciones del programa) en los distintos menús. */
crearRecentMenu();
}
/* ****************************************************** */
/* ********** FUNCIONALIDADES DEL MENÚ FILE ******** */
/* ****************************************************** */
/** Método que abre un nuevo fichero en una pestaña. */
public void newFile(){
/* Diálogo inicial que muestra las distintas opciones de Esquemas
* que permite realizar el editor. En este proyecto sólo se ha
* implementado XML Schema. El resto quedan como lineas futuras.*/
Object[] possibleValues = { "XML Schema",
"RELAX-NG", "Schematron"};
String selectedValue = (String)JOptionPane.showInputDialog(
- 57 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
application, "Choose a template", "New File",
JOptionPane.INFORMATION_MESSAGE, null,
possibleValues,
possibleValues[0]);
/* Si pulsamos "cancelar" el valor obtenido será null. */
if (selectedValue != null){
if (selectedValue.equals("RELAX-NG") ||
selectedValue.equals("Schematron")){
/*Caso de los esquemas que quedan como lineas futuras:*/
JOptionPane.showMessageDialog(application,
" ---- Schema Under Construction! ---\n The " +
"implementation of this Schema is not ready.",
"Under Construction", JOptionPane.
INFORMATION_MESSAGE);
}
else{
setCursor(Cursor.getPredefinedCursor(
Cursor.WAIT_CURSOR));
if (!actualizado){
this.actualizarMenu();
actualizado = true;
}
/* Variable para TabListener*/
nuevo = true;
fileName = "Untitled"+count_pest;
jep = new MyJEditorPane(null, true);
jep.setFileName(fileName);
jep.leerNuevo();
/* Añadido para trabajar directamente con el Redo
* y Undo que corresponden al crear una pestaña. */
this.setUndoableMenu(jep);
/* En este punto comienza la definición de los
* JScrollPanes,JSplitPanes y MyJEditorPane que
* necesito para crear un nuevo documento. */
jsp = new JScrollPane(jep);
jsp.setVerticalScrollBarPolicy(JScrollPane.
VERTICAL_SCROLLBAR_ALWAYS);
jsp.setHorizontalScrollBarPolicy(JScrollPane.
HORIZONTAL_SCROLLBAR_ALWAYS);
split = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT);
- 58 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
split.setLeftComponent(jsp);
tree_jsp = new JScrollPane(jep.arbol);
tree_jsp.setVerticalScrollBarPolicy(JScrollPane.
VERTICAL_SCROLLBAR_ALWAYS);
tree_jsp.setHorizontalScrollBarPolicy(JScrollPane.
HORIZONTAL_SCROLLBAR_ALWAYS);
split.setRightComponent(tree_jsp);
split.setOneTouchExpandable(true);
split.setDividerLocation(1050);
split.setDividerSize(10);
pestana.addTab(fileName, split);
tab_index = pestana.indexOfTab(fileName);
pestana.setSelectedIndex(tab_index);
/* Esta última linea asegura que el programa nos
* muestre la pestaña que acabamos de añadir. */
/* Para poder ver el Caret (o cursor), situado en la posicion
* inicial del texto, se utilizan las siguientes líneas. */
jep.initCaret();
jep.requestFocus();
count_pest++;
count++;
doc = jep.getDocument();
doc.addDocumentListener(new
MyDocumentListener(this));
doc.addUndoableEditListener(new
MyUndoableEditListener(this));
nuevo = false;
setCursor(Cursor.getPredefinedCursor(
Cursor.DEFAULT_CURSOR));
}
}
}
/** Método que abre un esquema ya existente desde un fichero.
* @param recent Indica si estamos abriendo un archivo reciente
* mediante el menú Open Recent File.
* @param recentName Nombre del archivo reciente. */
public void openFile(boolean recent, String recentName){
- 59 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
int retVal;
File file;
/* Si vemos que venimos de "Abrir Archivo Reciente" no debe
* abrirse el diálogo de elección de fichero(JFileChooser).*/
if(!recent){
/* Si aún no existe el file chooser, crea uno */
if (fileChooser == null){
fileChooser = new JFileChooser();
}
retVal = fileChooser.showOpenDialog(this);
}
else
retVal = JFileChooser.APPROVE_OPTION;
/* Si se escogio Ok, (o abrir): */
if (retVal == JFileChooser.APPROVE_OPTION){
setCursor(Cursor.getPredefinedCursor(
Cursor.WAIT_CURSOR));
if (!actualizado){
this.actualizarMenu();
actualizado = true;
}
/* Variable para TabListener*/
abriendo = true;
/* A la hora de asignar la variable file, se diferencia si se
* viene de Abrir Archivo Reciente o de Abrir.*/
if(!recent)
file = fileChooser.getSelectedFile();
else
file = new File(recentName);
/* OpenFile()realizada de modo que si el archivo ya está abierto
* en una pestaña, no se vuelva a abrir. El código que sigue es
* el que hace estas comprobaciones. */
/* Hacemos aqui estas asignaciones para poder comparar*/
absoluteName = file.getAbsolutePath();
fileName = file.getName();
int tabcount;
int a;
boolean ya_abierto = false;
String fich_abrir;
tabcount = pestana.getTabCount();
- 60 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
for (a=0; a < tabcount; a++){
/* Debido a la estructura de JScrollPanes, JSplitPanes y
* demás componentes que tenemos, la forma de acceder
* al MyJEditorPane es la siguiente: */
split = (JSplitPane) pestana.getComponentAt(a);
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).
getComponentAt(0, 0);
fich_abrir = jep.getFileName();
if (fich_abrir.equals(fileName)){
/* Break: si encontramos la pestaña ya abierta,
* no es necesario seguir el bucle. */
ya_abierto = true;
break;
}
}
/* Sólo abriré el archivo si no esta ya abierto. */
if(!ya_abierto){
jep = new MyJEditorPane(file, false);
jep.leer();
/* Añadido para trabajar directamente con el Redo
* y Undo que corresponden al crear una pestaña. */
this.setUndoableMenu(jep);
jsp = new JScrollPane(jep);
jsp.setVerticalScrollBarPolicy(JScrollPane.
VERTICAL_SCROLLBAR_ALWAYS);
jsp.setHorizontalScrollBarPolicy(JScrollPane.
HORIZONTAL_SCROLLBAR_ALWAYS);
split = new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT);
split.setLeftComponent(jsp);
tree_jsp = new JScrollPane(jep.arbol);
tree_jsp.setVerticalScrollBarPolicy(JScrollPane.
VERTICAL_SCROLLBAR_ALWAYS);
tree_jsp.setHorizontalScrollBarPolicy(JScrollPane.
HORIZONTAL_SCROLLBAR_ALWAYS);
split.setRightComponent(tree_jsp);
split.setOneTouchExpandable(true);
split.setDividerLocation(1050);
split.setDividerSize(10);
pestana.addTab(fileName, split);
- 61 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
tab_index = pestana.indexOfTab(fileName);
pestana.setSelectedIndex(tab_index);
jep.initCaret();
jep.requestFocus();
count++;
doc = jep.getDocument();
doc.addDocumentListener(new
MyDocumentListener(this));
doc.addUndoableEditListener(new
MyUndoableEditListener(this));
abriendo = false;
/* Este try es el que se encarga de actualizar el menu
* de archivos abiertos recientemente. */
try{
/* Es necesario usar el StringBuffer para no perder
* el contenido del fichero al escribir. */
int num_lineas = 1;
boolean repetido = false;
boolean add = false;
sb = new StringBuffer();
sb.append(absoluteName);
sb.append("\n");
bf = new BufferedReader(new
FileReader("./config.txt"));
while((linea = bf.readLine()) != null){
if(num_lineas < SIZE){
if(!linea.equals(absoluteName)){
sb.append(linea);
sb.append("\n");
}
else{
repetido = true;
add = true;
}
}
if(!repetido){
num_lineas ++;
}
else{
repetido = false;
}
- 62 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* Explicacion if-else --->en caso de que el fichero
* config tenga 4 lineas, y abro un fichero
* correspondiente a alguno de esos 4 que están en
* el fichero config,necesito llegar a num_lineas=5
* pero también necesito que en el fichero queden
* las 4 lineas (aunque cambiadas de orden).La
* variable repetido sirve para poder leer todas las
* lineas (4) del fichero de configuracion(cuando
* detecta que se abre un fichero de la lista reciente,
* se pone a true y no se aumenta num_lineas. Esto
* permite que la condicion if(num_lineas < SIZE)
* se cumpla hasta haber leido todas las lineas del
* fichero de configuracion que es lo que interesa.
* La variable add permite añadir una unidad a
* num_lineas, ya que en el supuesto anterior,
* necesitamos como dijimos, num_lineas=5 para
* eliminar los 4 items de menu que habría
* anteriormente. */
}
if(add)
num_lineas++;
linea = sb.toString();
/* Actualizo el fichero de configuración de
* archivos abiertos recientemente. */
bw = new BufferedWriter (new
FileWriter("./config.txt"));
bw.write(linea, 0, linea.length());
bw.close();
actualizarRecentMenu(num_lineas);
}catch (Exception e){
e.printStackTrace();
}
}
else{
/* En el caso que ya estuviese abierto el fichero, queremos
* que su pestaña vuelva a ser "marcada" o "elegida" */
pestana.setSelectedIndex(a);
}
setCursor(Cursor.getPredefinedCursor(
Cursor.DEFAULT_CURSOR));
}
}
- 63 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/** Método llamado al elegir alguno de los Items de Menú del
* menú Open Recent File.
* @param absName Ruta absoluta del archivo a abrir. */
public void openRecentFile(String absName){
openFile(true, absName);
}
/** Método que cierra una pestaña y guarda los cambios realizados
* al documento si fuese necesario. */
public void closeFile(){
/* Para la pestaña que estamos tratando, hay que ver las distintas
* posibilidades: si no está salvada, debemos preguntar antes de
* cerrar. Si cancela, no hacemos nada. Si elige salvar, guardamos
* y cerramos. Si elige no guardar, no guardamos y cerramos. */
int index;
boolean cancel = false;
index =pestana.getSelectedIndex();
split = (JSplitPane) pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).getComponentAt(0, 0);
if (!jep.getIsSaved()){
cancel = askSave();
}
if(!cancel){
/* Variable para TabListener. */
cerrando = true;
pestana.remove(index);
/* Disminuimos count, que contiene el número de pestañas
* abiertas. Esta variable sirve para ver si tenemos que
* volver al Estado Inicial de la aplicación (caso en que
* no queden pestañas abiertas). */
count--;
/* En este if se añade la condicion de salir para que en el caso
* de estar saliendo del programa no toquemos el menu (puesto
* que vamos a cerrar el programa no es necesario modificarlo),
* sino que salgamos directamente. */
if (count == 0 && !salir){
resetearMenu();
- 64 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* Para eliminar el popup menu y q no
* aparezca en el Estado Inicial. */
pestana.removeMouseListener(popupListener);
crearMenuInicial();
crearRecentMenu();
this.initConnections();
actualizado = false;
}
cerrando = false;
}
cancelado = cancel;
}
/** Método que cierra todas las pestañas abiertas. */
public void closeAllFiles(){
/* Numero de pestañas abiertas -> almacenado en la variable count. */
int i;
int j = count;
for (i = 0; i < j; i++){
closeFile();
if(cancelado)
break;
}
}
/** Método que cierra todas las pestañas abiertas salvo la
* que está seleccionada cuando la función es invocada.*/
public void closeAllExceptThis(){
int i;
int j = count -1;
int k=0;
int index;
index =pestana.getSelectedIndex();
if (index != 0){
for (i = 0; i < j; i++){
pestana.setSelectedIndex(k);
closeFile();
if(cancelado)
break;
- 65 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* Elegimos la pestaña de indice cero (la "primera" = la
* de más a la izquierda). Cuando estemos en la anterior
* a la que no queremos cerrar, i =index-1. En ese
* instante, aumentamos k para que, al volver a utilizar
* setSelectedIndex,no cojamos la de la índice cero que
* es la que queremos cerrar, sino la siguiente. */
if(i==(index-1))
k++;
}
}
else{
/* En el caso de que la que no queramos cerrar sea la primera,
* directamente iremos eligiendo la segunda pestaña todo el
* tiempo, por eso ponemos k=1. */
k=1;
for (i = 0; i < j; i++){
pestana.setSelectedIndex(k);
closeFile();
if (cancelado)
break;
}
}
}
/** Método que muestra al usuario un diálogo advirtiéndole que el
* fichero ha sido modificado y preguntándole si desea salvar. */
public boolean askSave(){
/* Booleano que será verdadero cuando elijamos la opción cancelar */
boolean cancel_option = false;
/* Componente que muestra ventanas de opciones */
/* Dialogo de confirmación: SI-NO-CANCELAR. */
int ret=JOptionPane.showConfirmDialog(this,
"This file has been modified. Save changes?",
"Save Resource",
JOptionPane.YES_NO_CANCEL_OPTION,
JOptionPane.QUESTION_MESSAGE);
if(ret==JOptionPane.YES_OPTION)
saveFile();
if(ret==JOptionPane.CANCEL_OPTION)
cancel_option = true;
return cancel_option;
}
- 66 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/** Método que salva los datos de un esquema en un fichero. */
public void saveFile(){
int index;
boolean cancelled = false;
/* cancelled es válido también para el caso en que
* el nombre elegido para salvar ya existe. */
/* Conseguimos el componente MyJEditorPane asociado a la pestaña
* seleccionada para así poder utilizar su variable isSaved. */
/* Esta primera línea elige el componente que está dentro de
* la pestaña seleccionada del JTabbedPane, que será, tal y
* como explicamos en newFile() y openFile(), un JSplitPane.*/
split = (JSplitPane)pestana.getSelectedComponent();
/* Una vez obtenido el JSplitPane, selecciono el componente
* que situé a la izquierda, que será un JScrollPane.*/
jsp = (JScrollPane)split.getLeftComponent();
/* Por último, y esto es lo más complicado, cómo obtener el jep.
* Haciendo pruebas (utilizando las funciones getComponentAt(),
* getComponent(),etc.), se puede ver que el elemento jsp no
* contiene más que 3 elementos dentro de él: en la posición 0 hay
* un JViewPort y en la 1 y la 2 hay JScrollBars. ¿Dónde está pues
* el MyJEditorPane?. El componente JViewport tiene lo que se
* denomina un cliente. Un JViewPort maneja el área visible de
* su cliente, y en este caso el cliente es el MyJEditorPane.
* Por eso, elegimos el Componente situado en la posición (0,0)
* del JViewPort. Elegimos esta posición porque sabemos que esa en
* esquina (superior izquierda) siempre habrá algo, por pequeño que
* sea el cliente del JViewport (este "algo" es el cliente que, como
* hemos dicho, es el componente MyJEditorPane que buscábamos.) y
* porque es el único punto cuyas coordenadas sabemos con certeza.
* Es más,no sabemos las coordenadas del resto de puntos del
* JViewport, y además pueden cambiar si modificamos el tamaño
* de la aplicación. */
jep = (MyJEditorPane)jsp.getComponent(0).getComponentAt(0, 0);
if (!jep.getIsSaved()){
/* Utiliza un file chooser para explorar dónde guardarlo. Si no
* existe, crea uno. Sólo mostramos el diálogo si el archivo es
* nuevo, y no ha sido aún salvado. */
if (jep.getIsNew()){
- 67 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
if (fileChooser == null){
fileChooser = new JFileChooser();
}
int retVal = fileChooser.showSaveDialog(this);
if (retVal == JFileChooser.APPROVE_OPTION){
File comprueba_file =
fileChooser.getSelectedFile();
/* Comprobamos si el fichero existe para no
* sobreescribirlo sin permiso del usuario. */
if (comprueba_file.exists()){
int comprobacion =JOptionPane.
showConfirmDialog(application,
" This file already exists." +
" Do you wish to overwrite this" +
" file?.","Overwrite File?",
JOptionPane.
OK_CANCEL_OPTION);
if (comprobacion ==
JOptionPane.CANCEL_OPTION){
cancelled = true;
}
}
if(!cancelled){
absoluteName = fileChooser.
getSelectedFile().getAbsolutePath();
fileName = fileChooser.getSelectedFile().
getName();
/* Ponemos el nombre que hemos dado al
* archivo a la pestaña que lo contiene.*/
index =pestana.getSelectedIndex();
pestana.setTitleAt(index,fileName);
File f = new File(absoluteName);
jep.setFile(f);
jep.setIsNew(false);
}
}
else
cancelled = true;
}
else{
absoluteName = jep.getAbsoluteName();
fileName = jep.getFileName();
}
- 68 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* La variable cancelled sirve para evitar ejecutar el código
* del try. Es necesario escribir si el archivo es nuevo pero
* si no ha sido cancelado. Ponemos cancelled a true cuando
* hemos cancelado para no escribir, y evitar asi la excepción
* que se produciria (NullPointerException) al crear un
* FileWriter con un absoluteName que no se ha inicializado.
* Esta variable no se necesita en la función SaveFileAs().*/
if (!cancelled){
try{
/* Tomar el texto que hay en el panel de texto. En
* las fases iniciales del proyecto, se utilizaba
* lo siguiente: String text=jep.getText(); Esto
* era válido para DOCUMENTOS SIN ESTILO.
* Introducir el tratamiento de texto con estilo
* en MyJEditorPane suponía que ese getText() nos
* devolviese un string=null pues la función
* getText() de JEditorPane NO RECONOCÍA
* EL TEXTO CON ESTILO.
* La solución adoptada ha sido utilizar el mismo
* método pero de la interfaz Document que por
* lógica debía obtener el texto, aunque no fuese
* plano, ya que esta interfaz tiene la propiedad
* de poder tratar con texto con estilo. Para poder
* acceder a ella se utiliza getDocument()*/
Document d = jep.getDocument();
String text=d.getText(0,d.getLength());
java.io.FileWriter fileWriter = new
java.io.FileWriter(absoluteName);
java.io.BufferedWriter br = new
java.io.BufferedWriter(fileWriter);
br.write(text);
br.close();
/* Como hemos salvado, isSaved debe ser true */
jep.setIsSaved(true);
/* Para quitar el asterisco que habría en caso de
* que el archivo hubiese sido modificado. */
index = pestana.getSelectedIndex();
pestana.setTitleAt(index, fileName);
}catch (Exception ioe){
System.err.println(ioe.getMessage());
ioe.printStackTrace();
}
}
}
}
- 69 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/** Método que salva un fichero con un nombre y ubicación
* determinados, proporcionados por el usuario. */
public void saveFileAs(){
int index;
boolean overwrite = true;
split = (JSplitPane)pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).getComponentAt(0, 0);
if (fileChooser == null){
fileChooser = new JFileChooser();
}
/* En esta función no es necesaria la variable cancelled ya que,
* sea o no nuevo el archivo, mostraremos el cuadro de diálogo y
* obtendremos de ahí los valores fileName y absoluteName. En
* caso de cancelar, directamente saldremos de la función.
* Para no sobreescribir archivos se utiliza overwrite. */
int retVal = fileChooser.showSaveDialog(this);
if (retVal == JFileChooser.APPROVE_OPTION){
File comprueba_file = fileChooser.getSelectedFile();
/* Comprobamos si el fichero existe para no
* sobreescribirlo sin permiso del usuario. */
if (comprueba_file.exists()){
int comprobacion =JOptionPane.
showConfirmDialog(application,
" This file already exists." +
" Do you wish to overwrite this file?.",
"Overwrite File?", JOptionPane.
OK_CANCEL_OPTION);
if (comprobacion == JOptionPane.CANCEL_OPTION){
overwrite = false;
}
}
if(overwrite){
absoluteName = fileChooser.getSelectedFile().
getAbsolutePath();
fileName = fileChooser.getSelectedFile().
getName();
index =pestana.getSelectedIndex();
- 70 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
pestana.setTitleAt(index,fileName);
File f = new File(absoluteName);
jep.setFile(f);
jep.setIsNew(false);
try{
/* Misma explicación que en saveFile() */
Document d = jep.getDocument();
String text=d.getText(0,d.getLength());
java.io.FileWriter fileWriter = new
java.io.FileWriter(absoluteName);
java.io.BufferedWriter br = new
java.io.BufferedWriter(fileWriter);
br.write(text);
br.close();
jep.setIsSaved(true);
index = pestana.getSelectedIndex();
pestana.setTitleAt(index, fileName);
}catch (Exception ioe){
System.err.println(ioe.getMessage());
ioe.printStackTrace();
}
}
}
}
/** Método que realiza las acciones y comprobaciones necesarias antes
* de salir de la aplicación y sale si no se ha cancelado la salida.*/
public void exit(){
int i;
int j = count;
int k = 0;
salir = true;
for (i=0; i<j; i++){
pestana.setSelectedIndex(k);
closeFile();
if (cancelado){
salir = false;
/* Para salir del bucle cuando hemos cancelado.
* En este caso no saldremos del programa.*/
break;
}
- 71 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
}
if (salir)
System.exit(0);
}
/* ****************************************************** */
/* ************** TRATAMIENTO DE MENÚS ************** */
/* ****************************************************** */
/** Método que crea los elementos de menú que conforman el Estado
* Inicial de la aplicación. Estos menús son File (pero sólo los
* elementos new, open, openRecent y Exit) y About. */
public void crearMenuInicial(){
menuBar = new JMenuBar();
fileMenu = new JMenu("File");
newMenu = new JMenuItem("New");
openMenu = new JMenuItem("Open");
openRecentMenu = new JMenu("Open Recent File");
exitMenu = new JMenuItem("Exit");
fileMenu.add(newMenu);
fileMenu.addSeparator();
fileMenu.add(openMenu);
fileMenu.add(openRecentMenu);
fileMenu.addSeparator();
fileMenu.add(exitMenu);
fileMenu.setMnemonic('f');
newMenu.setMnemonic('n');
openMenu.setMnemonic('o');
openRecentMenu.setMnemonic('r');
exitMenu.setMnemonic('x');
/* Agrega el menu a la barra de menu*/
menuBar.add(fileMenu);
/* Para situar el menu About en el lado derecho de la barra de
* menu,utilizamos un pegamento (glue) que crea un espacio
* transparente y permite situar el item al final de la barra.*/
menuBar.add(Box.createHorizontalGlue());
aboutMenu = new JMenu("About");
aboutEditorMenu = new JMenuItem("About Lyon Editor");
aboutMenu.add(aboutEditorMenu);
- 72 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
menuBar.add(aboutMenu);
aboutMenu.setMnemonic('a');
aboutEditorMenu.setMnemonic('l');
this.setJMenuBar(menuBar);
}
/** Método que, al abrir una pestaña PARTIENDO DESDE EL
* ESTADO INICIAL DEL EDITOR, actualiza los menús, añadiendo
* elementos a la barra de menú y creando y añadiendo la barra
* de herramientas. */
public void actualizarMenu(){
/* A lo largo de esta función se van creando botones, items de
* menú, añadiéndolos en su lugar correspondiente, añadiendo
* separadores, ActionListeneres, mnémonicos, etc. */
/* Hay que colocar esta orden antes de llamar a createEditMenu()
* ya que si no se producirá una NullPointerException. */
toolBar = new JToolBar();
closeMenu = new JMenuItem("Close");
closeAllMenu = new JMenuItem("Close All");
closeAllExceptMenu = new JMenuItem("Close All Except This");
closeP = new JMenuItem("Close");
closeAllP = new JMenuItem("Close All");
closeAllExceptP = new JMenuItem("Close All Except This");
saveMenu = new JMenuItem("Save");
saveAsMenu = new JMenuItem("Save As");
saveMenu.addActionListener(eventHandler);
saveAsMenu.addActionListener(eventHandler);
closeMenu.addActionListener(eventHandler);
closeAllMenu.addActionListener(eventHandler);
closeAllExceptMenu.addActionListener(eventHandler);
closeP.addActionListener(eventHandler);
closeAllP.addActionListener(eventHandler);
closeAllExceptP.addActionListener(eventHandler);
menuBar.removeAll();
fileMenu.remove(exitMenu);
fileMenu.add(closeMenu);
fileMenu.add(closeAllMenu);
fileMenu.add(closeAllExceptMenu);
- 73 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
fileMenu.addSeparator();
fileMenu.add(saveMenu);
fileMenu.add(saveAsMenu);
fileMenu.addSeparator();
fileMenu.add(exitMenu);
menuBar.add(fileMenu);
closeMenu.setMnemonic('c');
closeAllMenu.setMnemonic('a');
closeAllExceptMenu.setMnemonic('a');
closeP.setMnemonic('c');
closeAllP.setMnemonic('a');
closeAllExceptP.setMnemonic('a');
saveMenu.setMnemonic('s');
saveAsMenu.setMnemonic('a');
exitMenu.setMnemonic('x');
/* **** JToolBar **** */
newButton = new JButton();
newButton.setIcon(new ImageIcon(getClass().
getResource("./Images/nuevo.gif")));
newButton.setMargin(new Insets(0, 0, 0, 0));
newButton.setToolTipText("New");
toolBar.add(newButton);
openButton = new JButton();
openButton.setIcon(new ImageIcon(getClass().
getResource("./Images/abrir.gif")));
openButton.setMargin(new Insets(0, 0, 0, 0));
openButton.setToolTipText("Open");
toolBar.add(openButton);
saveButton = new JButton();
saveButton.setIcon(new ImageIcon(getClass().
getResource("./Images/guardar.gif")));
saveButton.setMargin(new Insets(0, 0, 0, 0));
saveButton.setToolTipText("Save");
toolBar.add(saveButton);
toolBar.addSeparator();
newButton.addActionListener(eventHandler);
openButton.addActionListener(eventHandler);
saveButton.addActionListener(eventHandler);
/* Código para el menú Edit. */
jep = new MyJEditorPane(null, false);
createActionTable(jep);
- 74 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
editMenu = createEditMenu();
menuBar.add(editMenu);
toolBar.addSeparator();
/* Código para el menu Refresh. */
refreshMenu = new JMenu("Refresh");
refreshMenu.setMnemonic('r');
refreshTabMenu = new JMenuItem("Refresh Tab");
refreshTabMenu.setMnemonic('r');
refreshTabMenu.addActionListener(eventHandler);
refreshAndSaveMenu = new JMenuItem("Refresh & Save");
refreshAndSaveMenu.setMnemonic('s');
refreshAndSaveMenu.addActionListener(eventHandler);
refreshButton = new JButton("Refresh", new
ImageIcon(getClass().getResource("./Images/star.png")));
refreshButton.setToolTipText("Refresh");
toolBar.add(refreshButton);
toolBar.addSeparator();
refreshButton.addActionListener(eventHandler);
refreshMenu.add(refreshTabMenu);
refreshMenu.add(refreshAndSaveMenu);
menuBar.add(refreshMenu);
/* Codigo para el menu Insert. */
insertMenu = new JMenu("Insert");
insertMenu.setMnemonic('i');
annotationMenu = new JMenuItem("Annotation");
annotationMenu.setMnemonic('t');
annotationMenu.addActionListener(eventHandler);
attributeMenu = new JMenuItem("Attribute");
attributeMenu.setMnemonic('b');
attributeMenu.addActionListener(eventHandler);
attributeGroupMenu = new JMenuItem("Attribute Group");
attributeGroupMenu.setMnemonic('a');
attributeGroupMenu.addActionListener(eventHandler);
complexTypeMenu = new JMenuItem("Complex Type");
complexTypeMenu.setMnemonic('c');
complexTypeMenu.addActionListener(eventHandler);
- 75 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
elementMenu = new JMenuItem("Element");
elementMenu.setMnemonic('e');
elementMenu.addActionListener(eventHandler);
groupMenu = new JMenuItem("Group");
groupMenu.setMnemonic('g');
groupMenu.addActionListener(eventHandler);
importMenu = new JMenuItem("Import");
importMenu.setMnemonic('i');
importMenu.addActionListener(eventHandler);
includeMenu = new JMenuItem("Include");
includeMenu.setMnemonic('d');
includeMenu.addActionListener(eventHandler);
notationMenu = new JMenuItem("Notation");
notationMenu.setMnemonic('n');
notationMenu.addActionListener(eventHandler);
redefineMenu = new JMenuItem("Redefine");
redefineMenu.setMnemonic('r');
redefineMenu.addActionListener(eventHandler);
simpleTypeMenu = new JMenuItem("SympleType");
simpleTypeMenu.setMnemonic('s');
simpleTypeMenu.addActionListener(eventHandler);
insertMenu.add(annotationMenu);
insertMenu.add(attributeMenu);
insertMenu.add(attributeGroupMenu);
insertMenu.add(complexTypeMenu);
insertMenu.add(elementMenu);
insertMenu.add(groupMenu);
insertMenu.add(importMenu);
insertMenu.add(includeMenu);
insertMenu.add(notationMenu);
insertMenu.add(redefineMenu);
insertMenu.add(simpleTypeMenu);
menuBar.add(insertMenu);
/* Parte del Toolbar de Insert */
annotationButton = new JButton (new
ImageIcon(getClass().getResource("./Images/t.gif")));
annotationButton.setToolTipText("Insert Annotation");
annotationButton.addActionListener(eventHandler);
toolBar.add(annotationButton);
attributeButton = new JButton (new
ImageIcon(getClass().getResource("./Images/b.gif")));
- 76 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
attributeButton.setToolTipText("Insert Attribute");
attributeButton.addActionListener(eventHandler);
toolBar.add(attributeButton);
attributeGroupButton = new JButton (new
ImageIcon(getClass().getResource("./Images/a.gif")));
attributeGroupButton.setToolTipText("Insert Attribute Group");
attributeGroupButton.addActionListener(eventHandler);
toolBar.add(attributeGroupButton);
complexTypeButton = new JButton (new
ImageIcon(getClass().getResource("./Images/c.gif")));
complexTypeButton.setToolTipText("Insert Complex Type");
toolBar.add(complexTypeButton);
elementButton = new JButton (new
ImageIcon(getClass().getResource("./Images/e.gif")));
elementButton.setToolTipText("Insert Element");
toolBar.add(elementButton);
groupButton = new JButton (new
ImageIcon(getClass().getResource("./Images/g.gif")));
groupButton.setToolTipText("Insert Group");
toolBar.add(groupButton);
importButton = new JButton (new
ImageIcon(getClass().getResource("./Images/i.gif")));
importButton.setToolTipText("Insert Import");
importButton.addActionListener(eventHandler);
toolBar.add(importButton);
includeButton = new JButton (new
ImageIcon(getClass().getResource("./Images/d.gif")));
includeButton.setToolTipText("Insert Include");
includeButton.addActionListener(eventHandler);
toolBar.add(includeButton);
notationButton = new JButton (new
ImageIcon(getClass().getResource("./Images/n.gif")));
notationButton.setToolTipText("Insert Notation");
toolBar.add(notationButton);
redefineButton = new JButton (new
ImageIcon(getClass().getResource("./Images/r.gif")));
redefineButton.setToolTipText("Insert Redefine");
toolBar.add(redefineButton);
simpleTypeButton = new JButton (new
ImageIcon(getClass().getResource("./Images/s.gif")));
simpleTypeButton.setToolTipText("Insert Simple Type");
- 77 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
toolBar.add(simpleTypeButton);
toolBar.addSeparator();
/* Codigo para resituar el menu About*/
menuBar.add(Box.createHorizontalGlue());
menuBar.add(aboutMenu);
/* Agrega el toolbar en el norte del contenedor. */
this.getContentPane().add(toolBar, BorderLayout.NORTH);
/* Código del popup menu, compuesto por: definiciones de los
* JMenuItems; En actualizarMenu: creacion de los menus y lineas
* a continuacion de este comentario. En closeFile: la orden
* removeMouseListener para evitar que salga el popup menu cuando
* estemos en el estado inicial. */
p = new JPopupMenu();
p.add(closeP);
p.add(closeAllP);
p.add(closeAllExceptP);
popupListener = new PopupListener(p);
pestana.addMouseListener(popupListener);
}
/** Método que elimina las barras de menús y de herramientas. */
public void resetearMenu(){
Action ac;
/* Si no se hace esto, la línea de la función createEditMenu()
* a = getActionByName(DefaultEditorKit.cutAction) produce una
* excepción. Por esto es necesario volver a dar los nombres
* "originales" a las acciones antes de volver a llamarlas en
* createEditMenu(), ya que allí las buscamos por el nombre
* original para darles el nombre que nosotros queremos. */
ac = getActionByName(DefaultEditorKit.cutAction);
ac.putValue(Action.NAME,DefaultEditorKit.cutAction);
ac = getActionByName(DefaultEditorKit.copyAction);
ac.putValue(Action.NAME,DefaultEditorKit.copyAction);
ac = getActionByName(DefaultEditorKit.pasteAction);
ac.putValue(Action.NAME,DefaultEditorKit.pasteAction);
ac = getActionByName(DefaultEditorKit.selectAllAction);
ac.putValue(Action.NAME,DefaultEditorKit.selectAllAction);
this.remove(menuBar);
- 78 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
this.remove(toolBar);
}
/** Método que crea los elementos del menú Edit(Menú de Edición).
* Devuelve un elemento JMenu que corresponde a este Menú Edit. */
public JMenu createEditMenu() {
JMenu menu = new JMenu("Edit");
menu.setMnemonic('e');
/* Las acciones Undo y Redo son de nuestra propia creación. */
undoAction = new UndoAction(undo);
redoAction = new RedoAction(undo);
undoAction.setRedoAction(redoAction);
redoAction.setUndoAction(undoAction);
menu.add(undoAction);
menu.add(redoAction);
menu.addSeparator();
/* Las acciones que utilizaremos vienen del Default Editor Kit.
* Cogemos las que queremos y las insertamos en el menú. */
Action a;
/* Problema encontrado: Los atributos de Action son Static. Esto
* implica que al cambiarlos, los cambios quedan registrados.
* Esto supone un problema a la hora de "rehacer" el menu,ya que
* el nombre inicial, que se obtiene de DefaultKitEditor y que
* seria por ejemplo "copy-to-clipboard", lo habremos modificado
* a "Copy". Al volver a buscar en la tabla de Acciones que creamos
* con createActionTable, tendremos en esa tabla el nombre Copy
* (pues nosotros mismos lo habíamos modificado y aunque rehagamos
* la tabla, el nombre queda modificado), mientras que lo que
* realmente estamos buscando es el nombre por defecto del default
* editor kit que es en este caso copy-to-clipboard. La solución
* adoptada finalmente ha sido, al llamar a resetearMenu, obtener
* la accion, y volver a ponerle "el nombre original", para que
* así, al llamar a getActionByName a continuación, la Hashtable
* actions pueda obtener las acciones con el nombre original. Así
* queda solucionado el problema. */
/* Para esta parte de código, se ha utilizado la idea de utilizar
* objetos action para asignar la misma acción a un item de menu
* y a un botón. */
JButton button = null;
JMenuItem menuItem = null;
- 79 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
a = getActionByName(DefaultEditorKit.cutAction);
a.putValue(Action.NAME,"Cut");
a.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_T));
a.putValue(Action.ACCELERATOR_KEY,KeyStroke.
getKeyStroke('X',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
a.putValue(Action.SMALL_ICON, new ImageIcon(getClass().
getResource("./Images/cortar.gif")));
button = toolBar.add(a);
button.setToolTipText("Cut");
menuItem = menu.add(a);
/* Si se quiere quitar el icono del menu, utilizar la orden:
* menuItem.setIcon(null); También se puede usar button.
* setText("..."); para poner algún texto en el botón. */
a = getActionByName(DefaultEditorKit.copyAction);
a.putValue(Action.NAME,"Copy");
a.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_C));
a.putValue(Action.ACCELERATOR_KEY,KeyStroke.
getKeyStroke('C',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
a.putValue(Action.SMALL_ICON, new ImageIcon(getClass().
getResource("./Images/copiar.gif")));
button = toolBar.add(a);
button.setToolTipText("Copy");
menuItem = menu.add(a);
a = getActionByName(DefaultEditorKit.pasteAction);
a.putValue(Action.NAME,"Paste");
a.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_P));
a.putValue(Action.ACCELERATOR_KEY,KeyStroke.
getKeyStroke('V',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
a.putValue(Action.SMALL_ICON, new ImageIcon(getClass().
getResource("./Images/pegar.gif")));
button = toolBar.add(a);
button.setToolTipText("Paste");
menuItem = menu.add(a);
menu.addSeparator();
a = getActionByName(DefaultEditorKit.selectAllAction);
a.putValue(Action.NAME,"Select All");
a.putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_A));
a.putValue(Action.ACCELERATOR_KEY,KeyStroke.
- 80 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
getKeyStroke('A',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
menu.add(a);
/* El codigo a continuación se puede utilizar pero existe un
* problema, y es que no pone Cut sino cut-to-clipboard. Con
* el código de arriba ponemos a la acción el nombre que queramos.
* menu.add(getActionByName(DefaultEditorKit.cutAction));
* menu.add(getActionByName(DefaultEditorKit.copyAction));
* menu.add(getActionByName(DefaultEditorKit.pasteAction));
* menu.addSeparator();
* menu.add(getActionByName(DefaultEditorKit.selectAllAction));*/
return menu;
}
/** Métodos que crea una tabla de acciones disponibles
* para un componente de texto..
* @param textComponent Componente de texto del que queremos
* conocer las acciones que realiza. */
public void createActionTable(JTextComponent textComponent) {
actions = new Hashtable();
Action[] actionsArray = textComponent.getActions();
for (int i = 0; i < actionsArray.length; i++) {
Action a = actionsArray[i];
actions.put(a.getValue(Action.NAME), a);
}
}
/** Método que permiten encontrar una acción dada por el
* kit de edición utilizando su nombre.
* @param name Nombre de la acción que buscamos. */
public Action getActionByName(String name) {
return (Action)(actions.get(name));
}
/** Método que crea el menú de archivos abiertos recientemente.
- 81 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* Crea un item de menú por cada una de las posibles cuatro
* líneas que puede haber en el fichero config.txt y los añade
* al menú Open Recent File. */
public void crearRecentMenu(){
try{
int cuenta = SIZE;
bf = new BufferedReader(new FileReader("./config.txt"));
linea = bf.readLine();
while (linea != null){
if(cuenta > 0){
switch (cuenta){
case 4:
jmi1 = new JMenuItem(linea);
openRecentMenu.add(jmi1);
jmi1.addActionListener(eventHandler);
break;
case 3:
jmi2 = new JMenuItem(linea);
openRecentMenu.add(jmi2);
jmi2.addActionListener(eventHandler);
break;
case 2:
jmi3 = new JMenuItem(linea);
openRecentMenu.add(jmi3);
jmi3.addActionListener(eventHandler);
break;
case 1:
jmi4 = new JMenuItem(linea);
openRecentMenu.add(jmi4);
jmi4.addActionListener(eventHandler);
break;
}
cuenta --;
}
else{
/* Para salir del while en caso de que hayamos
* escrito algo más de la cuenta en config.txt. */
break;
}
linea = bf.readLine();
}
bf.close();
}catch(Exception e){
e.printStackTrace();
}
}
- 82 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/** Método que actualiza el menú de archivos abierto recientemente.
* Elimina los items de menú que hubiese en el menú Open
* Recent File, antes de llamar a crearRecentMenu que añadirá los
* nuevos elementos al menú.
* @param nom_lineas Número de líneas en el fichero config. */
public void actualizarRecentMenu(int num_lineas){
switch (num_lineas){
case 1:
break;
case 2:
openRecentMenu.remove(jmi1);
break;
case 3:
openRecentMenu.remove(jmi1);
openRecentMenu.remove(jmi2);
break;
case 4:
openRecentMenu.remove(jmi1);
openRecentMenu.remove(jmi2);
openRecentMenu.remove(jmi3);
break;
default:
openRecentMenu.remove(jmi1);
openRecentMenu.remove(jmi2);
openRecentMenu.remove(jmi3);
openRecentMenu.remove(jmi4);
break;
}
crearRecentMenu();
}
/** Método que asigna los elementos Undo y Redo correspondientes
* al documento de texto que se esté tratando en cada instante.
* @param jep Panel de texto seleccionado en el instante de
* efectuar la llamada a este método. */
public void setUndoableMenu(MyJEditorPane jep){
/* Eliminamos el item de Menú correspondiente a Undo. */
editMenu.remove(0);
/* Eliminamos el item de Menú correspondiente a Redo. ¡OJO!
* De nuevo la posición 0, pues al eliminar Undo el resto
* de elementos sufren un desplazamiento de su posición. */
editMenu.remove(0);
- 83 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* En jep tenemos almacenado el MyJEditorPane que quedará
* seleccionado. Cargamos en las variables de Inicial las
* que corresponden a dicho MyJEditorPane.*/
undo = jep.undo;
undoAction = jep.undoAction;
redoAction = jep.redoAction;
/* Creamos y añadimos los nuevos items de menú de Undo y
* Redo que corresponderán a la pestaña que quedará en
* primer plano. */
JMenuItem jmi = new JMenuItem (undoAction);
editMenu.add(jmi,0);
jmi = new JMenuItem(redoAction);
editMenu.add(jmi,1);
}
/* ****************************************************** */
/* ******************* REFRESCAR ********************* */
/* ****************************************************** */
/** Método que refresca el área de texto y el árbol asociado. */
public void refresh(){
split = (JSplitPane)pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).getComponentAt(0, 0);
jep.refrescar();
}
/** Método que refresca el área de texto y el árbol
* asociado y a continuación salva el documento. */
public void refreshAndSave(){
refresh();
saveFile();
}
/* ****************************************************** */
/* ******* INSERTAR ELEMENTOS EN EL ESQUEMA ******* */
/* ****************************************************** */
- 84 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/** Método que inserta un elemento Annotation en el esquema. */
public void annotation(){
String texto = null;
String opcion;
String lengua;
Annotation a = new Annotation();
a.setVisible(true);
split = (JSplitPane)pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).
getComponentAt(0, 0);
/* Si NO hemos cancelado (en cuyo caso el texto habrá
* sido puesto a "") realizaremos las acciones que vienen
* a continuación. Si cancelamos no hacemos nada. */
if(a.cerrado == false){
if(!a.jtf.getText().equals("")){
texto = a.jtf.getText();
if(a.doc.isSelected()){
opcion = "documentation";
lengua = a.lenguaje.getText();
}
else{
opcion = "appinfo";
lengua = null;
}
jep.addAnnotation(texto, opcion, lengua, false);
}
}
}
/** Método que inserta un elemento Attribute en el esquema. */
public void attribute(){
String nombre;
String tipo;
String id;
String uso;
String valor;
Attribute at = new Attribute();
- 85 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
at.setVisible(true);
if(at.cancelado == false && at.cerrado == false){
/* En esta función, al contrario que en annotation, veremos
* si hemos cancelado mediante una variable booleana de la
* clase Attribute. */
nombre = at.jtf1.getText();
tipo = at.jtf2.getText();
id = at.jtf3.getText();
uso = at.jtf4.getText();
valor = at.jtf5.getText();
split = (JSplitPane)pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).
getComponentAt(0, 0);
if(at.annotation == true){
Annotation a = new Annotation();
a.setVisible(true);
if(!a.jtf.getText().equals("")){
String texto = null;
String opcion;
String lengua;
texto = a.jtf.getText();
if(a.doc.isSelected()){
opcion = "documentation";
lengua = a.lenguaje.getText();
}
else{
opcion = "appinfo";
lengua = null;
}
jep.addAttribute(nombre, tipo, id, uso, valor,
true, texto, opcion, lengua);
}
/*else: Si cancelo el annotation -> ¡¡no hago nada!!*/
}
else{
jep.addAttribute(nombre, tipo, id, uso, valor,
false, null, null, null);
}
}
}
- 86 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/** Método que inserta un elemento AttributeGroup en el esquema. */
public void attributeGroup(){
String nombre;
String num_att;
AttributeGroup ag = new AttributeGroup();
ag.setVisible(true);
if(ag.cancelado == false && ag.cerrado == false){
/* En esta función, al contrario que en annotation,
* veremos si hemos cancelado mediante una variable
* booleana de la clase AttributeGroup. */
nombre = ag.jtf1.getText();
num_att = ag.jtf2.getText();
split = (JSplitPane)pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).
getComponentAt(0, 0);
if(ag.annotation == true){
Annotation a = new Annotation();
a.setVisible(true);
if(!a.jtf.getText().equals("")){
String texto = null;
String opcion;
String lengua;
texto = a.jtf.getText();
if(a.doc.isSelected()){
opcion = "documentation";
lengua = a.lenguaje.getText();
}
else{
opcion = "appinfo";
lengua = null;
}
jep.addAttributeGroup();
}
/*else: Si cancelo el annotation -> ¡¡no hago nada!!*/
}
else{
- 87 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
jep.addAttributeGroup();
}
}
}
/** Método que inserta un elemento Import en el esquema.
* En este caso no se ha podido dar al método el nombre
* del elemento, pues import constituye una palabra
* reservada en el lenguaje Java. */
public void importar(){
String id;
String namespace;
String schemaLocation;
Import imp = new Import();
imp.setVisible(true);
if(imp.cancelado == false && imp.cerrado == false){
/* En esta función, al contrario que en annotation,
* veremos si hemos cancelado mediante una variable
* booleana de la clase Import. */
id = imp.jtf1.getText();
namespace = imp.jtf2.getText();
schemaLocation = imp.jtf3.getText();
split = (JSplitPane)pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).
getComponentAt(0, 0);
if (imp.annotation == true){
Annotation a = new Annotation();
a.setVisible(true);
if(!a.jtf.getText().equals("")){
String texto = null;
String opcion;
String lengua;
texto = a.jtf.getText();
if(a.doc.isSelected()){
opcion = "documentation";
lengua = a.lenguaje.getText();
- 88 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
}
else{
opcion = "appinfo";
lengua = null;
}
jep.addImport(id, namespace, schemaLocation,
true, texto, opcion, lengua);
}
/*else: Si cancelo el annotation -> ¡¡no hago nada!!*/
}
else{
jep.addImport(id, namespace, schemaLocation,
false, null, null, null);
}
}
}
/** Método que inserta un elemento Include en el esquema. */
public void include(){
String id;
String schemaLocation;
Include inc = new Include();
inc.setVisible(true);
if(inc.cancelado == false && inc.cerrado == false){
/* En esta función, al contrario que en annotation,
* veremos si hemos cancelado mediante una variable
* booleana de la clase Include. */
id = inc.jtf1.getText();
schemaLocation = inc.jtf2.getText();
split = (JSplitPane)pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).
getComponentAt(0, 0);
if (inc.annotation == true){
Annotation a = new Annotation();
a.setVisible(true);
if(!a.jtf.getText().equals("")){
String texto = null;
- 89 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
String opcion;
String lengua;
texto = a.jtf.getText();
if(a.doc.isSelected()){
opcion = "documentation";
lengua = a.lenguaje.getText();
}
else{
opcion = "appinfo";
lengua = null;
}
jep.addInclude(id, schemaLocation,
true, texto, opcion, lengua);
}
/*else: Si cancelo el annotation -> ¡¡no hago nada!!*/
}
else{
jep.addInclude(id, schemaLocation,
false, null, null, null);
}
}
}
}
- 90 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
MyDocumentListener.java
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
/** Clase que escucha los cambios que se producen en el documento
* del objeto MyJEditorPane al que está asociado.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0*/
public class MyDocumentListener implements DocumentListener {
Inicial i;
JSplitPane split;
JScrollPane jsp;
MyJEditorPane jep;
String filename;
/** Constructor de la clase. */
MyDocumentListener(Inicial in){
i = in;
}
/* Método que se ejecuta cuando se inserta texto.
* Hereda comentario de documentación. */
public void insertUpdate(DocumentEvent e) {
update(e);
}
/* Método que se ejecuta cuando se retira texto.
* Hereda comentario de documentación. */
public void removeUpdate(DocumentEvent e) {
update(e);
}
- 91 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* Muestra el tipo de edición que se produjo.
* En nuestra aplicación no se utiliza.
* Hereda comentario de documentación. */
public void changedUpdate(DocumentEvent e) {
}
/** Método que pone el asterisco al título de la pestaña cuando se ha
* producido un cambio en el texto desde la última modificación. */
private void update(DocumentEvent e) {
split = (JSplitPane)i.pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane)jsp.getComponent(0).getComponentAt(0, 0);
/* Estos if evitan que realicemos las órdenes que incluye el tercer if
* cada vez que se realice cualquier modificación (escritura) en el
* documento, que es lo que estaba programado en un principio. Así se
* consigue aumentar la eficiencia, dado que no será necesario ejecutar
* tanto código cada vez que se pulse una tecla.
* Si es nuevo, getIsSaved estará a false, con lo cual no entraríamos en
* el tercer if jamás y no pondríamos el asterisco. Para evitarlo, he
* incluido la variable "asterisco" en MyJEditorPane. Esta variable sólo
* la utilizaremos para los archivos nuevos, para el resto no es necesaria.
* La inicializamos a false al crear el jep. Si el archivo es nuevo,
* miraremos si ya tiene o no asterisco. Si aún no tiene, (asterisco =
* false), ponemos asterisco = true y ponemos momentáneamente isSaved
* a true. Así entraremos en el tercer if y pondremos el asterisco a la
* pestaña. El siguiente caracter que escribamos, no entrará en el segundo
* if, ya que asterisco es true, por tanto, no pondrá is saved a true, y
* por tanto no entraremos en el tercer if. Una vez que guardemos el
* archivo, la variable isNew sera puesta a false, con lo cual no
* entraremos en el primer if, y por tanto el valor de la variable
* asterisco ya nos dará totalmente igual.
*
* Tal vez todo esto pueda resultar un poco lioso, pero a la hora de la
* eficiencia es mejor ya que dejamos de realizar las 4 lineas del tercer
* if cada vez, que era lo que se había programado en un principio.*/
if(jep.getIsNew()){
- 92 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
if(!jep.getAsterisco()){
jep.setAsterisco(true);
jep.setIsSaved(true);
}
}
if(jep.getIsSaved()){
jep.setIsSaved(false);
filename = jep.getFileName();
int index =i.pestana.getSelectedIndex();
i.pestana.setTitleAt(index,"*" + filename);
}
}
}
- 93 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
MyJEditorPane.java
import java.util.Vector;
import javax.swing.Action;
import javax.swing.JEditorPane;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JTree;
import javax.swing.KeyStroke;
import javax.swing.text.BadLocationException;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.Caret;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.StyleConstants;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.undo.UndoManager;
import javax.xml.stream.FactoryConfigurationError;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Toolkit;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
/** Clase que ofrece soporte para la escritura de texto: es un panel
* de edición. Hereda de la clase JEditorPane del paquete javax.swing.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0*/
public class MyJEditorPane extends JEditorPane{
- 94 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
private File file;
private boolean isSaved;
private boolean isNew;
private boolean asterisco;
private Caret caret;
String fileName;
/* Elementos para implementar Deshacer-Rehacer. */
UndoAction undoAction;
RedoAction redoAction;
UndoManager undo = new UndoManager();
/* El siguiente objeto se utilizará para el popup menu */
JPopupMenu jpum;
/* Para leer el archivo utilizando StAX. */
XMLInputFactory inputFactory;
XMLStreamReader reader;
/* Definición de los estilos a aplicar en el tratamiento de texto. */
MutableAttributeSet apertura = new SimpleAttributeSet();
MutableAttributeSet etiqueta = new SimpleAttributeSet();
MutableAttributeSet declaracion_pi = new SimpleAttributeSet();
MutableAttributeSet comentario = new SimpleAttributeSet();
MutableAttributeSet normal = new SimpleAttributeSet();
MutableAttributeSet namespace = new SimpleAttributeSet();
MutableAttributeSet atributo = new SimpleAttributeSet();
MutableAttributeSet valorAtributo = new SimpleAttributeSet();
/* Definición de las cadenas de caracteres constantes
* que se utilizarán en los Esquemas XML. */
final String menor = "<";
final String mayor = ">";
final String xmlns = "xmlns:";
final String comilla= "'";
final String espacio = " ";
final String dosp = ":";
final String igual = "=";
final String rc = "\n";
final String cierre = "/";
final String tabulador = "\t";
final String open_comment = "<!--";
final String close_comment = "-->";
final String a_p_instr = "<?";
final String c_p_instr = "?>";
final String lengua = "xml:lang=";
- 95 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/* Cuenta el número de tabulaciones. */
int cuenta_tab = -1;
/* Para la implementación de refrescar(). Esta variable es importante
* a la hora de diferenciar, en leer(), si estamos refrescando,
* pues entonces habrá que modificar la variable file. */
boolean refresh;
String str;
/* Variables para tratar el árbol. */
JTree arbol;
DefaultTreeModel treeModel;
/* Nivel del nodo actual */
int nivel_act = 0;
DefaultMutableTreeNode top = new DefaultMutableTreeNode();
DefaultMutableTreeNode a;
DefaultMutableTreeNode b;
DefaultMutableTreeNode c;
DefaultMutableTreeNode d;
DefaultMutableTreeNode e;
DefaultMutableTreeNode f;
DefaultMutableTreeNode g;
DefaultMutableTreeNode h;
DefaultMutableTreeNode i;
DefaultMutableTreeNode j;
/* Indica si hay atributos en el elemento para, en dicho
* caso, coger lo que nos interesa mostrar en el árbol. */
boolean hay_atrib;
String prefijo = null;
/* File auxiliar para refrescar un fichero no_nuevo. */
File file_aux = null;
/* Fichero de refresco. Se crea aqui, y apuntamos a él desde el código.*/
File file_refresh = new File("./config_refresh.txt");
/* Para almacenar las palabras clave del esquema. */
Vector keywords = new Vector();
/* Objeto que implementa la interfaz Document y que haremos
* que sea el Modelo de nuestro Panel de Texto. */
CodeDocument codeDoc = new CodeDocument(this);
/* Implementar añadir elementos al esquema. */
int pto_insercion=0;
- 96 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* ****************************************************** */
/* ****************** CONSTRUCTOR ******************* */
/* ****************************************************** */
/** Constructor de la clase.
* @param f Fichero asociado a este panel de edición.
* @param New Indica si el fichero que abrimos en este
* panel de texto es nuevo o ya existía. */
public MyJEditorPane(File f, boolean New) {
/* Para que podamos tratar con texto con estilo no podemos utilizar
* el constructor con estos parámetros: super ("text/plain", null);
* Hay que utilizar la línea a continuación para que nuestro
* EditorPane trate el texto con formato.*/
super("text/rtf", null);
file = f;
inicializar_documento();
/* Variable que indica si el archivo es nuevo. Pasada
* como parámetro en el constructor de la clase. */
isNew = New;
/* La variable asterisco se utiliza para poner un asterisco
* en el título de la pestaña cuando esta se modifica. Sólo
* se usa cuando el archivo es nuevo. Una vez salvado el
* archivo nuevo esta variable no se utilizará más. */
asterisco = false;
/* Si el archivo existe ya, al abrirlo estará salvado. Si es un
* fichero que no existe, es decir, es nuevo, no está salvado. */
if(isNew)
isSaved=false;
else
isSaved=true;
/* Las siguientes líneas de código sirven para implementar el Popup
* menu para cada uno de los elementos MyJEditorPane. Se define
* dentro de esta clase para que sea general para todos los jep que
* creemos, tanto si vienen de newFile() como de openFile(). El
* código no es complicado, el único detalle a resaltar es que es
* necesario utilizar un MouseListener, y se crea para ello una
* clase PopupListener que hereda de MouseAdapter. */
jpum = new JPopupMenu();
Action a;
a = new DefaultEditorKit.CutAction();
- 97 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
a.putValue(Action.NAME,"Cut");
a.putValue(Action.ACCELERATOR_KEY,KeyStroke.
getKeyStroke('X',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
jpum.add(a);
a = new DefaultEditorKit.CopyAction();
a.putValue(Action.NAME,"Copy");
a.putValue(Action.ACCELERATOR_KEY,KeyStroke.
getKeyStroke('C',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
jpum.add(a);
a = new DefaultEditorKit.PasteAction();
a.putValue(Action.NAME,"Paste");
a.putValue(Action.ACCELERATOR_KEY,KeyStroke.
getKeyStroke('V',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
jpum.add(a);
this.addMouseListener(new PopupListener(jpum));
/* Uno nuevo para cada MyJEditorPane para poder hacer y deshacer
* lo propio de cada documento aun cambiando de pestaña. */
undoAction = new UndoAction(undo);
undoAction.putValue(Action.ACCELERATOR_KEY,
KeyStroke.
getKeyStroke('Z',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
redoAction = new RedoAction(undo);
redoAction.putValue(Action.ACCELERATOR_KEY,
getKeyStroke('Y',Toolkit.getDefaultToolkit().
getMenuShortcutKeyMask(), false));
KeyStroke.
undoAction.setRedoAction(redoAction);
redoAction.setUndoAction(undoAction);
/* Inicialización de los estilos. */
StyleConstants.setForeground(apertura,Color.RED);
StyleConstants.setForeground(etiqueta,Color.BLUE);
StyleConstants.setForeground(declaracion_pi,Color.RED);
StyleConstants.setBold(declaracion_pi,true);
StyleConstants.setItalic(comentario,true);
StyleConstants.setForeground(comentario,Color.GREEN);
StyleConstants.setItalic(namespace,true);
StyleConstants.setForeground(namespace,Color.ORANGE);
StyleConstants.setForeground(valorAtributo,Color.MAGENTA);
StyleConstants.setItalic(valorAtributo,true);
StyleConstants.setBold(valorAtributo,true);
}
- 98 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/* ****************************************************** */
/* ** MÉTODOS PARA TRABAJAR CON LAS VARIABLES ** */
/* ****************************************************** */
/* Métodos para manejar la variable booleana isSaved
* que indica si el documento está o no salvado.*/
public boolean getIsSaved(){
return isSaved;
}
public void setIsSaved(boolean b){
isSaved = b;
}
/* Métodos para manejar la variable booleana isNew
* que indica si el documento es o no nuevo.*/
public boolean getIsNew(){
return isNew;
}
public void setIsNew(boolean b){
isNew = b;
}
/* Métodos para tratar con la variable booleana asterisco. */
public boolean getAsterisco(){
return asterisco;
}
public void setAsterisco(boolean b){
asterisco = b;
}
/* ****************************************************** */
/* ***** MÉTODOS PARA TRABAJAR CON EL FICHERO ***** */
/* ****************************************************** */
- 99 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/** Método que inicializa el Caret (o cursor) en la
* posición inicial del texto. */
public void initCaret(){
caret = this.getCaret();
this.setCaretColor(Color.RED);
caret.setDot(0);
caret.setVisible(true);
}
/** Devuelve el nombre de la ruta absoluta del fichero asociado. */
public String getAbsoluteName(){
return file.getAbsolutePath();
}
/* Métodos pensado para el trabajo con las distintas pestañas.
* Utilizados desde la clase Inicial. Asignan el fichero que
* corresponde al panel de texto, así como modifican y obtienen
* el nombre de dicho fichero. */
public void setFile(File archi){
file=archi;
}
public void setFileName(String name){
fileName = name;
}
public String getFileName(){
String name;
if (isNew)
name = fileName;
else
name = file.getName();
return name;
}
/** Método encargado de leer el fichero: utilizando StAX captura eventos.
* A la vez se encarga de crear el árbol de la estructura del documento.*/
public void leer(){
try{
codeDoc.leer = true;
- 100 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
setCursor(Cursor.getPredefinedCursor
(Cursor.WAIT_CURSOR));
String s = null;
cuenta_tab = -1;
/* ul = ultimo leido: Sirve para conocer de qué tipo
* fue el último evento. pl= penúltimo leído. */
boolean ul_start = false;
boolean ul_characters = false;
boolean ul_end = false;
boolean pl_end = false;
/* Variable para realizar la inicialización del árbol. */
boolean no_inicializado = true;
if(refresh){
/* Cuando refrescamos, si el documento es un Untitled, o
* sea, es nuevo, y no ha sido aún guardado, la variable
* isNew sera verdadera. Si se trata de un documento
* nuevo pero que ya ha sido salvado, o bien un
* documento ya existente que hemos abierto, entonces
* isNew es false. En este caso, la variable file apunta
* al fichero, y al refrescar, con las lineas que siguen,
* escribimos todo en el fichero SIN CONSENTIMIENTO
* DEL USUARIO. Es por esto que para refrescar un
* fichero no_nuevo hay que utilizar un fichero auxiliar.
* Podemos usar el mismo config_refresh_new.txt que se
* utiliza en el caso del nuevo. */
if(!isNew){
file_aux = file;
file = file_refresh;
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(str.getBytes());
fos.close();
}
inputFactory = XMLInputFactory.newInstance();
reader = inputFactory.createXMLStreamReader(
new FileInputStream(file));
/* Código de tratamiento del evento START_DOCUMENT: Este
* evento no lo reconocía mi programa en un principio. Esto
* es debido a que, cuando se crea una instancia de
* XMLStreamReader en un stream, el evento inicial actual es
* el estado START_DOCUMENT. El método next() puede
* usarse entonces para obtener el siguiente evento. El
- 101 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* problema que se presentaba era que directamente se pasaba
* al bucle while y se utilizaba el método next(), perdiendo
* así el evento START_DOCUMENT. */
int event = reader.getEventType();
if (event == XMLStreamConstants.START_DOCUMENT){
String encoding = reader.getCharacterEncodingScheme();
if (encoding == null)
encoding = reader.getEncoding();
if (encoding == null)
encoding = "UTF-8";
String version = reader.getVersion();
if (version == null)
version = "1.0";
/* Dado que estos Strings no los vamos a reutilizar,
* no los definimos arriba sino aqui directamente. */
String declaration = "<?xml version=\"";
declaration += version;
declaration += "\" encoding=\"";
declaration += encoding;
if (reader.standaloneSet()) {
declaration += "\" standalone=\"";
if(reader.isStandalone())
declaration += "yes";
else
declaration += "no";
}
declaration += "\"?>";
declaration += rc;
codeDoc.insertString(codeDoc.getLength(),
declaration,declaracion_pi);
}
while(reader.hasNext()) {
event=reader.next();
switch(event){
/* El caso START_DOCUMENT ha sido eliminado del
* switch pues es tratado justo antes de éste. */
case(XMLStreamConstants.START_ELEMENT):
ul_start = true;
ul_characters = false;
ul_end = false;
/* Aquí me da igual si el anterior era o no de cierre. */
- 102 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
pl_end = false;
cuenta_tab ++;
nivel_act++;
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(codeDoc.
getLength(),s,apertura);
}
s = menor;
codeDoc.insertString(codeDoc.
getLength(),s,apertura);
if(reader.getPrefix() != null)
s=reader.getPrefix()+ ":" +
reader.getLocalName();
else
s=reader.getLocalName();
codeDoc.insertString(codeDoc.
getLength(),s,etiqueta);
if (reader.getLocalName().equals("schema")){
prefijo = reader.getNamespaceContext().
getPrefix(reader.getNamespaceURI());
s = espacio + xmlns + prefijo
+ igual + comilla +
reader.getNamespaceURI() +
comilla;
codeDoc.insertString(codeDoc.
getLength(),s,namespace);
nivel_act=0;
if(no_inicializado){
if (!refresh){
top = new
DefaultMutableTreeNode(
reader.getLocalName());
inicializar_arbol(top);
}
else{
/* De la función clear de
* DynamicTreeDemo, de "How to
* Use Trees", tutorial Sun.
- 103 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* Esto quita todos los nodos
* menos el nodo padre.*/
if(treeModel != null){
top.removeAllChildren();
treeModel.reload();
}
else{
top = new
DefaultMutableTreeNode
(reader.
getLocalName());
inicializar_arbol(top);
}
}
no_inicializado = false;
}
}
for(int i=0; i<reader.getAttributeCount();i++){
hay_atrib = true;
if (!reader.getAttributePrefix(i).equals(""))
s = espacio + reader.getAttributePrefix(i)
+ dosp+ reader.
getAttributeLocalName(i) + igual;
else
s = espacio + reader.
getAttributeLocalName(i)+ igual;
codeDoc.insertString(codeDoc.
getLength(),s,atributo);
s = comilla + reader.getAttributeValue(i)
+ comilla ;
codeDoc.insertString(codeDoc.
getLength(),s,valorAtributo);
}
s = mayor + rc;
codeDoc.insertString(codeDoc.getLength(),s,apertura);
if (!reader.getLocalName().equals("schema")){
if (hay_atrib){
s="";
- 104 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
for(int i=0; i<reader.
getAttributeCount();i++){
if(reader.getAttributeLocalName(i)
.equals("name") || reader.
getAttributeLocalName(i).
equals("ref")){
if (!reader.
getAttributePrefix(i).
equals(""))
s = espacio + "--- "+
reader.
getAttributePrefix(i)+
dosp + reader.
getAttributeLocalName
(i)+ igual;
else
s = espacio + "--- "+
reader.
getAttributeLocalName
(i)+ igual;
s += comilla + reader.
getAttributeValue(i)
+ comilla ;
}
}
}
else
s = "";
/* No es necesario poner para cada nodo
* allowsChildren a true como antes ya que
* Al inicializar el árbol con un defaultTreeModel,
* se crea un árbol en que cualquier nodo puede
* tener un hijo. Ocurre lo mismo en el caso del
* nodo raiz "top".*/
switch (nivel_act){
case(1):
a = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(a,top,top.getChildCount());
- 105 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
break;
case(2):
b = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(b,a,a.getChildCount());
break;
case(3):
c = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(c,b,b.getChildCount());
break;
case(4):
d = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(d,c,c.getChildCount());
break;
case(5):
e = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(e,d,d.getChildCount());
break;
case(6):
f = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(f,e,e.getChildCount());
break;
case(7):
g = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
- 106 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
treeModel.insertNodeInto
(g,f,f.getChildCount());
break;
case(8):
h = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(h,g,g.getChildCount());
break;
case(9):
i = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(i,h,h.getChildCount());
break;
case(10):
j = new
DefaultMutableTreeNode(
reader.getLocalName()+s);
treeModel.insertNodeInto
(j,i,i.getChildCount());
break;
default:
break;
}
}
hay_atrib = false;
break;
case(XMLStreamConstants.CHARACTERS):
s = reader.getText();
s = s.trim();
/* Cuando usamos trim(), si eran una serie de
* espacios en blanco, retornos de carro, etc,
* el resultado es una cadena vacía ("") como
* muestran estos resultados:
System.out.println("Valor:"+s.equals("")); TRUE
- 107 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
System.out.println("Valor:"+s.equals("\n")); FALSE
System.out.println("Valor:"+s.equals(" ")); FALSE
System.out.println("Valor:"+s.equals("null")); FALSE
*/
codeDoc.insertString(codeDoc.getLength()-1,s,normal);
/* Este es el caso en que hay que ver si el anterior era o no
* de cierre, para cuando compruebe en End_Element. */
pl_end = false;
/* Compruebo también si es characters, por el caso poco
* probable de tener etiqueta--texto--comentario o PI-* texto -- etiqueta. En ese caso habrá dos eventos
* character seguidos. En dicho caso, decido que se
* salte de línea. */
if(ul_end || ul_characters)
pl_end = true;
ul_start = false;
ul_characters = true;
ul_end = false;
break;
case(XMLStreamConstants.COMMENT):
s = tabulador + open_comment + reader.getText()
+ close_comment +rc;
codeDoc.insertString(codeDoc.getLength(),s,comentario);
break;
case(XMLStreamConstants.END_ELEMENT):
if (ul_start){
s = cierre;
codeDoc.insertString(codeDoc.
getLength()-2,s,apertura);
}
else if(ul_characters && !s.equals("")){
/*s viene de characters: o está vacío (ya que si eran
* sólo espacios en blanco, tabuladores y/o retornos
* de carro los hemos eliminado con trim(), o tiene
* texto. Aqui tratamos el caso en que contenga
* caracteres: puede haber dos casos:
* apertura - texto - cierre
- 108 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* cierre - texto - cierre*/
if(pl_end){
/* Si el texto se encuentra entre dos
* elementos de cierre, hay que saltar
* de línea. Añadimos otro retorno de
* carro para conseguir esto. */
codeDoc.insertString(codeDoc.
getLength()-1,rc,apertura);
/* Sólo tabulamos en el caso que sea
* cierre a continuación de cierre. */
s = tabulador;
for (int i=0; i<cuenta_tab; i++)
codeDoc.insertString(codeDoc.
getLength()-1,s,apertura);
}
s = menor + cierre;
codeDoc.insertString(codeDoc.
getLength()-1,s,apertura);
if(reader.getPrefix() != null)
s=reader.getPrefix()+":"+
reader.getLocalName();
else
s=reader.getLocalName();
codeDoc.insertString(codeDoc.
getLength()-1,s,etiqueta);
s = mayor;
codeDoc.insertString(codeDoc.
getLength()-1,s,apertura);
}
/* A este último else se llega en dos situaciones distintas.
* O bien venimos de characters con s vacio, o bien
* venimos de otro elemento de cierre (sin characters
* entre el anterior y el actual). En ambos casos hay que
* introducir las tabulaciones correspondientes, por esto
* el código es igual*/
else {
s = tabulador;
for (int i=0; i<cuenta_tab; i++)
codeDoc.insertString(codeDoc.
- 109 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
getLength(),s,apertura);
s = menor + cierre;
codeDoc.insertString(codeDoc.
getLength(),s,apertura);
if(reader.getPrefix() != null)
s=reader.getPrefix()+":"+
reader.getLocalName();
else
s=reader.getLocalName();
codeDoc.insertString(codeDoc.
getLength(),s,etiqueta);
s = mayor + rc;
codeDoc.insertString(codeDoc.
getLength(),s,apertura);
}
cuenta_tab--;
nivel_act--;
ul_start = false;
ul_characters = false;
ul_end = true;
pl_end = false;
break;
case(XMLStreamConstants.
PROCESSING_INSTRUCTION):
s = tabulador + a_p_instr + reader.getPITarget()+ " " +
reader.getPIData() + c_p_instr + rc;
codeDoc.insertString(codeDoc.
getLength(),s,declaracion_pi);
break;
case(XMLStreamConstants.END_DOCUMENT):
setCursor(Cursor.getPredefinedCursor
(Cursor.TEXT_CURSOR));
expandTree(arbol);
codeDoc.leer=false;
/* Solo inicializo valores la primera vez que leo.
* Al refrescar no hay que volver a hacerlo.*/
- 110 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
if(!refresh)
inicializar_valores_tras_leer();
else{
/*Si estoy refrescando, vuelvo a apuntar file al
* fichero original, almacenado en file_aux, pero
* sólo en caso de que no sea nuevo!!*/
if(!isNew)
file = file_aux;
}
break;
/* Caso ATTRIBUTE, NAMESPACE y SPACE
* suprimidos. En todas las pruebas hechas no se han
* producido estos eventos. Además, lo único que hacían
* era imprimir el tipo de evento. En caso de que se
* produzcan el default se encargará de ellos.*/
default:
break;
}
}
reader.close();
}catch(FactoryConfigurationError e){
System.err.println("FactoryConfigurationError"
+e.getMessage());
}catch(XMLStreamException e){
System.err.println("XMLStreamException: "+e.getMessage());
e.printStackTrace();
JOptionPane.showMessageDialog(null,
"ATTENTION! THE DOCUMENT IS NOT WELL " +
"FORMED." + " THE PARSER GAVE THE " +
"FOLLOWING MESSAGE: \n\n"+ e.getMessage() ,
"ERROR",JOptionPane.ERROR_MESSAGE);
/* Si tenemos excepción y no hemos llegado a END_
* DOCUMENT queremos volver a tener el cursor
* de texto y no el de espera.*/
setCursor(Cursor.getPredefinedCursor
(Cursor.TEXT_CURSOR));
/* Obtenemos la línea en que se produce la excepción. */
int linea = e.getLocation().getLineNumber();
try {
String mensaje1 = e.getMessage().substring(39,55);
String mensaje2 = e.getMessage().substring(40,56);
- 111 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
String mensaje3 = e.getMessage().substring(41,57);
String mensaje4 = e.getMessage().substring(42,58);
String tet = "The element type";
String cna = "Content is not a";
if(mensaje1.equals(tet) || mensaje2.equals(tet) ||
mensaje3.equals(tet) || mensaje4.equals(tet)){
throw new BadLocationException("Problema",0);
}
else if(mensaje1.equals(cna) || mensaje2.equals(cna) ||
mensaje3.equals(cna) || mensaje4.equals(cna)){
/* Para diferenciar el error "content is not allowed
* in prolog/in trailing section". Sólo en el 2º caso
* hay que aumentar en uno la variable linea. */
mensaje1 = e.getMessage().substring(39,72);
mensaje2 = e.getMessage().substring(40,56);
mensaje3 = e.getMessage().substring(41,57);
mensaje4 = e.getMessage().substring(42,58);
String trailing = "Content is not allowed in trailin";
if(mensaje1.equals(trailing) ||mensaje2.
equals(trailing) ||
mensaje3.equals(
trailing) || mensaje4.equals(trailing)){
linea ++;
}
}
RandomAccessFile raf =
new RandomAccessFile(file, "r");
String cadena;
int i = 1;
int offset = 0;
while (i<linea-1){
cadena = raf.readLine();
i++;
offset = (int)raf.getFilePointer();
}
while((cadena = raf.readLine()) != null){
cadena = cadena + "\n";
codeDoc.insertString(offset,cadena,normal);
offset += cadena.length();
}
codeDoc.remove(offset,codeDoc.getLength()-offset);
} catch (IOException e1){
e1.printStackTrace();
}catch (BadLocationException e2) {
e2.printStackTrace();
- 112 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* EXPLICACIÓN DE ESTE NUEVO TRY-CATCH:
* Cuando se produce una excepción por una instrucción
* de procesamiento o un comentario NO CERRADOS
* (NOTA: si no tienen el símbolo de apertura el editor
* lo toma como texto plano y no existe excepción!),
* depende de la posición en que esté este fallo funciona
* o no el código escrito hasta este punto.
* Esto se debe a que la linea que produce la excepción es
* el último punto del archivo. Si coincide que nuestra PI o
* comentario estaba en la linea anterior no hay problema.
* Sin embargo, si está antes, al intentar insertar en un
* número de línea incorrecto, se produce una Bad
* Location Exception y no se inserta el texto. En dicho
* caso, lo que haremos es el código que se muestra a
* continuación: Simplemente, se quita todo lo que se ha
* insertado hasta el momento, y se inserta todo de nuevo,
* pero en negro.*/
try{
codeDoc.remove(0,codeDoc.getLength());
RandomAccessFile raf2 =
new RandomAccessFile(file, "r");
String aux;
int posicion = 0;
while((aux = raf2.readLine()) != null){
aux = aux + "\n";
codeDoc.insertString(posicion,aux,normal);
posicion += aux.length();
}
}catch(Exception ex) {
ex.printStackTrace();
}
}
/* Repetimos todo lo que hacemos tras END_DOCUMENT*/
/* Miramos antes que el árbol no sea null. */
/* If añadido por la excepción de empezar un archivo
* con un espacio en blanco. En dicho caso, el prefijo
* será null (otra condición añadida en CodeDocument.
* inicializar_valores_tras_leer() sobre este caso) y
* otra en la linea 515 de este mismo archivo, ya que
* en este caso, treeModel será también null, pues no
* hemos inicializado nada. */
if(arbol != null)
expandTree(arbol);
codeDoc.leer=false;
if(!refresh)
- 113 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
inicializar_valores_tras_leer();
else
/* En caso de que estuviésemos refrescando y se produzca
* esta excepción,¡es FUNDAMENTAL volver a apuntar
* al fichero original!¡Pero cuidado! Hay que hacerlo
* después de haber creado el RandomAccesFile que
* apunte a config_refresh_new.txt ya que es ahí donde
* hemos escrito el texto tomado del JEditorPane. Es más,
* lo situamos después del segundo RandomAccesFile que
* podríamos llegar a crear (segundo catch para
* excepciones), ya que si tenemos que crear ese segundo
* RandomAccesFile, entonces se plantea el mismo caso
* explicado anteriormente. Igual que antes, sólo se
* hace esto si no es nuevo. */
if(!isNew)
file = file_aux;
}catch(IOException e){
System.err.println("IOException"+e.getMessage());
}catch(BadLocationException ble){
/* Esta Excepción es para el método insertString: */
System.err.println("BadLocationException"+ble.getMessage());}
}
/* Método utilizado para leer un archivo que es nuevo (creado con el
* método newFile()de Inicial. Se utiliza el archivo de configuración
* config_new.txt para la creación y después se apunta al fichero
* config_refresh.txt, por si hay que refrescar. */
/** Método utilizado para leer un archivo nuevo (no abierto desde fichero). */
public void leerNuevo(){
file = new File("./config_new.txt");
leer();
/* Cambiamos al fichero auxiliar de configuración config_refresh_new.
* Utilidad de este fichero: para la función refrescar. Esta función
* toma todo el texto que hay en el JEditorPane, lo reescribe en el
* file, y lo vuelve a leer para que se refresque. El problema con new
* era que file quedaba apuntando a config_new, y al refrescar SE
* ESCRIBÍA EN ESTE FICHERO, y este fichero no puede ser
* modificado, ya que si no, al volverlo a leer para crear un nuevo
* fichero, habría cambiado. Con los no_nuevos, mismo problema, al
* refrescar quedaba lo nuevo escrito en el fichero sin que el usuario
* lo confirmase. Es por esto que se utiliza este fichero auxiliar en
* ambos casos. */
- 114 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
file = file_refresh;
}
/** Método que realiza las acciones necesarias para refrescar */
/* (antes de llamar al método leer()). */
public void refrescar(){
try{
refresh = true;
str=codeDoc.getText(0,codeDoc.getLength());
codeDoc.remove(0,codeDoc.getLength());
}catch(BadLocationException e){
System.err.println("BadLocationException"+e.getMessage());
}
leer();
refresh = false;
}
/* ****************************************************** */
/* ********** PALABRAS CLAVE Y DOCUMENT *********** */
/* ****************************************************** */
/** Método que inicializa el vector de palabras clave y establece el
* elemento codeDoc como Documento asodiado a este panel de texto.*/
public void inicializar_documento(){
codeDoc.setKeywords(keywords);
this.setDocument(codeDoc);
}
/** Método que añade los elementos al vector de palabras clave. Las
* palabras están compuestas por el prefijo del espacio de nombres
* de XML Schema y la palabra clave de XML Schema.
* @param prefix Prefijo del espacio de nombres XML Schema. */
public void add_palabras_prefijo(String prefix){
/* No inicializamos el vector con valores hasta que tengamos el prefijo.
* Esto es porque antes, localizabamos la palabra clave, y en el metodo
* insertKeyWord le añadíamos el prefijo. Esto funcionaba bien si
* habíamos escrito por ejemplo xsd:element. Sin embargo, si escribimos
* element o xs:element también lo sustituia, añadiendole el prefijo
- 115 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
* pero con el problema que los calculos de posiciones eran invalidos ya
* que no eran el numero de letras esperados y el resultado no era
* correcto. Ahora, hasta que no se tenga el elemento completo (prefijo +
* palabra_clave) y correcto (bien escrito) no se cambiará de color. */
String s = prefix + ":";
/* Palabras del lenguaje XML Schema obtenidas: del documento
* "Esquema del Esquema". */
keywords.addElement(s + "all");
keywords.addElement(s + "annotation");
keywords.addElement(s + "any");
keywords.addElement(s + "anyAttribute");
keywords.addElement(s + "appinfo");
keywords.addElement(s + "attribute");
keywords.addElement(s + "attributeGroup");
keywords.addElement(s + "choice");
keywords.addElement(s + "complexContent");
keywords.addElement(s + "complexType");
keywords.addElement(s + "documentation");
keywords.addElement(s + "element");
keywords.addElement(s + "extension");
keywords.addElement(s + "field");
keywords.addElement(s + "group");
keywords.addElement(s + "import");
keywords.addElement(s + "include");
keywords.addElement(s + "key");
keywords.addElement(s + "keyref");
keywords.addElement(s + "list");
keywords.addElement(s + "notation");
keywords.addElement(s + "redefine");
keywords.addElement(s + "restriction");
keywords.addElement(s + "schema");
keywords.addElement(s + "selector");
keywords.addElement(s + "sequence");
keywords.addElement(s + "simpleContent");
keywords.addElement(s + "simpleType");
keywords.addElement(s + "unique");
keywords.addElement(s + "union");
/* Los siguientes no vienen en dicho documento, sin embargo
* son importantes y necesarios. Obtenidos de la explicación
* de XMLSchema de la memoria del proyecto.*/
keywords.addElement(s + "pattern");
keywords.addElement(s + "maxInclusive");
keywords.addElement(s + "minInclusive");
keywords.addElement(s + "maxExclusive");
keywords.addElement(s + "minExclusive");
keywords.addElement(s + "precision");
keywords.addElement(s + "scale");
keywords.addElement(s + "lenght");
- 116 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
keywords.addElement(s + "maxLenght");
keywords.addElement(s + "minLenght");
keywords.addElement(s + "enumeration");
}
/** Método para inicializar los valores que reconocerá
* la herramienta como "palabras clave". */
/* Si tenemos prefijo != null llama al método añadir_palabras_prefijo().*/
public void inicializar_valores_tras_leer(){
if(prefijo != null){
add_palabras_prefijo(prefijo);
}
}
/* ****************************************************** */
/* ************* TRATAMIENTO DEL ÁRBOL ************** */
/* ****************************************************** */
/** Método que inicializa el árbol que contiene
* la estructura asociada a un esquema.
* @param top Nodo raíz del árbol. */
public void inicializar_arbol(DefaultMutableTreeNode top){
treeModel = new DefaultTreeModel(top);
arbol = new JTree(treeModel);
arbol.getSelectionModel().setSelectionMode
(TreeSelectionModel.SINGLE_TREE_SELECTION);
}
/** Método que muestra un árbol expandido a partir del componente JTree. */
public static void expandTree(JTree tree){
TreeNode root = (TreeNode)tree.getModel().getRoot();
TreePath path = new TreePath(root);
for(int k = 0; k<root.getChildCount(); k++){
TreeNode child = (TreeNode)root.getChildAt(k);
expandTree(tree, path, child);
}
}
- 117 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/** Método que muestra un árbol expandido a partir del componente JTree. */
public static void expandTree(JTree tree, TreePath path, TreeNode node){
if (path==null || node==null)
return;
tree.expandPath(path);
TreePath newPath = path.pathByAddingChild(node);
for(int k = 0; k<node.getChildCount(); k++){
TreeNode child = (TreeNode)node.getChildAt(k);
if(child!=null)
expandTree(tree, newPath, child);
}
}
/* ****************************************************** */
/* ******* INSERTAR ELEMENTOS EN EL ESQUEMA ******* */
/* ****************************************************** */
/** Método que calcula el punto de inserción de los elementos.
* Este punto será la posición del cursor.*/
public void actualizar_pto_insercion(){
pto_insercion = caret.getDot();
}
/** Método que inserta un elemento Annotation en el esquema. */
public void addAnnotation(String text, String option,
String language, boolean llamado){
codeDoc.leer=true;
actualizar_pto_insercion();
String s;
String insertar = "annotation";
boolean seguir = true;
/* El booleano llamado se utiliza para actualizar cuenta_tab. Si
* sólo estamos añadiendo un elemento annotation a nuestro
* Documento, cuenta_tab valdrá -1. En caso contrario, es decir,si
* añadimos un elemento annotation dentro de otro elemento,
* cuenta_tab valdrá uno más de lo que valiese para el otro elemento.*/
if (llamado == false)
cuenta_tab = 1;
else
cuenta_tab++;
- 118 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
try{
/* Etiqueta de apertura annotation*/
while(seguir){
if(!insertar.equals("annotation")){
seguir = false;
}
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + insertar;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
if(seguir == false && language != null){
s =espacio + lengua;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + language + comilla;
codeDoc.insertString(
pto_insercion,s,valorAtributo);
pto_insercion += s.length();
}
s = mayor +rc ;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
if(insertar.equals("annotation"))
cuenta_tab++;
insertar = option;
}
/* Texto */
s = text;
codeDoc.insertString(pto_insercion-1,s,normal);
pto_insercion += s.length();
/*Etiquetas de cierre */
s = menor + cierre;
codeDoc.insertString(pto_insercion-1,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + insertar;
codeDoc.insertString(pto_insercion-1,s,etiqueta);
- 119 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
pto_insercion += s.length();
s = mayor;
codeDoc.insertString(pto_insercion-1,s,apertura);
pto_insercion += s.length();
cuenta_tab--;
insertar = "annotation";
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor + cierre;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + insertar;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
s = mayor +rc ;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
cuenta_tab--;
/* Sólo en este caso pondremos la variable codeDoc.leer
* a false; En caso contrario seguiremos añadiendo
* elementos, por tanto leer debe seguir a true. */
if(!llamado){
codeDoc.leer=false;
}
}catch(BadLocationException ble){
System.err.println("BadLocationException"+ble.getMessage());
}
}
/** Método que inserta un elemento Attribute en el esquema. */
public void addAttribute(String name, String type, String id, String
use,String value, boolean annotation, String text, String option,
String language){
codeDoc.leer=true;
actualizar_pto_insercion();
cuenta_tab = 1;
String s;
String att = "attribute";
try{
- 120 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* Etiqueta de apertura insert */
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + att;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
/* Añadimos el nombre (OBLIGATORIO). */
s =espacio + "name" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + name + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
/* Añadimos el tipo (OBLIGATORIO). */
s =espacio + "type" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + type + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
/* Los otros campos pueden estar o no. */
if(!id.equals("")){
s =espacio + "id" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + id + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
}
if(!use.equals("")){
s =espacio + "use" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + use + comilla;
- 121 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
}
if(!value.equals("")){
s =espacio + "value" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + value + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
}
if (!annotation){
/*Si no hay annotation, cierro el atributo directamente*/
s = cierre + mayor + rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
else{
s = mayor + rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
addAnnotation(text, option, language, true);
/*Etiqueta de cierre para attribute */
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor + cierre;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + att;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
s = mayor +rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
}
}catch(BadLocationException ble){
System.out.println("BadLocationException"+ble.getMessage());
}
- 122 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
codeDoc.leer=false;
}
/** Método que inserta un elemento AttributeGroup en el esquema. */
/* NO IMPLEMENTADO. LINEAS FUTURAS. */
public void addAttributeGroup(){
}
/** Método que inserta un elemento Import en el esquema. */
public void addImport(String id, String namesp, String schemaLocation,
boolean annotation, String text, String option, String language){
codeDoc.leer=true;
actualizar_pto_insercion();
cuenta_tab = 1;
String s;
String importar = "import";
try{
/* Etiqueta de apertura import */
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + importar;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
if(!id.equals("")){
s =espacio + "id" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + id + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
- 123 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
}
if(!namesp.equals("")){
s =espacio + "namespace" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + namesp + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
}
if(!schemaLocation.equals("")){
s =espacio + "schemaLocation" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + schemaLocation + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
}
if (!annotation){
/*Si no hay annotation, cierro import directamente*/
s = cierre + mayor + rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
else{
s = mayor + rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
addAnnotation(text, option, language, true);
/*Etiqueta de cierre para import*/
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor + cierre;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + importar;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
- 124 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
s = mayor +rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
}
}catch(BadLocationException ble){
System.err.println("BadLocationException"+ble.getMessage());
}
codeDoc.leer=false;
}
/** Método que inserta un elemento Include en el esquema. */
public void addInclude(String id, String schemaLocation, boolean
annotation,String text, String option, String language){
codeDoc.leer=true;
actualizar_pto_insercion();
cuenta_tab = 1;
String s;
String incluir = "include";
try{
/* Etiqueta de apertura include */
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + incluir;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
if(!id.equals("")){
s =espacio + "id" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + id + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
}
- 125 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
/* No es necesario ver si schemaLocation está vacío
* ya que hemos obligado a que rellenen el campo. */
s =espacio + "schemaLocation" + igual;
codeDoc.insertString(pto_insercion,s,atributo);
pto_insercion += s.length();
s = comilla + schemaLocation + comilla;
codeDoc.insertString(pto_insercion,s,valorAtributo);
pto_insercion += s.length();
if (!annotation){
/*Si no hay annotation, cierro include directamente*/
s = cierre + mayor + rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
else{
s = mayor + rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
addAnnotation(text, option, language, true);
/*Etiqueta de cierre para include */
s = tabulador;
for (int i=0; i<cuenta_tab; i++){
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion+=s.length();
}
s = menor + cierre;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
s = prefijo + dosp + incluir;
codeDoc.insertString(pto_insercion,s,etiqueta);
pto_insercion += s.length();
s = mayor +rc;
codeDoc.insertString(pto_insercion,s,apertura);
pto_insercion += s.length();
}
}catch(BadLocationException ble){
System.err.println("BadLocationException"+ble.getMessage());
}
codeDoc.leer=false;
}
}
- 126 -
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
MyUndoableEditListener.java
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
/** Clase que escucha las ediciones que pueden ser deshechas.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
class MyUndoableEditListener implements UndoableEditListener {
Inicial inicial;
/** Constructor de la clase. */
MyUndoableEditListener(Inicial in){
inicial = in;
}
/** Método que recuerda la edición y actualiza los menús. */
public void undoableEditHappened(UndoableEditEvent e) {
inicial.undo.addEdit(e.getEdit());
inicial.undoAction.update();
inicial.redoAction.update();
}
}
- 127 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
PopupListener.java
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JPopupMenu;
/** Clase que escucha los eventos de ratón para mostrar un JPopup menú si el
* botón correspondiente del ratón es pulsado en la posición adecuada.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
class PopupListener extends MouseAdapter {
JPopupMenu jpum;
/** Constructor de la clase. */
PopupListener(JPopupMenu j) {
jpum = j;
}
/* Ejecutado cuando se pulsa un botón del ratón.
* Hereda comentario de documentación. */
public void mousePressed(MouseEvent e) {
maybeShowPopup(e);
}
/* Ejecutado cuando se suelta un botón del ratón.
* Hereda comentario de documentación. */
public void mouseReleased(MouseEvent e) {
maybeShowPopup(e);
}
- 128 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
/** Muestra el PopupMenú si se pulsó el botón
* correspondiente en el lugar adecuado. */
public void maybeShowPopup(MouseEvent e) {
if (e.isPopupTrigger()) {
jpum.show(e.getComponent(), e.getX(), e.getY());
}
}
}
- 129 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
RedoAction.java
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.UndoManager;
/** Clase que implementa la acción Rehacer.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class RedoAction extends AbstractAction {
UndoManager undo;
UndoAction undoAction;
/** Constructor de la clase. */
public RedoAction(UndoManager um) {
super("Redo");
undo = um;
putValue(Action.NAME, "Redo");
setEnabled(false);
}
/** Método que asocia un UndoAction a este RedoAction. */
public void setUndoAction(UndoAction ua){
undoAction = ua;
}
/* Hereda comentario de documentación. */
public void actionPerformed(ActionEvent e) {
try {
undo.redo();
} catch (CannotRedoException ex) {
System.err.println("Unable to redo: " + ex);
ex.printStackTrace();
}
update();
- 130 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
undoAction.update();
}
/** Método que activa o desactiva el item de menú correspondiente. */
protected void update() {
if (undo.canRedo()) {
setEnabled(true);
} else {
setEnabled(false);
}
}
}
- 131 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
TabListener.java
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/** Clase que escucha los cambios de pestaña.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class TabListener implements ChangeListener {
Inicial i;
JSplitPane split;
JScrollPane jsp;
MyJEditorPane jep;
String filename;
/** Constructor de la clase. */
TabListener(Inicial ini) {
i = ini;
}
/** Método disparado cuando se cambia el estado de las pestañas. */
public void stateChanged(ChangeEvent e) {
if (!i.nuevo && !i.abriendo && !i.cerrando) {
split = (JSplitPane) i.pestana.getSelectedComponent();
jsp = (JScrollPane)split.getLeftComponent();
jep = (MyJEditorPane) jsp.getComponent(0).
getComponentAt(0, 0);
i.setUndoableMenu(jep);
}
}
}
- 132 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
TextFieldAL.java
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
/** Clase que escucha las acciones que se realicen sobre los
* campos de texto de las diferentes clases que producen
* cuadros de diálogo (Import,Annotation, etc).
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
public class TextFieldAL implements ActionListener {
JOptionPane jop;
final String btnString1 = "Enter";
/** Constructor de la clase. */
TextFieldAL(JOptionPane option){
jop = option;
}
/* Se ejecuta cuando se pulsa intro y tenemos
* el cursor dentro de un campo de texto.
* Hereda comentario de documentación. */
public void actionPerformed(ActionEvent e) {
jop.setValue(btnString1);
}
}
- 133 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
UndoAction.java
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;
/** Clase que implementa la acción Deshacer.
* @author Mª del Pilar Jiménez Guijarro.
* @version 1.0 */
class UndoAction extends AbstractAction {
UndoManager undo;
RedoAction redoAction;
/** Constructor de la clase. */
public UndoAction(UndoManager um) {
super("Undo");
putValue(Action.NAME, "Undo");
setEnabled(false);
undo = um;
}
/** Método que asocia un RedoAction a este UndoAction. */
public void setRedoAction(RedoAction ra){
redoAction = ra;
}
/* Hereda comentario de documentación. */
public void actionPerformed(ActionEvent e) {
try {
undo.undo();
} catch (CannotUndoException ex) {
System.err.println("Unable to undo: " + ex);
- 134 -
Código.
Implementación en el Lenguaje Java de una Herramienta de edición para XML Schema.
Código.
ex.printStackTrace();
}
update();
redoAction.update();
}
/** Método que activa o desactiva el item de menú correspondiente. */
protected void update() {
if (undo.canUndo()) {
setEnabled(true);
/* putValue(Action.NAME, undo.getUndoPresentationName());
* undo.getUndoPresentationName() devolvia, o bien "deshacer
* adición", o bien "deshacer cambio estilo", en castellano.
* La he quitado para mantener toda la interfaz en inglés.
* (Igual ocurre en Redo). Al final, en vez de asignar el
* nombre dentro de la función update, lo he sacado al
* constructor, ya que en update tiene sentido asignar el
* nombre si tengo distintos nombres para distintas funciones
* (por ejemplo, lo explicado arriba: puedo tener deshacer o
* cambio de estilo), pero en mi implementación sólo tendré
* como nombre Undo, nhe decidido que no haya opción de
* cambio en el nombre. */
} else {
setEnabled(false);
}
}
}
- 135 -
Descargar