2013-03-20 17 views
9

Quindi ho un pacchetto con classi che estendono JPanel e voglio aggiungerle come schede dinamicamente. All'inizio ho usato una fabbrica e ho registrato tutte le classi e ha funzionato, ma ora voglio caricare tutte le classi nel pacchetto senza conoscerne i nomi. Ho provato diverse cose tra cui Reflections library (che ho trovato molto confuso) e non ho potuto farli funzionare. Apprezzo qualsiasi aiuto.Come ottenere tutti i nomi delle classi in un pacchetto?

Ecco una delle mie prove:

public static void registerTab() { 
    String pkg = TabA.class.getPackage().getName(); 
    String relPath = pkg.replace('.', '/'); 

    URL resource = ClassLoader.getSystemClassLoader().getResource(relPath); 
    if (resource == null) { 
     throw new RuntimeException("Unexpected problem: No resource for " 
       + relPath); 
    } 

    File f = new File(resource.getPath()); 

    String[] files = f.list(); 

    for (int i = 0; i < files.length; i++) { 

     String fileName = files[i]; 
     String className = null; 
     String fileNm = null; 

     if (fileName.endsWith(".class")) { 

      fileNm = fileName.substring(0, fileName.length() - 6); 
      className = pkg + '.' + fileNm; 
     } 

     if (className != null) { 

      if (!tabClasses.containsKey(className)) 
       tabClasses.put(fileNm, className); 
     } 
    } 
} 
+0

Cosa non ha funzionato con la riflessione? –

risposta

50

Ecco una soluzione personalizzata che ho sviluppato per trovare tutte le classi di un pacchetto:

public class ClassFinder { 

    private static final char PKG_SEPARATOR = '.'; 

    private static final char DIR_SEPARATOR = '/'; 

    private static final String CLASS_FILE_SUFFIX = ".class"; 

    private static final String BAD_PACKAGE_ERROR = "Unable to get resources from path '%s'. Are you sure the package '%s' exists?"; 

    public static List<Class<?>> find(String scannedPackage) { 
     String scannedPath = scannedPackage.replace(PKG_SEPARATOR, DIR_SEPARATOR); 
     URL scannedUrl = Thread.currentThread().getContextClassLoader().getResource(scannedPath); 
     if (scannedUrl == null) { 
      throw new IllegalArgumentException(String.format(BAD_PACKAGE_ERROR, scannedPath, scannedPackage)); 
     } 
     File scannedDir = new File(scannedUrl.getFile()); 
     List<Class<?>> classes = new ArrayList<Class<?>>(); 
     for (File file : scannedDir.listFiles()) { 
      classes.addAll(find(file, scannedPackage)); 
     } 
     return classes; 
    } 

    private static List<Class<?>> find(File file, String scannedPackage) { 
     List<Class<?>> classes = new ArrayList<Class<?>>(); 
     String resource = scannedPackage + PKG_SEPARATOR + file.getName(); 
     if (file.isDirectory()) { 
      for (File child : file.listFiles()) { 
       classes.addAll(find(child, resource)); 
      } 
     } else if (resource.endsWith(CLASS_FILE_SUFFIX)) { 
      int endIndex = resource.length() - CLASS_FILE_SUFFIX.length(); 
      String className = resource.substring(0, endIndex); 
      try { 
       classes.add(Class.forName(className)); 
      } catch (ClassNotFoundException ignore) { 
      } 
     } 
     return classes; 
    } 

} 

Poi, basta usare:

List<Class<?>> classes = ClassFinder.find("com.package"); 
+0

Grazie! Lo proverò. – Tareq

+0

Restituisce una lista vuota. L'ho usato in questo modo 'Elenco > cls = ClassFinder.find (TabA.class.getPackage(). GetName());' – Tareq

+0

@Tareq 'TabA' in un JAR o direttamente nella cartella * classes * del tuo progetto ? Questa soluzione funziona solo nel secondo caso. – sp00m

Problemi correlati