Java + Swing 025. Modo diseño en NetBeans. Cargar imágenes “jpg” y “png” desde un directorio a un JTable.

Ejercicio: Realizar una pequeña aplicación que permita cargar imágenes tipo "jpg" y "png" desde un directorio a un JTable.
Gran parte del código que se implementa en esta aplicación es tomada y adaptada de otra fuente: referencia principal jc-mouse (http://goo.gl/uKrT2W).
Diseñamos el formulario utilizando un JFrame. El nombre para el jFrame es a criterio de cada uno, lo importante es el diseño de la misma. En la imagen podemos ver el diseño y los nombres de variables de cada objeto (etiquetas en rojo para los nombres de variable), esto es muy importante ya que cada método utiliza el nombre de variable correspondiente para referenciar al objeto en específico. Se puede cambiar el “Nombre de variable” de cada objeto haciendo clic derecho sobre la misma y clic en “Cambiar nombre de variable…”. El jTable posee tres columnas sin nombre, esta se agregará desde al “model”. (clic para ampliar imgen)
Observación: Tomar en cuenta que hay que utilizar las importaciones “import”, básico para utilizar ciertos métodos y objetos. El “setLocationRelativeTo(null)” sirve para centrar el formulario. El método “tableModel()” que llamamos en el constructor se ejecutará al lanzar el formulario. Debemos de tener en cuenta también el paquete de nuestro jFrame.
Lista de Importaciones necesarias.
Código Java
import java.awt.Component;
import java.io.File;
import java.io.FileFilter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTable;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
Lista de Variables de clase.
Código Java
//Variables de clase.
private MyTableModel modelo = new MyTableModel();
private FileNameExtensionFilter filter = new FileNameExtensionFilter("Archivo de Imagen","jpg","png");
Creamos los métodos y clases siguientes, cada método y clase posee un nombre que especifica de cierta forma su función. Las clases al igual que los métodos pueden ir dentro del mismo JFrame, es ideal si no se utiliza en otro formulario. En caso de ser necesaria su utilización en otros formularios debe de ir en un archivo independiente y dentro del mismo paquete si es posible. Se agregan comentarios para indicar en lo posible que función cumple cada línea de código.
Código Java

//Método para manejar jTable
private void tableModel(){
String[] nombreColumnas = {"Imagen","Imagen","Imagen"};
Object[][] datosFila = { };
modelo.setDataVector(datosFila, nombreColumnas);
tableImg.setModel(modelo);
tableImg.getColumnModel().getColumn(0).setCellRenderer( new ImageRenderer() );
tableImg.getColumnModel().getColumn(1).setCellRenderer( new ImageRenderer() );
tableImg.getColumnModel().getColumn(2).setCellRenderer( new ImageRenderer() );
tableImg.setRowHeight(256);

//Método para mostrar una vista previa de la imagen seleccionada del jtable.
tableImg.addMouseListener(new java.awt.event.MouseAdapter() {
@Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
int row = tableImg.rowAtPoint(evt.getPoint());
int col = tableImg.columnAtPoint(evt.getPoint());
if ( row >= 0 && col >= 0 )
{
//si celda contiene imagen
if( modelo.getValueAt(row, col) != null )
{
//obtiene la ruta que corresponde a la celda donde se hizo el clic
File fichero = new File( modelo.getValueAt(row, col).toString() );
//se carga la imagen en un jlabel
JLabel picLabel = new JLabel(new ImageIcon( fichero.getAbsolutePath() ));
//se muestra la imagen en el jdialog
JOptionPane.showMessageDialog(null, picLabel, "Vista Previa", JOptionPane.PLAIN_MESSAGE, null);
}
}
}
});
}
//Permite seleccionar el directorio del cual cargaremos las imagenes.
private void selecDir(){
//JFileChooser como selector de archivos.
JFileChooser fileDir = new JFileChooser();
//Filtro que creamos más arriba como variable de clase. Permite mostra solo imagenes jpg y png
fileDir.setFileFilter(filter);
//Comprobamos que se apruebe la selección
if (fileDir.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
//Limpiamos las filas del jtable.
modelo.setRowCount(0);
//ImgFilter es una clase que se crea más abajo para filtrar la imagenes que se cargarán.
//Esto porque el anterior filtro que creamos es para filtrar las que se muestran.
ImgFilter filt = new ImgFilter();
//Cargamos en un array los orchivos de imagen especificando nuestro filtro.
File[] selectedFiles = fileDir.getCurrentDirectory().listFiles(filt);
//Recorremos el array y vamos cargando las imagenes en la tabla.
for (int id = 0; id < selectedFiles.length; id++) {
File selectedFile = selectedFiles[id];
int f = modelo.getRowCount();//cantidad de filas
int c = modelo.getColumnCount();//cantidad de columnas
boolean ok = true;
//recorre todo el TableModel buscando una celda vacia para agregar la imagen
for( int i=0; i<f;i++ )
{
if( ok )
{
for( int j=0; j<c; j++ ){

if( modelo.getValueAt(i, j) == null )
{
this.modelo.setValueAt( selectedFile.getAbsolutePath() , i, j );
tableImg.repaint();
ok=false;
break;
}
}
}
else
{
break;
}
}


if( ok ) //añade nueva fila
{
modelo.setRowCount( modelo.getRowCount() + 1 );
this.modelo.setValueAt( selectedFile.getAbsolutePath() , modelo.getRowCount()-1, 0 );
tableImg.repaint();
}
}
}


}


