2013-03-20 3 views
9

Итак, у меня есть пакет, который имеет классы, расширяющие JPanel, и я хочу добавить их в виде вкладок динамически. Сначала я использовал завод, и я зарегистрировал все классы в нем, и он сработал, но теперь я хочу загрузить все классы в пакете, не зная их имен. Я пробовал несколько вещей, включая Reflections library (который я нашел очень запутанным), и я не мог заставить их работать. Я ценю любую помощь.Как получить все имена классов в пакете?

Вот один из моих испытаний:

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

Что пошло не так с отражением? –

ответ

50

Вот пользовательское решение, которое я разработал, чтобы найти все классы пакета:

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

} 

Затем просто использовать:

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

Спасибо! Я попробую. – Tareq

+0

Он возвращает пустой список. Я использовал его так: «Список > cls = ClassFinder.find (TabA.class.getPackage(). GetName());' – Tareq

+0

@Tareq Is 'TabA' в JAR или непосредственно в * классе * в вашем проекте ? Это решение работает только во втором случае. – sp00m

Смежные вопросы