在java中将类作为组件加载

时间:2011-01-01 23:23:59

标签: java swing reflection components

我正在制作一个程序,允许您在其主窗口中添加任何将java.awt.Component扩展到javax.swing.JToolBar的类文件。我创建了一个测试类,它只是一个名为“test.class”的空javax.swing.JButton。当我所知道的是这个类文件存储在计算机上的什么位置时,如何将其作为我javax.swing.JToolBar中的一个组件加载到程序中?

或者:假设最终项目是一个单独的jar文件(TinyExplorer.jar),并且它位于C:\ Users \ Username \ Desktop \ TinyExplorer.jar中,应该在哪里添加附加类那罐子应该怎么找呢?

修改


我已经实现了以下代码:

      if (addOnFile.exists())
      {
        System.out.println(addOnFile.getName() + " is there!");
        java.util.Scanner scan = new java.util.Scanner(addOnFile);
        while (scan.hasNextLine())
        {
          String str = scan.nextLine();
          System.out.println(str);
          java.io.File f = new java.io.File(str);
          if (f.exists())
          {
            try
            {
              java.awt.Component comp;
              Class cls = Class.forName(str);
              Object obj = cls.newInstance();

              if (obj instanceof java.awt.Component)
              {
                comp = (java.awt.Component)obj;
              }
            }
            catch (Exception err)
            {
              err.printStackTrace();
            }
          }
        }
      }

但每次运行时,我都会遇到以下异常:

java.lang.ClassNotFoundException: G:\Java\NetBeansProjects\TinyExplorer\build\classes\testAddOn\test.class
        at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:169)
        at explorer.Frame$24.run(Frame.java:1091)

3 个答案:

答案 0 :(得分:1)

听起来你想要这样的东西:

Component comp = null;
String cls_name = "test";  // include your package ie "java.lang.String"

try {
    Class cls = Class.forName(cls_name);
    Object obj = cls.newInstance();

    if (obj instanceof Component) {
        comp = (Component) obj;
    }
}
catch (Exception err) {
    err.printStackTrace();
}

setLayout(new BorderLayout() );

JToolBar toolbar = new JToolBar();
if (comp != null) {
    toolbar.add(comp);
}

add(toolbar, BorderLayout.NORTH);

Class.forName()Class.newInstance()实例化您的新对象。 try块有很多异常的可能性,你可能想要做得更好。如果您的类没有默认构造函数,那么这将无效,您需要通过反射获取Constructor对象,并通过调用Constructor.newInstance(...)来创建对象。

答案 1 :(得分:1)

问题

此处的问题可以从stacktrace中的以下消息中找到:

java.lang.ClassNotFoundException: G:\Java\NetBeansProjects\TinyExplorer\build\classes\testAddOn\test.class

这表明代码正在尝试查找实际上是class文件的文件路径的类名。这是Class.forName方法的错误用法。

Class.forName方法(link to the Java API Specification of the method)所采用的名称是应该加载的类的完全限定类名。例如,如果我们要加载JPanel类,我们必须提供"javax.swing.JPanel"而不是 class文件的完整路径。

解决方案

从查看代码开始,意图似乎是class文件中包含的完整文件系统路径为G:\Java\NetBeansProjects\TinyExplorer\build\classes\testAddOn\test.class的类应该在运行时加载。

为了做到这一点,必须

  1. classpath
  2. 中加入class个文件
  3. 将完全限定的类名提供给Class.forName类以获取Class<?>对象。
  4. 使用reflection
  5. 实例化Class<?>的对象

    执行(1)将要求Java虚拟机能够找到应该加载的类(2) - 不在类路径中的class文件不是将在运行时提供。

    在类路径中包含文件通常是IDE中的某种类型的构建配置,或者必须告诉javac添加path to the classpath

    点(2)和(3)似乎已在给定代码中部分实现,并且看起来正朝着正确的路径前进。

答案 2 :(得分:0)

教程http://download.oracle.com/javase/tutorial/uiswing/components/toolbar.html提供了如何添加按钮的示例。建议你在你的环境中运行并运行。然后你应该通过类比你的组件来扩展它。