在java中加载一个类作为组件

Posted

技术标签:

【中文标题】在java中加载一个类作为组件【英文标题】:Loading a class as a component in java 【发布时间】:2011-06-02 08:30:56 【问题描述】:

我正在制作一个程序,允许您在其主窗口中添加任何扩展 java.awt.Componentjavax.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)

【问题讨论】:

【参考方案1】:

教程http://download.oracle.com/javase/tutorial/uiswing/components/toolbar.html 给出了如何添加按钮的示例。建议您在您的环境中运行和工作。然后您应该能够通过类比将其扩展到您自己的组件。

【讨论】:

我知道如何制作组件并将它们添加到工具栏;那是儿戏。我想知道如何将第三方类文件作为组件添加到工具栏,而我唯一知道的是类文件在计算机上的位置。请在发布答案之前阅读整个问题。 在你成为试图破译它的人的混蛋之前,请先问一个清晰连贯的问题。 我在评论中没有说问题中没有提到的内容 您添加了您希望第三方组件使用此功能的声明,而不是您自己的组件。因此,当您没有提出明确的问题时,请不要这么快发表评论或判断,尤其是考虑到您在收到问题答案时懒得阅读 API 的发帖历史。 @Supuhstar。 @Falmani 和 @camickr 制作了有价值的 cmets。你最初的帖子只包含 4 行,措辞很糟糕,没有明确的问题。我试图弄清楚你想要什么 - 我的答案是针对可能需要帮助但不知道教程存在的人。没有理由粗鲁和投反对票。【参考方案2】:

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

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.newInstance(...)创建对象。

【讨论】:

谢谢。这看起来很完美,我会尝试看看这是否有效。现在,我想知道......如果类的名称是计算机中的路径,这会起作用吗?这就是它的输入方式。【参考方案3】:

问题

这里的问题可以从堆栈跟踪中的以下消息中找到:

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) 采用的 name 是应加载的类的完全限定类名。例如,如果我们要加载JPanel 类,我们必须提供"javax.swing.JPanel"不是class 文件的完整路径。

解决方案

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

为了做到这一点,我们必须

    在classpath 中包含class 文件。 为Class.forName 类提供完全限定的类名以获得Class<?> 对象。 使用reflection 实例化Class<?> 的对象。

执行 (1) 将成为 Java 虚拟机能够找到应在 (2) 中加载的类的要求——不在类路径中的 class 文件不会在运行时可用。

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

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

【讨论】:

假设最终项目是单个 jar 文件 (TinyExplorer.jar),并且它位于 C:\Users\Username\Desktop\TinyExplorer.jar 中,附加组件应该在哪里放置类,jar 应该如何查找它? @Supuhstar:如果目标类包含在 JAR 中,那么只要 JAR 在类路径中,那么只需要完全限定的类名。

以上是关于在java中加载一个类作为组件的主要内容,如果未能解决你的问题,请参考以下文章

无法在标记为 @SpringBootTest 的组件测试中加载 @Configuration 类

Storybook 不会在 Vue 项目的组件中加载 SVG

NuxtJS|在头组件中加载组件

在 jFrame 中加载带有图像的面板:组件必须为非空

React Router 在 else 中加载任何一个组件

如何在 FMX 组件中加载资源