Beginning Sistemas de Información Java Imágenes Listado siguiente
PresentaciónEntrada/SalidaBibliotecasSwingMarcosBotonesCuadros de texto
ListasImágenesMenúsDiálogosArchivosGráficos 2D 

Visualización de imágenes

El proceso seguido para mostrar una imagen mediante Swing es el esperable: primero es preciso cargar la imagen (mediante un ImageIcon), y después se visualiza la imagen en pantalla en algún componente (un JLabel, por ejemplo). La carga es sencilla porque el constructor de ImageIcon admite como argumento un URL. Ejemplo.- Construir un programa que admita imágnes en formato .gif, .png y .jpg. Las imágenes se adquirirán a partir de un archivo local (file://) o remoto (http://). El programa mostraá tres listas, una por cada tipo de imagen; a medida que el usuario inserte imágenes, éstaws aparecerán en la lista correspondiente. Cada lista tendrá un botón para ordenar las imágenes por nombres. La última imagen seleccionada se mostrará en el visor de programa.



Este programa funciona correctamente tanto con archivos locales como con archivos remotos. Basta recordar que el protocolo exige direcciones de la forma file:///seguidas por el resto de la ruta.

La lista de archivos que forman parte de este programa es como sigue: Veamos a continuación el contenido de estos archivos. Quizá el más interesante sea ListaBotonVisor.java, al tratarse de un componente que se reutiliza en tres ocasiones y maneja tanto la selección en la lista como la ordenación de los contenidos cuando se hace clic en un botón.

Los archivos son los siguientes:

ImagenesBLT.java
/** 
 * ImagenesBLT.java
 *
 * Descripción: 
 * @author   coti
 * @version   1.0
 */
import java.awt.BorderLayout;

public class ImagenesBLT {
 public ImagenesBLT() {
  PanelVisor pv = new PanelVisor();
  TresListasYDistribuidor tlyd 
  	= new TresListasYDistribuidor(pv.getVisor());
  JFrame4 jf = new JFrame4("Listas, Texto y Botones");
  jf.getContentPane().add(tlyd, BorderLayout.SOUTH);
  jf.getContentPane().add(pv, BorderLayout.CENTER);
  jf.pack();
  jf.centerThisFrame();
  jf.setVisible(true);
 }

 static public void main(String[] args) {
  new ImagenesBLT();
 }
 
}

JFrame4.java
/** 
 * JFrame4.java
 *
 * DescripciÛn: 
 * @author   coti
 * @version   1.1
 */


import java.awt.Dimension;
import java.awt.Component;
import java.awt.Toolkit;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.UIManager;

public class JFrame4 extends JFrame{
 Dimension dim_pantalla, dim_cuadro;
 int posx, posy;
 JFrame4() {
  super("Sin título");
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent we) {
    System.exit(0);
   }
  });
  try
   {
    UIManager.setLookAndFeel(
    	UIManager.getSystemLookAndFeelClassName());
   }
  catch(Exception e)
   {
    System.err.println(e);
   }
 } // Constructor sin tÌtulo
 
 JFrame4(String t) {
  super(t);
  addWindowListener(new WindowAdapter() {
   public void windowClosing(WindowEvent we) {
    System.exit(0);
   }
  });
  try
   {
    UIManager.setLookAndFeel(
    	UIManager.getSystemLookAndFeelClassName());
   }
  catch(Exception e)
   {
    System.err.println(e);
   }

 } // Constructor con tÌtulo
 

 public void centerThisFrame() {
  dim_pantalla
   = Toolkit.getDefaultToolkit().getScreenSize();
  dim_cuadro = getContentPane().getPreferredSize();
  //pack();
  setLocation( (dim_pantalla.width-dim_cuadro.width)/2,
      (dim_pantalla.height-dim_cuadro.height)/2);
 }
}


ListaBotonVisor.java
import javax.swing.JButton;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Toolkit;

import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;

