Plugins für eigenes Programm

SeeSharpNewBee

Erfahrenes Mitglied
Hi,

ich hätte eine Frage bez. Plugins, und zwar:

Ich möchte ein Programm schreiben, dessen Hauptfenster ist ein MDI Fenster. In dem MDI Fenster gibt es eine ToolBar (wenn das möglich ist) und das Programm soll auf einen Ordner zugreifen, und je nachdem welche Jars da drinnen liegen, diese "laden" und in der Toolbar ein en neuen Punkt hinzufügen.

Geht das?

Danach soll bei einem klick auf den neu hinzugefügten button ein Fenster aus diesem geladenen Jar aufgerufen und in dem MDI Fenster als Child angezeigt werden.

Geht das?

Danke!
 
Ja klar geht das.

Du sucht dann halt in dem Ordner nach allen Dateien die mit Jar enden und öffnest diese mittels JarFile und itererierst über die Einträge wobei du alle anschaust die mit class Ende. Dann erstellt du dir einen URLClassLoader mit dem Pfad zu dem Jar und mit
class.forName instanziierst du die Klassen und schaust ob diese ein Klasse implementieren die du verwenden kannst. Diese Klassen merkst du dir in einer Liste.

Alle Jars die in Frage kommende Klassen enthalten kannst du in einem URLClassLoader zusammenfassen und dann darüber bei Klicken auf Neu die entsprechenden Klassen die Fenster erstellen aufrufen.
 
Eventuell hilft es, eine Plugin-Klasse zu erstellen, um sämtliche PLugins davon abzuleiten und dazu eventuell noch eine Namenskonvention einzuführen, dass das .jar-file genauso heissen muss, wie die (Haupt-)Klasse des Plugins.

Damit sollte es wesentlich eifnacher sein, das PLugin in das Programm einzubinden.
 
Halli und Hallo,
vor einigen Jahren habe ich sowas auch mal gebraucht, und es entstand dies hier. vielleicht hilft es Dir ja weiter.
Code:
mport java.io.File;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Vector;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import javax.swing.JProgressBar;

/**
* ClassCollector sammelt Klassen einer Gegebenen unter Vorgabe eines
* Unterverzeichnises, welches direkt unter dem Package der gegebenen Klasse
* liegt.
* Diese Klasse ist zum dynamischen Zuladen von Klassen geeignet. Auf diese Weise
* können z.B. Unterdialoge zur Laufzeit einem Übergeordneten Panel zugeordnet werden
*/

public class ClassCollector
{
    Vector m_classNames = new Vector();
    String m_path;
    String m_packageName;
    String m_subPackageName;
    String m_lastQual;
    Class  m_class;



    public ClassCollector(Class klasse, String lastQualifier)
    {
        m_class          = klasse;
        m_path           = m_class.getResource("").getFile();
        m_lastQual       = lastQualifier;
        m_packageName    = m_class.getName().substring(0, m_class.getName().lastIndexOf('.'));
        if (m_lastQual!=null && m_lastQual.length()>0)
        {
            m_subPackageName = m_packageName + '.' + m_lastQual;
        }
        else
        {
            m_subPackageName = m_packageName;
        }

        try
        {
            collectClassNames();
        }
        catch (Exception e)
        {
            MExceptionHandler.handleException(e);
        }
    } // end of ClassCollector(Class, String)

    protected void collectClassNames() throws Exception
    {
        Vector classFileNames = new Vector();

        if (m_class.getResource("").getProtocol().equalsIgnoreCase("jar"))
        {
            URLConnection urlConn = m_class.getResource("").openConnection();
            if (!(urlConn instanceof JarURLConnection))
            {
                throw new Exception("Is jar file but has no JarURLConnection");
            }
            JarURLConnection jarConn = (JarURLConnection)urlConn;
            JarFile jarFile = jarConn.getJarFile();
            for (Enumeration e = jarFile.entries(); e.hasMoreElements(); )
            {
                JarEntry currentEntry = (JarEntry)e.nextElement();
                if (currentEntry.getName().startsWith(m_path)
                    &&!currentEntry.isDirectory())
                {
                    classFileNames.add(currentEntry.getName());
                } // end of if
            } // end of for e
        } // end of if(Classe in einer .jar Datei)
        else
        {
            URL url;

            url = m_class.getResource("/"+m_subPackageName.replace('.','/'));
//            System.out.println("2. url="+url.toString());
            if (url==null)
            {
                throw new Exception("Kann "+m_lastQual+" Verzeichnis nicht finden"+
                                    "\nres="+m_class.getResource(""));
            }
            File demosDir = new File(url.getFile());

            if (demosDir==null)
            {
                throw new Exception("Kann "+m_lastQual+" Verzeichnis nicht finden"+
                                    "\n url="+url);
            }

            if (!demosDir.isDirectory())
            {
                throw new Exception(m_lastQual+" ist kein Verzeichnis"+
                                    "\n url="+url+
                                    "\n file="+demosDir);
            }
            String[] list = demosDir.list();

            for (int i = 0; i<list.length; i++)
            {
                String fullName = m_subPackageName+"."+list[i];
                classFileNames.add(fullName);
            }
        } // end of if else (Classe in einer .jar Datei)

        for (int i = 0; i<classFileNames.size(); i++)
        {
            String currentName = (String)classFileNames.get(i);
            if (currentName.indexOf("$")==-1 && currentName.endsWith(".class"))
            {
                // remove trailing ".class"
                currentName = currentName.substring(0, currentName.length()-6);
                StringBuffer tmp = new StringBuffer(currentName);
                for (int j = 0; j<tmp.length(); j++)
                {
                    if (tmp.charAt(j)=='/'||tmp.charAt(j)=='\\')
                        tmp.setCharAt(j, '.');
                }
                m_classNames.add(tmp.toString());
            }
        }

    } // end of collectClassNames()

    public List loadClasses(JProgressBar progressBar)
    {
        List loadedClasses = new ArrayList();
        int count = progressBar.getValue();

        for (int i = 0; i<m_classNames.size(); i++)
        {
            String className = (String)m_classNames.get(i);
            String progressName = className.substring(m_subPackageName.length()+1,
                className.length());
            progressBar.setValue(count++);
            progressBar.setString("Lade "+progressName);
            try
            {
                Class currentClass = Class.forName(className);
                Object obj = currentClass.newInstance();

                if (m_class.isInstance(obj))
                {
                    loadedClasses.add(obj);
                }

            }
            catch (Exception e)
            {
                MExceptionHandler.handleException(e);
            }
        }
        return loadedClasses;
    } // end of loadClasses(JProgressBar)

    public List loadClasses()
    {
        List loadedClasses = new ArrayList();

        for (int i = 0; i<m_classNames.size(); i++)
        {
            try
            {
                Class currentClass = Class.forName((String)m_classNames.get(i));
                if (!currentClass.isInterface())
                {
                    Object obj = currentClass.newInstance();
                    if(m_class.isInstance(obj))
                    {
                        loadedClasses.add(obj);
                    }
                }
            }
            catch (Exception e)
            {
                MExceptionHandler.handleException(e);
            }
        }
        return loadedClasses;
    } // end of loadClasses()

    public String[] getClassNames()
    {
        return (String[])m_classNames.toArray((Object[])new String[0]);
    }

    public String getClassName(int i)
    {
        return (String)m_classNames.get(i);
    }

} // end of ClassCollector

Mit ein paar Anpassungen kannst Du das Teil vielleicht einsetzen.

viel Spaß

Takidoso
 
Zurück