Visor de imágenes Cómico!
Pues siendo yo un hombre y como tal debo ser fiel a mis palabras, en este comentario dije algo de lo que ni sabia y no imaginaba que pudiera ser tan complicado realizar un simple visor de imágenes, je! y yo queriendo hacer uno de la calidad de Comix, me dio tanta risa por haber creído que seria sencillo que le nombre Cómico!
Después de la dura y cruda realidad( de que me faltaba aprender muchas cosas para poder hacer lo que yo quería) me dije: "¡Dijiste que lo harías y ahora lo haces!"
Observe y "estudie" varios códigos de la red, principalmente de la API de Java.
De allí y otros lugares olvidados por dios, me dispuse a usarlos para crear la aplicación. El camino fue lento, algo empedrado y con una pendiente un tanto empinada.
Pero bueno, lo intente, encontré varios problemas pero al final pude solucionar la mayoría, uf, ahora recuerdo a mis amigos diciéndome que trabajar frente a la computadora era estar en un trabajo sencillo y fácil...que mentira mas grande.
¿Porque les digo todo esto como si fuese una aplicación profesional? Pese a que realmente no tiene nada de profesional, tiene todo mi esfuerzo y dedicación, al menos la que le pude dar en estos días. Y estoy orgulloso de ella :D.
Ya después de haberles contado mis desventuras, pasemos a ¿Lo bueno? Esto es lo que obtuve.
* Aplicacion que simula ser un visor de imagenes...
* Creado por: Jose Manuel Hernandez Farias @author KaltWulx
* Version: 0.0.0.0 :D
* @warning: Hecho por un novice Lvl 1/1... D:
*/
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
public class Imagen
{
private JFrame frame;
private JLabel labelImagen;
private JButton botonAtras, botonAdelante;
private JPanel panelComponentes, panelImagen, panelContenidoDirectorio;
private JFileChooser fileChooser;
private JScrollPane scroll;
private JMenuBar barraMenu;
private JMenu menuArchivo;
private JMenuItem itemArchivo;
private String[] arregloImagenes;
private int contador = 0;
private String contenidoDirectorio;
public static void main(String arg[])
{
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch (Exception e)
{
e.printStackTrace();
}
new Imagen();
}
public Imagen()
{
//Creando frame principal y obteniendo un Contenedor y un manejador BorderLayout
frame = new JFrame( "Cómico!" );
frame.getContentPane().setLayout( new BorderLayout() );
/**Creacion de componentes*/
//Creando la barra de menus
barraMenu = new JMenuBar();
frame.setJMenuBar(barraMenu);
//Construyendo el primer menu
menuArchivo = new JMenu("Archivo");
barraMenu.add(menuArchivo);
//Creando items del menu
itemArchivo = new JMenuItem("Abrir directorio...");
menuArchivo.add(itemArchivo);
//Label
labelImagen = new JLabel();
scroll = new JScrollPane(labelImagen);
//Botones
botonAdelante = new JButton("Siguiente");
botonAtras = new JButton( "Anterior" );
//Creando paneles y añadiendolos al frame principal
panelComponentes = new JPanel();
panelComponentes.setLayout( new FlowLayout() );
panelComponentes.add( botonAtras);
panelComponentes.add( botonAdelante);
panelComponentes.setBorder( BorderFactory.createTitledBorder ( "Controles de imagen" ) );
frame.add( panelComponentes , BorderLayout.SOUTH );
panelImagen = new JPanel();
panelImagen.setLayout( new BorderLayout() );
panelImagen.setBorder( BorderFactory.createTitledBorder ( "Visualizacion de la imagen" ) );
panelImagen.add( scroll, BorderLayout.CENTER );
frame.add( panelImagen , BorderLayout.CENTER );
//Crear panel para el contenido del directorio
panelContenidoDirectorio = new JPanel();
panelContenidoDirectorio.setLayout( new BorderLayout() );
//Estableciendo visibilidad, tamaño y cierrre de la aplicacion
frame.setVisible( true );
frame.setBounds(500,200, 500, 800);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
//Creando FileChooser
fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//Action Listener para el boton atras
botonAtras.addActionListener (new ActionListener ()
{
public void actionPerformed (ActionEvent e )
{
//Disminuyendo y validando contador y el string contenidoDirectorio y arregloImagenes
if(arregloImagenes!= null && contenidoDirectorio != null )
{
contador--;
if(contador == -1)
{
contador = arregloImagenes.length -1;
}
else
{
//Creando y seteando objeto ico en labelImagen
ImageIcon ico = new ImageIcon(contenidoDirectorio+"/"+arregloImagenes[contador]);
labelImagen.setIcon(ico);
}
}
}
});
//Accion de botonAdelante
botonAdelante.addActionListener (new ActionListener ()
{
public void actionPerformed (ActionEvent e)
{
//Aumentando y validando contador y el string contenidoDirectorio y arregloImagenes
if(arregloImagenes != null && contenidoDirectorio != null)
{
contador++;
if(contador == arregloImagenes.length)
{
contador = 0;
}
else
{
//Creando y seteando objeto ico en labelImagen
ImageIcon ico = new ImageIcon(contenidoDirectorio+"/"+arregloImagenes[contador]);
labelImagen.setIcon(ico);
}
}
}
});
//Accion de itemArchivo
itemArchivo.addActionListener (new ActionListener ()
{
public void actionPerformed (ActionEvent e)
{
//Valor que tomara el fileChooser
int regresaValor = fileChooser.showDialog( null, "Abrir imagen" );
//Accion del fileChooser
if(regresaValor == JFileChooser.APPROVE_OPTION)
{
//Crear propiedades para ser utilizadas por fileChooser
File archivoElegido = fileChooser.getSelectedFile();
//Obteniendo el contenido del directorio seleccionado
contenidoDirectorio = archivoElegido.getParent();
//Usando contenidoDirectorio para usar propiedades de File
File direccion = new File( contenidoDirectorio );
if(direccion.isDirectory())
{
contador = 0;
arregloImagenes = null;
//Pasando el contenido del directorio al arreglo
arregloImagenes = direccion.list( new FilenameFilter()
{
@Override
//Sobrescribiendo el metodo accept para ser usado con un filtro de archivos
public boolean accept(File dir, String name)
{
if (name.endsWith(".jpg") ||
name.endsWith(".jpeg") ||
name.endsWith(".gif") ||
name.endsWith(".png"))
{
return true;
}
else
{
return false;
}
}
});
}
}
}
});
}
}
Aquí un video del poder y espíritu de mi aplicación, los errores tambien estan presentes, yeah!!
Nota: Cuando quieras subir un video y postearlo en algún lugar recuerda el tiempo de espera que te dan antes de poder verlo D:
Visor de imagenes Cómico! from Kalt Wulx on Vimeo.
En el video se puede apreciar un error al momento de cambiar la imagen, yo por ahora creo que es la forma en la que estoy controlando el contador del arreglo. Ya después veré que es.
La cosa esta tan jodida que ni siquiera le eh colocado excepciones pero hombre poco a poco, pasito a pasito.
Acepto criticas tanto constructivas como destructivas ja!, pues a partir de aquí, en los ratos libres lo iré mejorando y agregándole cosas nuevas e interesantes :) tengo pensado colocar un panel como el de Comix y que se vean las imágenes en miniatura, colocare la barra de estados, crear una lupa para el zoom, y sobre todo tener la capacidad de mostrar la imagen en diferentes formas, el tamaño original, uno predefinido, etc...Tengo varias ideas para hacerle al programa. Que las pueda hacer es otro rollo...
Les dejo el archivo adjunto, es un zip con el archivo dentro, por si quieren descargarlo, luego, mandarlo a la papelera/imprimirlo y quemar la hoja...y por si casualidad o error, lo compilen y ejecuten.
Quien sabe y algún día prefieran instalar mi aplicación para leer sus mangas en ves de Comix o su lector antes-preferido :O
Que por cierto me baje el paquete de Comix.Y no son ni 40 archivos de python :S y para acabarla no les entiendo mucho que digamos...La competencia si que esta recia.
Bueno gente, se vale soñar y ademas no gasto efectivo en ello.
Moraleja: Nunca comas papaya en la noche...yo no lo hago.
Saludos!
Adjunto | Tamaño |
---|---|
Imagen.zip | 1.9 KB |
- Jose Manuel's blog
- Inicie sesión o regístrese para enviar comentarios
Comentarios
Tu eres KaltWulx ? Muy bueno
Tu eres KaltWulx ?
Muy bueno el visor, muy bonito.
Ep, si.
Gracias por comentar, creía que había hecho algo tan simple que no tendrían razón para comentar. Aunque es posible que por el momento sea así.
Y a tu pregunta, si, kalt wulx es un nick que me invente. ¿Porque? ¿Lo has visto en sitios indebidos? :O je!
Aunque esperaba que me dijeras algunos consejos D: o por lo menos unas criticas destructivas. Pero bueno no estas obligado y ademas ya entraste, lo leíste y lo viste, y ademas comentaste. Con eso estoy satisfecho con tu apoyo.
Saludos.
No, para nada. Sucede que el
No, para nada. Sucede que el código dice hecho por kalt y posteado por tí, no sabía si eran el mismo o no.
No hay muchas cosas que observar, el código está bastante limpio y legible. En todo caso respecto al estilo, pero eso es un tema más subjetivo.
Para no echar tanto rollo, ahi te dejo mis modificaciones ( casi nada ) , espero que te sirvan:
https://gist.github.com/1043409
Si tienes un editor con visualizador de diferencias es más fácil:
Pues de entrada, lo compilé y
Pues de entrada, lo compilé y me marcó excepción en la siguiente anotación
@Override
^
Total, la quité y jaló bien, felicidades; sugerencia, si quieres darle un look and feel de cómic, puedes usarNapkin Look and Feel para que "destaque" tu aplicación, aquí te dejo la liga del proyecto y aquí la de la descarga, por si te gusta, de nuevo, felicidades..
Si ya decía yo.
@OscarRyz
Jeje, por tratar de solucionar los problemas me lleve entre las patas el estilo y hasta el nombre de la clase...
Ya te había dicho que cambiaría mi estilo, según yo uso el del libro de Deitel.
Observe que le cambiaste varias cosas, las voy a estudiar para ver que hacen :D
@neko069
Esa anotación fue creada por el IDE Eclipse y pues solamente no se la quite. A mi no me daba problemas y creía que tampoco a nadie mas le daría.
Ya revise los Look and Feels del link, me gusto uno. Haber si ya con el tiempo madura la aplicación y comparto los avances.
Gracias por los comentarios, sugerencias y modificaciones.
Saludos.
Si está muy raro, a mi
Si está muy raro, a mi también me marco lo mismo del
@Override
,méndigo Eclipse... :)No esta mal eh, solamente que a mí por ejemplo no me gusta poner las llaves en una linea aparte.
java5/6
Lo del @Override es porque tienen una versión distinta de Java. En Java 5 no pueden ponerle @Override a métodos que son de una interfaz y en Java 6 sí (o alrevés, ahorita no me acuerdo).
Ahh si puede ser. Es al
Ahh si puede ser. Es al revés, yo compilé con 1.6
1.5
Segun tengo entendido, la anotacion
@override
se usa para indicarle al compilador de que vas a sobrecargar un metodo de la clase padre y si te equivocas al nombrar al metodo dara un error.Aqui en la liga, en el api de java lo dice.
Total, puedes o no ponerlo. De todos modos se hace la sobrecarga del metodo. Segun la api, dice 1.5.
Y @ezamudio, gracias por comentar :D
Saludos.
@Jose Manuel, si, lo que pasa
@Jose Manuel, si, lo que pasa es que desde la v1.6 ya no se puede poner en una interfaz.
A todos:
Según yo se puede anotar las clases, las interfaces, los atributos y los métodos. Alguna otra parte donde se pueda poner?
Anotaciones
Las anotaciones se pueden poner en clases/interfaces/enums, métodos, atributos (variables de instancia, donde se declaran), declaración de variables locales, constructores (es distinta de un método normal, puedes tener anotaciones que sólo sean válidas en un constructor y no en cualquier método), anotaciones, parámetros (hay anotaciones especiales para parámetros, lo de web service de Java 6 usa esto, Spring también lo usa para algo de REST) y paquetes.
Un ejemplo de anotación de variable local es
@SuppressWarnings
que permite ponerlo en una variable local asignada, al menos para unchecked funciona. Por ejemplo esto arroja advertencia del compilador:System.out.println("Puro relleno");
List<String> lista=new ArrayList();
System.out.println("bye.");
}
Y lo podemos suprimir así:
System.out.println("Puro relleno");
@SuppressWarnings("unchecked")
List<String> lista=new ArrayList();
System.out.println("bye.");
}
Ooh. ya veo.. crei que eran
Ooh. ya veo.. crei que eran menos.
Por cierto #HOYAPRENDÍ que eso de retention policy ( o retention type no me acuerdo ) SOURCE|CLASS|RUNTIME sirve pos claaaro como su nombre lo indica para que se pase al bytecode o no. Por ejemplo
@Override
no llega al compilado y@Deprecated
si.Swing
@Jose Manuel
Buen programa, creeme que para ser estudiante de sistemas sabes programar mejor que mis compas del trabajo.
Haciendole a la talacha
Gracias @Sr. Negativo, se hace lo que se puede :D
Y si, al menos lo que llevo visto de mi carrera la programación aun siendo un tanto fuerte(su precencia en la carrera)no es muy profundizada.
Conforme aprenda mas cosas lo ire modificando, me habia comentado @JaimeItlzc usar Flex y Air. Y pues le voy a andar moviendo y picando haber que tanto puedo aprender y usar en mi aplicación.
Pero de que se va a mejorar, se va a mejorar.
Saludos.
Que tal!!
Estaba intentando ejecutar el Visor de imagnes pero no le he conseguido hacerlo, me sale este error :
at Imagen$2.actionPerformed(Imagen.java:133)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:236)
at java.awt.Component.processMouseEvent(Component.java:6267)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3267)
at java.awt.Component.processEvent(Component.java:6032)
at java.awt.Container.processEvent(Container.java:2041)
at java.awt.Component.dispatchEventImpl(Component.java:4630)
at java.awt.Container.dispatchEventImpl(Container.java:2099)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4238)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168)
at java.awt.Container.dispatchEventImpl(Container.java:2085)
at java.awt.Window.dispatchEventImpl(Window.java:2478)
at java.awt.Component.dispatchEvent(Component.java:4460)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)
Alguna sugerencia por favor?
Ya había dejado olvidado este
Ya había dejado olvidado este post.... D: La verdad es que aquí todos fueron muy amables y suaves conmigo, porque el código esta lleno de errores, estoy trabajando en una nueva versión en mis momentos de libertad.
El error podría estar en como abres el directorio de las imágenes, revisa bien. Hay un error al abrir ciertos directorios. Lamento no poder ayudarte mas, cuando salga mi nuevo prototipo seguro estarás mas complacido ;)
Saludos.
:-/
Yo hice un visor muy sencillo, y al ver este post me interesé, en mi visor tengo una gran limitante porque para poner la imagen en el panel la tengo que renombrar así:
File file = new File( dir_imagen );
try {
// image.getScaledInstance(100, 100, Image.SCALE_AREA_AVERAGING);
image = ImageIO.read(file) ;
} catch (IOException ex) {
// Logger.getLogger(Foto.class.getName()).log(Level.SEVERE, null, ex);
}
int ancho = Contenedor.getWidth();
int alto = Contenedor.getHeight();
image = redimensionarImagen(image, ancho, alto);
Contenedor.setImage(image);
donde "1.jpg" es el nombre de la foto, es decir si tengo 20 fotos tendria que hacer 20 diferentes String dir_imagen,
entonces quisiera saber como le hiciste para hacerlo digamos general... no sé si me explico... ojala puedas darme un tip, gracias!!
Bueno si es eso la cosa es
Bueno si es eso la cosa es bastante simple. Hay que utilizar la clase
File
para obtener un archivo y a partir de el obtener los archivos que están en el directorio.Checa este ejemplo, tiene un
JFrame
donde esta un botón que abre unJFileChooser
y se selecciona una imagen y luego se lista el contenido del directorio en el que se encuentra.* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package test;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FilenameFilter;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
/**
*
* @author Kalt
*/
public class Test {
private static File directorioImagenes[] = null;
private static File archivoEscogido = null;
private JFrame frame = null;
private JButton b = null;
private final static JFileChooser jfc = new JFileChooser();
public Test() {
frame = new JFrame("Test");
frame.getContentPane().setLayout(new BorderLayout());
jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
b = new JButton("Abrir");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
int var = jfc.showDialog(frame, "Escoje la imagen");
if (var == JFileChooser.APPROVE_OPTION) {
archivoEscogido = jfc.getSelectedFile();
listarImagenes();
}
}
});
frame.add(b);
frame.pack();
frame.setVisible(true);
}
private void listarImagenes() {
capturarImagenes();
if (directorioImagenes != null) {
int length = directorioImagenes.length;
System.out.println("Contenido del directorio:");
for (int i = 0; i < length; i++) {
System.out.println(directorioImagenes[i]);
}
}
}
private void capturarImagenes() {
if (archivoEscogido != null) {
System.out.println("El archivo elegido es: "+archivoEscogido);
File contenidoDelDirectorio = archivoEscogido.getParentFile();
System.out.println("El directorio padre es: "+contenidoDelDirectorio);
directorioImagenes = contenidoDelDirectorio.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
if (name.toLowerCase().endsWith(".jpg")
|| name.toLowerCase().endsWith(".png")
|| name.toLowerCase().endsWith(".jpeg")
|| name.toLowerCase().endsWith(".gif")) {
return true;
} else {
return false;
}
}
});
}
}
public static void main(String args[]) {
new Test();
}
}
La salida es:

Creo que lo he hecho lo suficientemente claro como para que lo entiendas pero si tienes dudas déjalas aquí y tratare de ayudarte.
Saludos
jejeje
Bueno me respondo a mi mismo por si alguien le sirve, se pueden obtener los nombres de archivos de un fichero mediante .list()
acá un ejemplito muy bueno...
http://lineadecodigo.com/java/listar-un-directorio-con-java-io/
de todos modos acepto cualquier otro tip... saludos
Excelente
AAhhhh excelente...!!!! gracias por la pronta respuesta.... !!! saludos
Es mejor si utilizas
Es mejor si utilizas
listFiles();
Porque seria mas fácil para ti trabajar con objetos files.(y)
Cierto, muchas gracias José Manuel.. se agradece el aporte, saludos desde Oaxaca!!
Ya sabanas pá que cobijas
Ya sabanas pá que cobijas XD
Suerte!