Nivel: Intermedio-Avanzado
IDE: Netbeans 6.9 o Sup.
Tiempo: 30 minutos
En este tutorial crearemos una aplicación que nos permita cargar una imagen desde el disco duro, y añadirle texto, este texto podremos editarlo, la aplicación tambien tendra la opcion de guardar nuestra imagen con el texto incorporado.
Este sera nuetro resultado final
Paso 1: Crear un nuevo proyecto en Nebeans (nombre: jc2dTexto), en el paquete que se crea por defecto, añade dos JFrames (interfaz.java , ventana_texto.java), añade tambien tres clases java (midibujo.java, mipanel.java, mitexto.java), crea tambien un nuevo paquete (images), debes tener algo como:
Paso 2: Ahora crearemos las interfaces para el proyecto, primero para la clase interfaz.java
Continuamos con la clase ventana_texto.java
En el objeto jComboBox jcFuente, añadimos manualmente algunos tipos de fuentes que se tengan en el sistema, por ejemplo:
Arial
Consolas
Times New Roman
Impact
Monotype Corsiva
Asi tambien en el jComboBox jcSize, se añaden algunos valores numericos para el tamaño de la fuente, por ejemplo: 10,14,16,18,69, etc
Recuerda que los nombres son importantes, debes crearlos tal y como estan en los dibujos.
Paso 3: Seguimos ahora con las clases.
Clase midibujo.java
Esta clase es la que contendra la imagen que cargaremos del disco duro, ademas de los textos que agreguemos en la imagen, esta clase hace uso de la clase mitexto.java, para almacenar los textos que se crean en la imagen, utiliza un ArrayList hace uso tambien de un DefaultListModel para actualizar los cambios que se hagan en la interfaz del usuario.
package jc2dtexto; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Image; import java.util.ArrayList; import java.util.Iterator; import javax.swing.DefaultListModel; /** * @web http://jc-mouse.blogspot.com/ * @author Mouse */ public class midibujo { private int texto_seleccionado = -1; //contenedor de los objetos "mitexto" private ArrayList ArrayTexto = new ArrayList(10); //para la imagen de fondo private Image foto; private Dimension size = new Dimension(1, 1); private DefaultListModel modelo; public midibujo() {} public void setFoto(Image f) { this.foto = f; this.size = new Dimension(f.getWidth(null), f.getHeight(null)); } public void setTexto(mitexto t) { this.ArrayTexto.add(t); this.modelo.addElement(t.getTexto()); } public mitexto getTexto(int i) { return (mitexto) ArrayTexto.get(i); } public void updateTexto(mitexto t, int id){ this.ArrayTexto.remove(id); this.ArrayTexto.add(t); this.modelo.remove(id); this.modelo.addElement(t.getTexto()); } public Dimension getSize() { return this.size; } public void pintar_dibujo(Graphics2D g2) { //pinta la imagen cargada en memoria g2.drawImage(foto, 0, 0, null); //pinta el texto, si tiene Iterator it = ArrayTexto.iterator(); while (it.hasNext()) { mitexto f = ((mitexto) it.next()); f.pintar_texto(g2); } } public void seleccionar_texto(int num) { this.texto_seleccionado = num; } public int get_texto_seleccionado() { return this.texto_seleccionado; } public void setModel(DefaultListModel m) { this.modelo = m; } }
Clase mipanel.java
Esta clase, que se extiende de un JPanel e implementa eventos del ratón, es el contenedor donde se pintara el resultado de midibujo.java asi como los diferentes textos que se vayan a crear. Los eventos del mouse se utilizan para capturar las coordenadas del cursor y pasarlas a las clases correspondientes.
package jc2dtexto; import java.awt.event.MouseEvent; import javax.swing.JPanel; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingHints; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; /** * @web http://jc-mouse.blogspot.com/ * @author Mouse */ public class mipanel extends JPanel implements MouseMotionListener,MouseListener { private BufferedImage Imagen_en_memoria; //imagen de fondo de cuadrados private Image fondo = new ImageIcon(getClass().getResource("/images/default.jpg")).getImage(); private mitexto texto; private midibujo tmpdibujo = null; //tamaño del contenedor private Dimension size = new Dimension(100,100); /* constructor que toma el tamaño por defecto 100x100*/ public mipanel(){ this.setPreferredSize( size ); this.setSize( size ); this.setVisible(true); addMouseMotionListener(this); addMouseListener(this); } /* constructor que toma el tamaño pasado como parametro*/ public mipanel(Dimension d){ this.setPreferredSize( d ); this.setSize( d ); this.setVisible(true); addMouseMotionListener(this); addMouseListener(this); } public void setDibujo(midibujo md){ this.tmpdibujo = md; this.repaint(); } public void resize(){ this.size = this.tmpdibujo.getSize(); this.setSize(size); this.setPreferredSize(size); this.repaint(); } public void setTexto(mitexto t){ texto = new mitexto(); this.texto = t; this.repaint(); } public BufferedImage getDibujoFinal(){ return Imagen_en_memoria.getSubimage(0, 0, tmpdibujo.getSize().width, tmpdibujo.getSize().height); } @Override public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D)g; //se crea una imagen en memoria Imagen_en_memoria = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_RGB); ; Graphics2D g2Oculta = Imagen_en_memoria.createGraphics(); g2Oculta.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //pinta imagen de fondo g2Oculta.drawImage(fondo, 0, 0, getWidth(), getHeight(), null); //pinta los objetos de clase midibujo if( this.tmpdibujo != null) this.tmpdibujo.pintar_dibujo(g2Oculta); //pinta los objetos de la clase mitexto if( this.texto != null ) this.texto.pintar_texto(g2Oculta); g2.drawImage(Imagen_en_memoria, 0, 0, this); this.repaint(); } public void mouseDragged(MouseEvent e) { //se envian las nuevas coordenadas if( this.tmpdibujo != null) if( tmpdibujo.get_texto_seleccionado()!= -1 ) tmpdibujo.getTexto( tmpdibujo.get_texto_seleccionado() ).mover((int)e.getPoint().getX(),(int) e.getPoint().getY()); this.repaint(); } public void mouseMoved(MouseEvent e) {} public void mouseClicked(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} }
Al crear el proyecto, creamos tambien un paquete llamado IMAGES, aqui debemos colocar una pequeña imagen que nos sirve de fondo al pintar el JPanel en la interfaz. La imagen es la siguiente:
Clase mitexto.java
Esta clase sirve para almacenar las propiedades del texto que se vaya a crear, ademas de que tiene una función para pintar el texto en pantalla, asi como la función mover() que nos permite desplazar el texto pot pantalla
package jc2dtexto; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.font.FontRenderContext; import java.awt.font.TextLayout; /** * @web http://jc-mouse.blogspot.com/ * @author Mouse */ public class mitexto { private String texto="Default Text"; /* variables para el moviento del texto*/ private int Pos_Marca_X=20; private int Pos_Marca_Y=100; private int Pos_Marca_new_X = 0; private int Pos_Marca_new_Y = 0; private int Dist_X=0; private int Dist_Y=0; /* variables para las propiedades del texto*/ private Color color = new Color(255,0,0); private int tamanio = 20 ; private String tipo_fuente = "Times New Roman"; private Font fuente = new Font(tipo_fuente, Font.PLAIN, tamanio); public mitexto(){} public void setTexto(String t){ this.texto = t; } public String getTexto(){ return this.texto; } public void setSize(int t){ this.tamanio = t; fuente = new Font(tipo_fuente, Font.PLAIN, tamanio); } public int getSize(){ return this.tamanio; } public void setColor(Color c){ this.color = c; } public Color getColor(){ return this.color; } public void setFuente(String tf){ this.tipo_fuente=tf; fuente = new Font(tipo_fuente, Font.PLAIN, tamanio); } public String getFuente(){ return this.tipo_fuente; } public void setPosicion(int x, int y){ Pos_Marca_X=x; Pos_Marca_Y=y; } public void mover(float x, float y){ //nuevas coordenadas Pos_Marca_new_X = (int)x ; Pos_Marca_new_Y = (int)y ; //se obtiene distancia de desplazamiento Dist_X = Pos_Marca_new_X - Pos_Marca_X; Dist_Y = Pos_Marca_new_Y - Pos_Marca_Y; //se actualiza nuevo punto Pos_Marca_X = Pos_Marca_X + Dist_X ; Pos_Marca_Y = Pos_Marca_Y + Dist_Y ; } public void pintar_texto(Graphics2D g2){ FontRenderContext frc = g2.getFontRenderContext(); TextLayout tl; tl = new TextLayout(this.texto, this.fuente, frc); g2.setColor(this.color); tl.draw(g2, (float)Pos_Marca_X,(float)Pos_Marca_Y); } }
Paso 4. Unir todo el codigo.
Trabajamos primero con la clase interfaz.java
– Declaramos las variables a utilizar
//JPanel para dibujar imagenes y letras private mipanel panel; //el objeto dibujo contiene la imagen y letras asi como sus funciones static midibujo dibujo = new midibujo(); //filtro para las imagenes private FileNameExtensionFilter filter = new FileNameExtensionFilter("Archivo de Imagen","jpg","png"); private JFileChooser fileChooser = new JFileChooser(); private File Directorio = fileChooser.getCurrentDirectory(); //para los datos que se extraen de midibujo.java DefaultListModel modelo = new DefaultListModel();
En el constructor de la clase, colocamos:
/** Creates new form interfaz */ public interfaz() { initComponents(); this.setTitle("Texto/Imagenes en Java 2D - by Mouse"); this.setLocationRelativeTo(null); panel = new mipanel(); panel.setDibujo(dibujo); this.jScrollPane1.setViewportView(panel); this.repaint(); dibujo.setModel(modelo); jList1.setModel(modelo); }
Despues se van añadiendo lso eventos a los diferenets controles de la interfaz:
/* MUETSRA UNA VENTANA DE DIALOGO PARA ABRIR UN ARCHIVO DE IMAGEN */ private void jmOpenActionPerformed(java.awt.event.ActionEvent evt) { String file=null; fileChooser = new JFileChooser(); fileChooser.setFileFilter(filter); fileChooser.setCurrentDirectory( Directorio ); int result = fileChooser.showOpenDialog(null); if ( result == JFileChooser.APPROVE_OPTION ){ //se obtiene la direccion del archivo file = fileChooser.getSelectedFile().toString(); dibujo.setFoto(new ImageIcon(file).getImage()); this.panel.resize(); this.repaint(); this.Directorio = fileChooser.getCurrentDirectory(); } } private void jmCrearTextoActionPerformed(java.awt.event.ActionEvent evt) { //se abre ventana de creacion de texto new ventana_texto(-1).setVisible(true); } /* PRESENTA UNA VENTANA DE DIALOGO "GUARDAR COMO..." Y GUARDA LA IMAGEN QUE ESTA EN LA CLASE MIDIBUJO */ private void jmSaveActionPerformed(java.awt.event.ActionEvent evt) { String file=null; fileChooser = new JFileChooser(); fileChooser.setFileFilter(filter); fileChooser.setCurrentDirectory( Directorio ); int result = fileChooser.showSaveDialog(null); if ( result == JFileChooser.APPROVE_OPTION ){ file = fileChooser.getSelectedFile().toString() + ".png"; try { //se extrae el fomato de la cadena "f" que contiene la direccion String formato = (file.endsWith(".jpg")) ? "jpg" : "png"; //se escribe en disco ImageIO.write(this.panel.getDibujoFinal(), formato, new File(file)); JOptionPane.showMessageDialog(null, "La imagen se guardo correctamente..."); } catch (IOException e) { JOptionPane.showMessageDialog(null, "Error: no se pudo crear la imagen"); } } } private void jList1MouseClicked(java.awt.event.MouseEvent evt) { dibujo.seleccionar_texto(jList1.getSelectedIndex()); } private void jmEditarTextoActionPerformed(java.awt.event.ActionEvent evt) { if( jList1.getSelectedIndex() != -1) new ventana_texto(jList1.getSelectedIndex()).setVisible(true); else JOptionPane.showMessageDialog(null, "Error: No existen elementos seleccionados"); }
Para terminar, debemos añadir el codigo a la clase ventana_texto.java.
Declaramos las variables:
private mipanel paneledicion; private mitexto tmptexto = new mitexto(); private int id=-1;
Continuamos con el constructor de clase:
/** Creates new form ventana_texto */ public ventana_texto(int idtexto) { initComponents(); this.setTitle("Añadir/Modificar Texto - by Mouse"); this.setLocationRelativeTo(null); //se crea un nuev panel con un tamaño fijo paneledicion = new mipanel( jPanel1.getSize() ); jPanel1.add(paneledicion); //si ya existe texto en el dibujo, carga este en pantalla if( idtexto!= -1){ id=idtexto; //se copian las propiedades del texto tmptexto.setTexto( interfaz.dibujo.getTexto(id).getTexto() ); tmptexto.setSize( interfaz.dibujo.getTexto(id).getSize() ); tmptexto.setColor( interfaz.dibujo.getTexto(id).getColor() ); tmptexto.setFuente( interfaz.dibujo.getTexto(id).getFuente() ); //se coloca el texto en el jpanel de edición paneledicion.setTexto( tmptexto ); //se colocan los datos en la interfaz jtTexto.setText( tmptexto.getTexto() ); } this.repaint(); }
Y terminando el proyecto, añadimos los eventos a los controles
private void Button1ActionPerformed(java.awt.event.ActionEvent evt) { if( id != -1 ) interfaz.dibujo.updateTexto(tmptexto, id); else interfaz.dibujo.setTexto(tmptexto); dispose(); } private void jpColorMouseClicked(java.awt.event.MouseEvent evt) { Color color = JColorChooser.showDialog(null, "Seleccione un Color", Color.WHITE); jpColor.setBackground(color); tmptexto.setColor(color); this.repaint(); } private void jcSizeActionPerformed(java.awt.event.ActionEvent evt) { tmptexto.setSize(Integer.valueOf(jcSize.getSelectedItem().toString())); this.repaint(); } private void jcFuenteActionPerformed(java.awt.event.ActionEvent evt) { tmptexto.setFuente(jcFuente.getSelectedItem().toString()); this.repaint(); } private void jtTextoKeyTyped(java.awt.event.KeyEvent evt) { String t = jtTexto.getText(); if( t.length()>0 ){ tmptexto.setTexto( t ); paneledicion.setTexto( tmptexto ); this.repaint(); } } private void Button2ActionPerformed(java.awt.event.ActionEvent evt) { dispose(); }
Muy bien, terminamos, si no tienes ningun error, es hora de ejecutar el programa, por el contrario, revisa nuevamente todos los pasos.
El codigo del proyecto: 24kb
Las imagenes SVG (Scalable Vector Graphics) (Ver Wikipedia) son un tipo de imagen ya bastante antiguo pero poco conocido[...]
Modelo Vista Controlador (MVC) es un patrón de arquitectura de software que separa los datos de una aplicación, la inter[...]
Continuando con los tutoriales sobre LibGDX (Librería para el desarrollo de videojuegos), en esta ocasión veremos como e[...]
Webcam Capture es un API que permite usar una cámara web incorporada o externa directamente desde código Java utilizand[...]
¿Qué es Maven? Maven es una herramienta de software para la gestión y construcción de proyectos Java. Provee un conjunto[...]
Este post es la continuación del tutorial «Generador de código para Netbeans« en donde vimos como crear un modulo para N[...]