Download implementación en el lenguaje java de una herramienta de edición

Document related concepts
no text concepts found
Transcript
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 -