//Clase que extiende a DefaultTableModel, nos permite trabajar con tablas.
public class MyTableModel extends DefaultTableModel {

@Override
public boolean isCellEditable(int row, int column) {
return false;
}

}

//------------------------------------class ImageRenderer-----------------------------------------------------------------------------------------------------
//Clase que extiende a DefaultTableCellRenderer, nos permitira cargar una imagen a una celda seleccionada.
public class ImageRenderer extends DefaultTableCellRenderer{

private JLabel lb = new JLabel();
//imagen que se muestra cuando la celda esta vacia
private ImageIcon icon = new ImageIcon( getClass().getResource("conta.png") );
//para contener las imagenes que se vayan cargando
private Map iconos = new HashMap() ;

@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,boolean hasFocus, int row, int column){
lb.setText((String) value);
File fichero;
//
if( value !=null )
{
fichero = new File( value.toString() );
//comprueba que fichero exista
if( fichero.exists() )
{
//busca la imagen en el MAP
if( ya_existe( value.toString() ) )
{
//si ya existe, extrae la imagen del MAP
lb.setIcon( getIcono( value.toString() ) );
}
else //No existe
{
//Agrega la imagen al map
iconos.put(value.toString(), bToIcon(fichero) );
//extrae y muestra
lb.setIcon( getIcono( value.toString() ) );
}

}
else //si no existe, muestra imagen por default
{
lb.setIcon(icon);
}
}
else
{
lb.setIcon(icon);
}
return lb;
}
/**
* Comprueba que una imagen ya exista en memoria
* @param String key identificador
*/

private boolean ya_existe( String key ){
Iterator it = iconos.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry)it.next();
if( e.getKey().equals(key) )
return true;
}
return false;
}
/**
* Extrae una imagen del MAP dado su KEY
* @param String key identificador unico
* @return ImageIcon
*/

private ImageIcon getIcono( String key ) {
ImageIcon imageIcon = icon;
Iterator it = iconos.entrySet().iterator();
while (it.hasNext()) {
Map.Entry e = (Map.Entry)it.next();
if( e.getKey().equals(key) )
{
imageIcon = (ImageIcon) e.getValue();
break;
}
}
return imageIcon;
}

/**
* Dado la ruta de un archivo de imagen, carga este en un ImageIcon y retorna
* @param File fichero
*/

private ImageIcon bToIcon( File fichero ){
ImageIcon imageIcon = new ImageIcon( fichero.getAbsolutePath() );
return imageIcon;
}
}
//-----------------------------------------------------------------------------------------------------------------------------------------

//Clase que permite filtrar tipos de arhivos, extiende a FileFilter.
//Esta clase la utilizaremos para filtrar los archivos de una carpeta selecionada.
public class ImgFilter implements FileFilter{
//Se retorna true o false según corresponda o no al filtro indicado.
@Override
public boolean accept(File f)
{
if (f != null && f.getName().toLowerCase().endsWith(".jpg") ||f.getName().toLowerCase().endsWith(".png") )
{
return true;
}
else
{
return false;
}
}

public String getDescription()
{
return "Filtro para imagenes.";
}
}
Utilizamos el evento “ActionPerformed” para llamar nuestro método “selecDir()” desde el botón “cargar” de nuestro diseño. Para utilizar un “Evento” hacemos clic derecho sobre el objeto y seleccionamos “Eventos” de la lista utilizamos la que podamos aplicar al objeto. En la mayoría de los casos se utiliza el “ActionPerformed”. Se agregan comentarios para tratar de facilitar el entendimiento.
Código Java
    private void cargarActionPerformed(java.awt.event.ActionEvent evt) {                                         
//Método para seleccionar una imagen y poder cargar el directorio completo en la que se encuentra.
selecDir();
}
Ejecutamos nuestro formulario y vemos los resultados. El tamaño del jFrame como el de las columnas de la tabla se puede ajustar. (Clic para ampliar la imagen)

No hay comentarios :

Publicar un comentario