I have been working on refactoring a java graphics package for the graphics program at EWU and noticed that it was adding tabs to a JPanel, so I figured that it could put all the tabs in a package then scan the directory for appropriate classes and load them dynamically. Voila instant plugin architecture.
It turned out to be pretty simple using Java's ClassLoader interface. The only complication was that my tabs had parameters in their initialization functions, so I needed to create a super class(MasterPanel) that held that functionality and call that instead of casting the class as a JPanel, since I don't know what the panel names might be in the future.
It turned out to be pretty simple using Java's ClassLoader interface. The only complication was that my tabs had parameters in their initialization functions, so I needed to create a super class(MasterPanel) that held that functionality and call that instead of casting the class as a JPanel, since I don't know what the panel names might be in the future.
//Get the path of the package relative to the project directory
String packageName = "package.name.here";
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
String path = "./" + packageName.replace('.', '/');
//Check all the files in the package directory for Panel.class files
//Check all the files in the package directory for Panel.class files
//If there are any add them to this panel as tabs
File dir = new File(path);
File[] files = dir.listFiles();
for(File curFile : files)
if(curFile.getName().endsWith("Panel.class") && !curFile.getName().endsWith("MasterPanel.class"))
{
{
String curPanel = curFile.getName();
int index = curPanel.indexOf('.');
curPanel = curPanel.substring(0, index);
Class<MasterPanel> loadPanel = (Class<MasterPanel>) Class.forName(packageName + "." + curPanel);
Constructor<MasterPanel> constructPanel = loadPanel.getConstructor(new Class[]{Scene.class});
MasterPanel newPanel = constructPanel.newInstance(new Object[]{theScene});
if (newPanel != null)
tabPane.addTab(newPanel.name, newPanel);
}