2013-03-20 22 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 JAR内、またはプロジェクトの* classes *フォルダ内の' TabA'は 'TabA'です?このソリューションは、2番目のケースでのみ機能します。 – sp00m