Aprende Java Aprende Php Aprende C++ Aprende HTML 5 Aprende JavaScript Aprende JSON Aprende MySQL Aprende SQLServer Aprende Visual Basic 6 Aprende PostgreSQL Aprende SQLite Aprende Redis Aprende Kotlin Aprende XML Aprende Linux VSC Aprende Wordpress Aprende Laravel Aprende VueJS Aprende JQuery Aprende Bootstrap Aprende Netbeans Aprende Android
Sigueme en Facebook Sigueme en Twitter Sigueme en Instagram Sigueme en Youtube Sigueme en TikTok Sigueme en Whatsapp
Home / Java / Java2D / Proyectos / Texto e Imagen en Java2d (Proyecto)

Texto e Imagen en Java2d (Proyecto)

Por jc mouse domingo, octubre 9, 2011

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

Click para descargar

Tags

Artículos similares

Gráficos Vectoriales SVG

Las imagenes SVG (Scalable Vector Graphics) (Ver Wikipedia) son un tipo de imagen ya bastante antiguo pero poco conocido[...]

3 en raya java con MVC y Netbeans

Modelo Vista Controlador (MVC) es un patrón de arquitectura de software que separa los datos de una aplicación, la inter[...]

Empaquetado de texturas en LibGDX

Continuando con los tutoriales sobre LibGDX (Librería para el desarrollo de videojuegos), en esta ocasión veremos como e[...]

API completo y ligero para el uso de webcams desde java

Webcam Capture es un API  que permite usar una cámara web incorporada o externa directamente desde código Java utilizand[...]

Aplicaciones java con Maven

¿Qué es Maven? Maven es una herramienta de software para la gestión y construcción de proyectos Java. Provee un conjunto[...]

Crear e instalar modulo NBM

Este post es la continuación del tutorial «Generador de código para Netbeans« en donde vimos como crear un modulo para N[...]