2013-03-20 14 views
9

JPanel'i genişleten sınıfları olan bir paketi var ve bunları dinamik olarak sekmeler olarak eklemek istiyorum. Başlangıçta bir fabrika kullandım ve bütün sınıfları oraya kaydettim ve işe yaradı, ama şimdi paketlerdeki bütün sınıfları isimlerini bilmeden yüklemek istiyorum. Reflections library (çok kafa karıştırıcı bulduğum) dahil birkaç şey denedim ve onları işe alamadım. Herhangi bir yardım için minnettarım.Tüm sınıf isimleri bir pakette nasıl alınır?

İşte benim denemeler biri:

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); 
     } 
    } 
} 
İşte
+0

Yansımada neyin ters gittiği? –

cevap

50

Bir paketin tüm sınıfları bulmak için geliştirilmiş özel bir çözümdür: Sonra

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; 
    } 

} 

, sadece kullanın:

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

Teşekkürler! Deneyeceğim. – Tareq

+0

Boş bir liste döndürür. Ben bu gibi kullandım 'List > cls = ClassFinder.find (TabA.class.getPackage(). GetName());' – Tareq

+0

@Tareq Bir JAR içinde 'TabA' veya doğrudan projenin * sınıfları * klasöründe ? Bu çözüm sadece ikinci durumda çalışır. – sp00m

İlgili konular