Bienvenidos a todos, ¿qué tal? Este post va a
consistir en la creación de un procesador de textos, no va a ser como LibreOffice Writer o Microsoft Word va a ser más básico pero
en el que apliquemos conceptos ya aprendidos. En este procesador va a ser muy
rudimentario pero vosotros podéis añadir nuevas funcionalidades, cambiar la interfaz, etc., y si luego encima
lo queréis compartir pues vamos, mejor de lo mejor. Así que vamos a empezar con
el proyecto.
El procesador de texto va a consistir en la parte
superior tres menús: Fuente Estilo
Tamaño con los submenús respectivos: Arial
Courier y Verdana Cursiva Negrita 12 16 18 20 En parte inferior un área de
texto con el cursor parpadeando para poder escribir. Escribimos cualquier frase
y podemos cambiar la fuente, el estilo, el tamaño…
Sería recomendable antes de que siguierais leyendo
probad a realizarlo vosotros solos, no obstante, explico paso a paso la
creación de este procesador de texto que a su vez lo iremos mejorando.
Para empezar nos creamos un proyecto nuevo en Java al
que vamos a llamar ProcesadorTexto,
nos creamos un paquete prtxt, dentro
de este paquete nos creamos la clase Procesador
que va a contener el siguiente código:
package prtxt;
import
javax.swing.JFrame;
import
javax.swing.JPanel;
public class Procesador {
public static void main(String[] args) {
MenuProcesador
mimenu = new
MenuProcesador();
mimenu.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class MenuProcesador
extends JFrame {
public
MenuProcesador() {
setBounds(500,300,550,400);
LaminaProcesador
milamina = new
LaminaProcesador();
add(milamina);
setVisible(true);
}
}
class LaminaProcesador
extends JPanel{
public
LaminaProcesador() {
}
}
Lo primero hay que fijarnos en la distribución en la
parte superior va a ir la barra de menús y en la parte inferior el área de
texto. En este caso vamos a utilizar el setLayout
BorderLayout. En el constructor de
la lámina nos creamos la disposición:
public
LaminaProcesador() {
setLayout(new
BorderLayout());
}
Nos creamos una segunda lámina:
JPanel
LaminaMenu = new JPanel();
El siguiente paso es crear la barra de menús :
JMenuBar
mibarra
= new
JMenuBar();
Tenemos que determinar que elementos va a contener
esta barra, creamos los menús:
JMenu
fuente = new JMenu("Fuente");
JMenu
estilo = new JMenu("Estilo");
JMenu tamano
= new JMenu("Tamaño");
Agregamos los menús a la barra de menús:
mibarra.add(fuente);
mibarra.add(estilo);
mibarra.add(tamano);
Tenemos que añadir la barra de menús a la lámina que
va en la parte superior, esa lámina es la segunda lámina.
LaminaMenu.add(mibarra);
Tenemos que indicar que la segunda lámina con su
correspondiente barra de menús va en la parte superior de la lámina principal:
add(LaminaMenu, BorderLayout.NORTH);
Lo siguiente sería crear los elementos que cuelgan de
los menús, es decir, los submenús. Después de los elementos JMenu vamos a crearnos los submenús
para ello utilizamos la clase JMenuItem:
JMenuItem arial = new JMenuItem("Arial");
JMenuItem courier = new JMenuItem("Courier");
JMenuItem
verdana = new
JMenuItem("Verdana");
Posteriormente añadimos los submenús al menú:
fuente.add(arial);
fuente.add(courier);
fuente.add(verdana);
Y haríamos lo mismo con los submenús del menú Edición y el menú Tamaño:
JMenuItem
negrita = new JMenuItem("Negrita");
JMenuItem
cursiva = new JMenuItem("Cursiva");
estilo.add(negrita);
estilo.add(cursiva);
JMenuItem
tam_12 = new JMenuItem("12");
JMenuItem
tam_16 = new JMenuItem("16");
JMenuItem
tam_20 = new JMenuItem("20");
JMenuItem
tam_24 = new JMenuItem("24");
tamano.add(tam_12);
tamano.add(tam_16);
tamano.add(tam_20);
tamano.add(tam_24);
Con esto ya tendríamos la barra de menús:
El siguiente paso es crear el área de texto y para
ello vamos a utilizar la clase JTextPane
que nos permite añadir barras de desplazamiento y modificar texto a diferencia
de la clase JTextArea.
Nos situamos después de la línea de código:
add(LaminaMenu, BorderLayout.NORTH);
Creamos un objeto de tipo JTextPane y lo ubicamos en la parte
central de la lámina principal:
JTextPane miarea = new JTextPane();
add(miarea,
BorderLayout.CENTER);
Con esto ya tendríamos el área de texto creada donde poder escribir:
Ahora tenemos que indicar a cada uno de los elementos
que cuelgan de los menús tenemos que ponerlos a la escucha de un evento de tipo
actionListener para que cuando
pulsemos en uno de los elementos con el ratón vaya cambiando las
características del texto que hay escrito. Vamos a empezar con este elemento:
JMenuItem
courier = new JMenuItem("Courier");
De forma que al pulsar el submenú Courier se desencadene el evento y el evento va a ser que el texto
cambie el tipo de letra a Courier.
Nos creamos una clase interna que gestione los eventos
para el elemento Courier. Después del
constructor de la lámina nos creamos la clase:
private class GestionaMenus
implements ActionListener
{
@Override
public void
actionPerformed(ActionEvent e) {
// TODO
Auto-generated method stub
}
}
Dentro del método actionPerformed
vamos a programar el evento del elemento Courier.
private class GestionaMenus
implements ActionListener
{
@Override
public void
actionPerformed(ActionEvent e) {
miarea.setFont(new Font("Courier", Font.PLAIN, 12 ));
}
}
En el constructor de la lámina después de la línea de
código hemos declarado el elemento Courier
instanciamos el elemento:
GestionaMenus
tipo_letra = new
GestionaMenus();
courier.add(courier);
En lugar de utilizar la clase interna podemos utilizar
una clase anónima de la siguiente forma:
courier.addActionListener(new
ActionListener() {
@Override
public void
actionPerformed(ActionEvent e) {
miarea.setFont(new Font("Courier", Font.PLAIN, 12 ));
}
});
Eliminamos la clase interna.
Con los siguientes elementos Arial y Verdana hacemos
lo mismo, creamos una clase anónima para cada uno de ellos:
JMenuItem
arial = new JMenuItem("Arial");
arial.addActionListener(new
ActionListener() { //Clase anónima. Nos crea el evento
para convertir el tipo de letra a Courier
@Override
public void
actionPerformed(ActionEvent e) {
miarea.setFont(new Font("Arial", Font.PLAIN, 12 ));
}
});
JMenuItem
verdana = new JMenuItem("Verdana");
verdana.addActionListener(new
ActionListener() { //Clase anónima. Nos crea el evento
para convertir el tipo de letra a Courier
@Override
public void
actionPerformed(ActionEvent e) {
miarea.setFont(new Font("Verdana", Font.PLAIN, 12 ));
}
});
Sin embargo, tal y como tenemos planteado el código si
tenemos que crear una clase interna por cada uno de los elementos que nos
quedan nos va a quedar un código muy extenso, para evitar que haya tanto código
se podía plantear de otra forma.
Lo primero sería eliminar todos los submenús que hemos
creado en el constructor de la lámina dejarlo de la siguiente forma:
public
LaminaProcesador() {
setLayout(new
BorderLayout());
JPanel
LaminaMenu = new JPanel();
JMenuBar
mibarra = new JMenuBar();
//Creación
de los menús
JMenu
fuente = new JMenu("Fuente");
JMenu
estilo = new JMenu("Estilo");
JMenu
tamano = new JMenu("Tamaño");
mibarra.add(fuente);
mibarra.add(estilo);
mibarra.add(tamano);
LaminaMenu.add(mibarra);
add(LaminaMenu, BorderLayout.NORTH);
miarea = new JTextPane();
add(miarea, BorderLayout.CENTER);
}
Declarar las variables de clase de los menús van al
final de la última llave de cierre de código:
JTextPane
miarea; //Objeto
del área de texto
JMenu
fuente, estilo, tamano; //creamos
los menús
Font letras;
Y en el constructor de la lámina ya no es necesario
declarar los menús:
JMenu
fuente = new JMenu("Fuente");
JMenu
estilo = new JMenu("Estilo");
JMenu tamano
= new JMenu("Tamaño");
Luego nos creamos un método que ponga los elementos a
la escucha y a la misma vez construir los elementos, el método lo creamos
después del constructor de la lámina:
public void ConfiguraMenu (String rotulo, String
menu, String tipo_letra, int estilos, int tam) {
}
A este método le pasamos una serie de parámetros: rotulo que va a servir para especificar
el texto que va a tener el menú que estemos construyendo en cada momento, por
ejemplo, si es Arial, Courier, si va a tener negrita o cursiva, si el tamaño va
a tener 20 o 25, el segundo parámetro Menu
se va a encargar de especificar si el elemento que estamos creando en cada
momento a que menú tiene que ir, por ejemplo, si al menú fuente, al menú
estilos, el tercer parámetro tipo_letra
se va a encargar de los elementos que cuelgan del menú Fuente especificar el
tipo de letra, el cuarto parámetro estilos
especificar si el texto va a ir en negrita o en cursiva y el último parámetro
especificiar el tamaño del texto si va a tener 12, 20…
Con esto empezamos a crearnos los submenús
instanciamos la clase JMenuItem :
JMenuItem
submenus
= new
JMenuItem(rotulo);
Mediante un condicional especificamos donde han de ir
los elementos:
JMenuItem
submenus = new JMenuItem(rotulo);
if(menu=="fuente") {
fuente.add(submenus);
}else if(menu=="estilo") {
estilo.add(submenus);
}else if(menu=="tamano") {
tamano.add(submenus);
}
Ahora en el constructor de la lámina después de la
creación de los menús creamos cada uno de los JMenuItems
ConfiguraMenu("Arial", "fuente", "", 1,1);
ConfiguraMenu("Courier", "fuente", "", 1,1);
ConfiguraMenu("Verdana",
"fuente", "",
1,1);
Para los estilos:
ConfiguraMenu("Negrita", "estilo", "", 1,1);
ConfiguraMenu("Cursiva",
"estilo", "",
1,1);
Para el tamaño:
ConfiguraMenu("12", "tamano", "", 1,1);
ConfiguraMenu("16", "tamano", "", 1,1);
ConfiguraMenu("20", "tamano", "", 1,1);
ConfiguraMenu("24",
"tamano", "",
1,1);
Con esto ya tendríamos creamos todos los submenús.
Creamos una clase interna que gestione los eventos
estos submenús, después de la llave de cierre del método creamos la clase:
private class GestionaEventos implements ActionListener{
@Override
public void
actionPerformed(ActionEvent e) {
// TODO
Auto-generated method stub
}
}
Dentro del método le vamos a indicar que cambie el
tipo de letra:
public void
actionPerformed(ActionEvent e) {
miarea.setFont(new Font("Arial", Font.BOLD, 14));
}
Sin embargo, aquí hay un inconveniente ya que al
constructor de setFont le hemos
pasado valores fijos de forma que si lo dejamos así cuando pulsemos en
cualquier submenú nos va a poner el texto en Arial, negrita y un tamaño de 14.
De alguna forma tenemos que sustituir estos valores por tres variables que
vayan cambiando dependiente del submenú que seleccionemos. Para ello dentro de
la clase interna antes del método nos creamos las variables:
private class GestionaEventos
implements ActionListener{
String tipo_texto,
menu;
int estilo_letra, tamano_letra;
@Override
public void
actionPerformed(ActionEvent e) {
miarea.setFont(new Font("Arial", Font.BOLD, 14));
}
}
Sustituimos los valores fijos por las variables:
public void
actionPerformed(ActionEvent e) {
miarea.setFont(new Font(tipo_texto, estilo_letra, tamano_letra));
}
Tenemos que almacenar estas variables el tipo
de letra, el estilo, el tamaño del menú correspondiente, es decir, necesitamos
pasar los valores de la clase padre a la clase hijo, para ello vamos a utilizar
el constructor de la clase interna que gestiona eventos. Después de las
variables nos creamos el constructor.
GestionaEventos(String
elemento, String texto2, int estilo2, int tam_letra){
}
Al constructor le pasamos una serie de
parámetros, el primer parámetro elemento que va a detectar el submenú que hemos
pulsado, el segundo parámetro texto2 va almacenar el texto del botón, otro
parámetro estilo2 que va almacenar el estilo que hayamos pulsado y otro
parámetro tam_letra que almacene el
tamaño de la letra.
En definitiva, este constructor va a detectar
que submenú hemos pulsado, evidentemente para pasar los parámetros al
constructor tenemos que hacer la llamada en la clase padre a este constructor
esto lo vamos a hacer en cuanto instanciemos la clase GestionaEventos que es la encargada de gestionar los eventos,
dentro del constructor vamos a darle valores a las variables:
GestionaEventos(String
elemento, String texto2, int estilo2, int tam_letra){
tipo_texto=texto2;
estilo_letra=estilo2;
tamano_letra=tam_letra;
menu=elemento;
}
Lo que vamos a hacer es instanciar la clase GestionaEventos, para ello nos vamos al
método ConfiguraMenu antes de la
llave de cierre:
submenus.addActionListener(new
GestionaEventos(rotulo, tipo_letra, estilos, tam));
Y le pasamos como parámetros los parámetros
del método.
Vamos al constructor de la lámina y en la
llamada a la clase ConfiguraMenu
hacemos lo siguiente para el tipo de letra:
ConfiguraMenu("Arial", "fuente", "Arial", 9,10);
ConfiguraMenu("Courier", "fuente", "Courier", 9,10);
ConfiguraMenu("Verdana",
"fuente", "Verdana",
9,10);
Solo se va a encargar de cambiar el tipo de
letra, los valores 9 y 10 son de ejemplo, no hacen nada. Para el estilo:
ConfiguraMenu("Negrita", "estilo", "", Font.BOLD,1);
ConfiguraMenu("Cursiva",
"estilo", "",
Font.ITALIC,1);
Para el tamaño:
ConfiguraMenu("12", "tamano", "", 1,12);
ConfiguraMenu("16", "tamano", "", 1,16);
ConfiguraMenu("20", "tamano", "", 1,20);
ConfiguraMenu("24",
"tamano", "",
1,24);
Tenemos que detectar el submenú que pulsamos
y que cambié el texto solo con la característica correspondiente del submenú,
es decir, si pulsamos el tipo de texto Courier que solo modifique el tipo de
texto, el estilo y el tamaño lo deje como esta.
Dentro del método actionPerformed tenemos que capturar el texto que escribimos para
darle un tipo de texto, por ello ya nos creamos en su momento y una variable de
clase llamada letras:
Font
letras;
Capturamos el texto que hay en el área de
texto:
public void
actionPerformed(ActionEvent e) {
letras=miarea.getFont();
miarea.setFont(new Font(tipo_texto, estilo_letra, tamano_letra));
}
Con esto lo que conseguimos es almacenar en
la variable letras el tipo de letra, el estilo y el tamaño seleccionado.
Para seleccionar cada uno de los elementos
tenemos que utilizar varios métodos de la clase Font. Empezamos con el tipo de letra, mediante un condicional le
vamos a indicar que si seleccionamos cualquier submenú Arial, Courier o Verdana
el estilo y el tamaño nos los deje tal y como está:
public void
actionPerformed(ActionEvent e) {
letras=miarea.getFont();
if(menu=="Arial" || menu=="Courier" || menu=="Verdana") {
estilo_letra=letras.getStyle();
tamano_letra=letras.getSize();
}
miarea.setFont(new Font(tipo_texto, estilo_letra, tamano_letra));
}
Seguimos con el condicional para el estilo y
el tamaño:
public void
actionPerformed(ActionEvent e) {
letras=miarea.getFont();
if(menu=="Arial" || menu=="Courier" || menu=="Verdana") {
estilo_letra=letras.getStyle();
tamano_letra=letras.getSize();
}else if(menu=="Cursiva" || menu=="Negrita") {
if(letras.getStyle()==1
|| letras.getStyle()==2)
{
estilo_letra=3;
}
tipo_texto=letras.getFontName();
tamano_letra=letras.getSize();
}else if(menu=="12"
|| menu=="16"
|| menu=="20"
|| menu=="24")
{
tipo_texto=letras.getFontName();
estilo_letra=letras.getStyle();
}
Con esto ya estaría terminado, probamos:
Si seleccionamos el tipo de letra 20:
Cambiamos el estilo a Cursiva comprobamos que el tamaño y la fuente nos la mantiene igual:
Podemos mejorarlo si al seleccionar el tipo
de letra nos muestre en consola el tipo de letra que hemos seleccionado:
miarea.setFont(new Font(tipo_texto, estilo_letra, tamano_letra));
System.out.println("Tipo:
"+tipo_texto+"
Estilo: "+estilo_letra+"
Tamaño: "+tamano_letra);
Si probamos cambiamos al fuente:
Con esto ya tendríamos terminado el
procesador de textos, aun así es un procesador bastante básico tal y como lo
tenemos solo permite cambiar las características de todo el texto, si
seleccionamos parte del texto para que solo nos haga los cambios en el texto
seleccionado no lo va a tener en cuenta, va a seguir modificando todo el texto
que está en el área de texto. También el inconveniente que al seleccionar
cursiva o negrita ya no le podemos quitar está característica al texto.
Para solucionar estos inconveniente se
utiliza una clase StyledEditorKit()
que permite seleccionar parte del texto y cambiar las característica solo del
texto seleccionado y además permite quitar negrita y cursiva, es decir, si
pulsamos negrita el texto se convierte en negrita si volvemos a pulsar negrita
en el texto se elimina el estilo negrita.
Para utilizar esta clase tenemos que
modificar el código, lo primero es que nos sobra la clase interna por lo que la
eliminamos y también eliminamos la siguiente línea de código:
submenus.addActionListener(new GestionaEventos(rotulo, tipo_letra, estilos, tam));
Empezamos cambiando el tamaño del texto para
ello nos metemos dentro del método y en el bloque condicional referente al
tamaño escribimos lo siguiente:
else if(menu=="tamano") {
tamano.add(submenus);
submenus.addActionListener(new
StyledEditorKit.FontSizeAction("cambia_tamaño", tam));
}
Le pasamos dos parámetros, el segundo de
ellos es el mismo parámetro que el método. Para los estilos:
else if(menu=="estilo") {
estilo.add(submenus);
if(estilos==Font.BOLD) {
submenus.addActionListener(new
StyledEditorKit.BoldAction());
}else if (estilos==Font.ITALIC) {
submenus.addActionListener(new
StyledEditorKit.ItalicAction());
}
Para el tipo de texto:
if(menu=="fuente") {
fuente.add(submenus);
if(tipo_letra=="Arial") {
submenus.addActionListener(new
StyledEditorKit.FontFamilyAction("cambia_letra", "Arial"));
}else if(tipo_letra=="Courier") {
submenus.addActionListener(new
StyledEditorKit.FontFamilyAction("cambia_letra", "Courier"));
}else if(tipo_letra=="Verdana") {
submenus.addActionListener(new
StyledEditorKit.FontFamilyAction("cambia_letra", "Verdana"));
}
Si probamos, seleccionamos texto y modificamos el tipo de letra y el tamaño, solo se modifica el texto seleccionado:
Con esto ya estaría terminado el procesador
de textos, aquí os dejo el link con el código completo ya finalizado por si queréis
modificarlo, añadir nuevas funcionalidades… Con cualquier duda me lo podéis
hacer llegar a través de los comentarios del blog. Hasta pronto!
7.9 CREACIÓN DE MENÚS << >> 7.11MENÚ CON IMÁGENES
No hay comentarios:
Publicar un comentario