Mostrando entradas con la etiqueta utils. Mostrar todas las entradas
Mostrando entradas con la etiqueta utils. Mostrar todas las entradas

sábado, 21 de abril de 2012

Listar archivos en un JAR

Listar archivos en Java es muy sencillo, pero cuando tales archivos se encuentran dentro de un JAR el método listFiles() no funciona. Si buscas un poco seguro encuentras como hacerlo en java2s ó en stackoverflow.

Aquí dejo un método basado en la respuesta de stackoverflow con unas pequeñas modificaciones que lo hacen más flexible:
public List<String> listFiles4JAR(Class clazz, String pack, String ext, boolean includeSubPackage) {

        CodeSource src = clazz.getProtectionDomain().getCodeSource();
        List<String> list = new ArrayList<String>();
        String extension = ext.contains(".") ? ext : "." + ext;
        pack = pack.replace('.', '/');

        int numFolders = 0;
        if( !includeSubPackage ){
            numFolders = pack.split("/").length;
        }
        
        try{

            if(src != null){

                String location = src.getLocation().getPath().replaceAll("%20", " ").replaceAll("!/", "");
                URL jarUrl = new URL(location);

                ZipInputStream zip = new ZipInputStream(jarUrl.openStream());
                ZipEntry ze = null;

                while((ze = zip.getNextEntry()) != null){
                    String entryName = ze.getName();

                    if(entryName.startsWith(pack)
                            && (entryName.endsWith(extension.toLowerCase())
                            || entryName.endsWith(extension.toUpperCase()))){
                        
                        if( !includeSubPackage ){
                            
                            if( numFolders == entryName.split("/").length-1 ){
                                list.add(entryName);
                            }
                            continue;
                        }
                        
                        list.add(entryName);
                    }
                }

            }

        }catch(IOException ex){
            Logger.getAnonymousLogger().log(Level.SEVERE, ext);
        }

        return list;
    }


donde:
            clazz es un clase que se encuentra en el JAR que queremos inspeccionar
            pack es el paquete a examinar
            ext es la extensión de los archivos a listar
            includeSubPackage indica si se listan o no los archivos de los sub-paquetes

Ahora solo queda colocar el método en una clase Utils, digamos JARUtils. De esta forma podremos llamar a nuestro método desde cualquier parte:
public class JARUtils {

    private static final JARUtils jarUtis = new JARUtils();

    private JARUtils() {
    }

    public static JARUtils getInstance() {
        return jarUtis;
    }

    ...

}
Y finalmente hacemos algo como:
List<String> list = JARUtils.getInstance().listFiles4JAR(this.getClass(), "un.paquete.con.imagenes", "png", false);
que nos devolverá la lista de imágenes png en el paquete un.paquete.con.imagenes que se encuentra en el JAR que contiene a la clase que realiza la llamada this.getClass().


martes, 1 de noviembre de 2011

Habilitar/deshabilitar componentes de un Panel en Java

Hola.

En ocasiones sucede que necesitamos deshabilitar todos los componentes de un JPanel o un JFrame por alguna razón. Además tenemos botones, etiquetas, sliders, cajas de texto... y tenemos que hacer por cada componente setEnable(true/false), pero como buenos programadores esa opción no nos agrada, así que buscamos y el buen Google nos da la solución rápidamente:

@Override
public void setEnabled(boolean en) {
    super.setEnabled(en);
    setComponentsEnabled(this, en);
}
private void setComponentsEnabled(java.awt.Container c, boolean en) {
    Component[] components = c.getComponents();
    for (Component comp: components) {
        if (comp instanceof java.awt.Container)
            setComponentsEnabled((java.awt.Container) comp, en);
        comp.setEnabled(en);
    }
}

esto lo que hace es sobreescribir el método setEnabled() del componente de tal forma que cuando se llame al método primero se activará/desactivará el propio componente y posteriormente habilita/deshabilita todos los componentes en él con la llamada a setComponentsEnabled.

Pero esto de pegar el par de métodos en cada componente como que no parece lo mejor, porque no mejor hacer lo siguiente:

public static void setEnableContainer(Container c, boolean band) {
        
 Component[] components = c.getComponents();
 c.setEnabled(band);
 for(int i = 0; i < components.length; i++){            
  components[i].setEnabled(band);
  
  if(components[i] instanceof Container){
   setEnableContainer((Container)components[i], band);
  }
  
 }        
} 
 así podemos dejar el método digamos en una clase SwingUtils y cuando necesitemos habilitar/deshabilitar un componente y todos sus hijos únicamente haríamos una llamada así:

SwingUtils.setEnableContainer(miComponente, true);
SwingUtils.setEnableContainer(miComponente, false); 

y listo.

SwingUtils.java