问题描述
因此,我有一个包含jpanel的类的软件包,我想动态地将它们添加为选项卡.一开始,我使用了一个工厂,并注册了其中的所有类,并且它起作用了,但是现在我希望在包装中加载所有类的情况,而不知道它们的名字.我已经尝试了几件事,包括反射库(我发现很困惑) t让他们上班.感谢任何帮助.
这是我的试验之一:
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); } } }
推荐答案
这是我开发的一种自定义解决方案,以查找包装的所有类:
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");
问题描述
So I have a package that has classes that extend JPanel and I want to add them as tabs dynamically. At the beginning I used a factory and I registered all the classes in it and it worked, but now I want load all the classes in the package without knowing their names. I've tried several things including Reflections library (which I found very confusing) and I couldn't get them to work. I appreciate any help.
Here's one of my trials:
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); } } }
推荐答案
Here is a custom solution I developed to find all the classes of a package:
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; } }
Then, just use:
List<Class<?>> classes = ClassFinder.find("com.package");