import java.util.Arrays;
import java.util.Hashtable;

public class ListaBotonVisor extends JPanel
        implements ActionListener,
           ListSelectionListener {
 /*
  Este JPanel contiene un JList y un JButton.
  El JList se clasifica por orden descendente cuando
  se pulsa el bt.
  Si se hace clic en un elemento, ese elemento
  se muestra en el JPanel visor, recibe como argumento
  el constructor.
 */
 private JList jl;
 private JButton jb;
 private JLabel pv;
 private Hashtable ht;
 private DefaultListModel dlm;
 ListaBotonVisor(JLabel pv) {
  this.pv = pv;
  dlm = new DefaultListModel();
  ht = new Hashtable();
  jl = new JList(dlm);
  jl.setFixedCellWidth(200);
  jl.addListSelectionListener(this);
  
  JScrollPane jsp = new JScrollPane(jl);
  jsp.setHorizontalScrollBarPolicy(
  	JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
  jsp.setVerticalScrollBarPolicy(
  	JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
  
  jb = new JButton("Ordenar");
  jb.addActionListener(this);
  
  setLayout(new BorderLayout());
  add(jb, BorderLayout.NORTH);
  add(jsp, BorderLayout.CENTER);
 }
 public DefaultListModel getDefaultListModel()
 	{return dlm;};
 public Hashtable getHashtable() {return ht;};
 public void actionPerformed(ActionEvent ae) {
  int num_elementos = dlm.getSize();
  if (num_elementos>1)
   {
    String[] ls = new String[num_elementos];
    dlm.copyInto(ls);
    Arrays.sort(ls);
    dlm.removeAllElements();
    for(int i=0;i<num_elementos;i++)
     dlm.addElement(ls[i]);
   }
  else
   Toolkit.getDefaultToolkit().beep();
   
 }
 public void valueChanged(ListSelectionEvent le) {
  String s = (String)jl.getSelectedValue();
  pv.setIcon((ImageIcon)ht.get(s));
  pv.setText(s);
 }
}
PanelVisor.java
import java.awt.BorderLayout;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.ImageIcon;
import java.awt.Dimension;
import javax.swing.SwingConstants;

public class PanelVisor extends JPanel {
 private JLabel visor;
 PanelVisor(ImageIcon mg, String comentario) {
  setPreferredSize(new Dimension(400,400));
  setLayout(new BorderLayout());
  /*
   Centramos el contenido del JPanel.
  */
  setAlignmentX(SwingConstants.CENTER);
  setAlignmentY(SwingConstants.CENTER);
  /*
   Centramos la imagenen en el JLabel.
  */
  visor = new JLabel(comentario, mg, JLabel.CENTER);
  /*
   El texto va debajo de la imagen.
  */
  visor.setVerticalTextPosition(JLabel.BOTTOM);
  /*
   Se centra el texto en la imagen.
  */
  visor.setHorizontalTextPosition(JLabel.CENTER);
  add(visor, BorderLayout.CENTER);
 }
 PanelVisor() {
  setPreferredSize(new Dimension(400,400));
  setLayout(new BorderLayout());
  /*
   Centramos el contenido del JPanel.
  */
  setAlignmentX(SwingConstants.CENTER);
  setAlignmentY(SwingConstants.CENTER);
  /*
   Centramos la imagenen en el JLabel.
  */
  visor = new JLabel("", null, JLabel.CENTER);
  /*
   El texto va debajo de la imagen.
  */
  visor.setVerticalTextPosition(JLabel.BOTTOM);
  /*
   Se centra el texto en la imagen.
  */
  visor.setHorizontalTextPosition(JLabel.CENTER);
  add(visor, BorderLayout.CENTER);
 }
 public JLabel getVisor() {return visor;};
}

TresListasYDistribuidor.java
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.Toolkit;
import java.net.URL;
import java.util.Hashtable;

public class TresListasYDistribuidor extends JPanel
          implements ActionListener{
/*
 Esta clase construye tres ejemplares
 de ListaBotonVisor y un campo de texto
 que va sobre ellos.
 Cuando se inserta un posible URL en el
 campo, ese URL se verifica y se añade
 a una de las tres listas (para JPG, GIF o PNG).
 Cuando se hace clic en uno de los botones, se ordena
 descendentemente la lista correspondiente.
 Cuando se hace clic en un elemento, ese elemento
 se visualiza en el visor recibido como argumento
 del constructor.
*/
 private ListaBotonVisor gif, jpg, png;
 private JTextField jtf;
 private Toolkit tk;
 private JLabel pv;
 Cursor espera,normal;
 TresListasYDistribuidor(JLabel pv) {
  this.pv = pv;
  setLayout(new BorderLayout());
  tk = Toolkit.getDefaultToolkit();
  gif = new ListaBotonVisor(pv);
  jpg = new ListaBotonVisor(pv);
  png = new ListaBotonVisor(pv);
  jtf = new JTextField(40);
  jtf.addActionListener(this);
  add(jtf,BorderLayout.NORTH);
  add(gif, BorderLayout.WEST);
  add(jpg, BorderLayout.CENTER);
  add(png, BorderLayout.EAST);
  espera = new Cursor(Cursor.WAIT_CURSOR);
  normal = new Cursor(Cursor.DEFAULT_CURSOR);
 }
 public void actionPerformed(ActionEvent ae) {
  String temp = jtf.getText();
  ImageIcon imagen;
  URL url;
  DefaultListModel dlm;
  Hashtable ht;
  /*
   Determinamos en quÈ lista se encuadra el
   URL proporcionado.
  */
  setCursor(normal);
  if ((temp.indexOf(".gif")) > 0)
   {
    dlm = gif.getDefaultListModel();
    ht = gif.getHashtable();
   }
  else if ((temp.indexOf(".jpg")) > 0)
   {
    dlm = jpg.getDefaultListModel();
    ht = jpg.getHashtable();
   }
  else if ((temp.indexOf(".png")) > 0)
   {
    dlm = png.getDefaultListModel();
    ht = png.getHashtable();
   }
  else
   {
    tk.beep();
    jtf.selectAll();
    return;
   }
  /*
   Si el modelo de lista seleccionado no contiene
   la imagen cuya ubicaciÛn se proporciona, intentamos
   crear un URL. Si ese URL es válido, se intenta
   cargar la imagen. Si esto es posible, se añade
   la cadena y la imagena a la Hashtable asociada
   al duo JList/JButton determinado anteriormente.
  */
  setCursor(espera);
  if (!dlm.contains(temp))
   {
    try
     {
      url = new URL(temp);
      imagen = new ImageIcon(url);
     }
    catch(Exception e)
     {
      //System.out.println(e);
      Toolkit.getDefaultToolkit().beep();
      jtf.selectAll();
      setCursor(normal);
      return;
     }
    if (imagen.getIconHeight()!=-1)
     {
      dlm.addElement(temp);
      ht.put(temp,imagen);
      pv.setIcon(imagen);
      pv.setText(temp);
     }
    else
     {
      jtf.selectAll();
      Toolkit.getDefaultToolkit().beep();
      setCursor(normal);
      return;
     }
   }
  else
   {
    pv.setIcon((ImageIcon)ht.get(temp));
    pv.setText(temp);
   }
  setCursor(normal);

 }
}


Comentarios.- Cuando falla la lectura de una imagen, sea cual fuere la causa, el usuario no recibe más notificación que un pitido. Esto es, a todas luces, insuficiente. Sería preferible añadir un cuadro de dlálogo explicativo. Por otra parte, este programa carece de la posibilidad de activar opciones a través de un menú; tampoco sería mala idea aportarlas. Finalmente, si se añade al programa la posibilidad de reproducir una lista de imágenes procedentes de disco (con un temporizador) se dispondrá de un visor de imágenes razonablemente operativo.