在java中将类加载为组件
我正在制作一个程序,允许您添加任何将 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)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题
这里的问题可以从堆栈跟踪中的以下消息中找到:
这表明代码正在尝试查找实际上是
class
的文件路径的类名文件。这是Class.forName
方法。Class.forName
方法的名称 (指向该方法的 Java API 规范的链接) 是一个完全限定的类名应该加载的类。例如,如果我们想要加载JPanel
类,我们必须提供"javax.swing.JPanel"
,不是完整的class
文件的路径。解决方案
从代码来看,其意图似乎是
class
文件中包含的类,其完整文件系统路径为G:\Java\ NetBeansProjects\TinyExplorer\build\classes\testAddOn\test.class
应在运行时加载。为此,必须
Class.forName
类以获取Class
对象。Class
的对象。执行 (1) 将是 Java 虚拟机能够找到应在 (2) 中加载的类的要求 - 不在类路径中的
class
文件不会被加载。将在运行时可用。在类路径中包含该文件通常是 IDE 中某种类型的构建配置,或者必须告诉
javac
添加 类路径的路径。第 (2) 点和第 (3) 点似乎已经在给定代码中部分实现,并且看起来正在朝着正确的方向前进。
The issue
The issue here can be found from the following message in the stacktrace:
This indicates that the code is trying to find a class name that's actually a file path to the
class
file. This is an incorrect usage of theClass.forName
method.The name that the
Class.forName
method (link to the Java API Specification of the method) takes is a fully-qualified class name of the class that should be loaded. For example, if we want to load theJPanel
class, we'd have to provide"javax.swing.JPanel"
, not a full path to theclass
file.The solution
From looking at the code, the intention seems to be that the class contained in the
class
file with the full file system path ofG:\Java\NetBeansProjects\TinyExplorer\build\classes\testAddOn\test.class
should be loaded at runtime.In order to do so, one must
class
file in the classpath.Class.forName
class to obtain aClass<?>
object.Class<?>
using reflection.Performing (1) is going to be a requirement for the Java virtual machine to be able to find the class that should be loaded in (2) -- a
class
file that is not in the classpath is not going to be available during runtime.Including the file in the classpath is usually going to be some type of build configuration in your IDE, or having to tell
javac
to add a path to the classpath.Points (2) and (3) appears to be already partially implemented in the given code, and appears like it is heading toward the right path.
听起来您想要这样的东西:
Class.forName()
和Class.newInstance()
实例化您的新对象。 try 块很可能会出现异常,您可能希望做得比包罗万象更好。如果您的类没有默认构造函数,则这将不起作用,您需要通过反射获取 Constructor 对象,并通过调用Constructor.newInstance(...)
。It sounds like you want something like this:
Class.forName()
andClass.newInstance()
instantiate your new object. The try block has a lot of potential for exceptions, and you may want to do better than a catch-all. If your class doesn't have a default constructor, this won't work, and you'll need to get a Constructor object via reflection, and create the object by callingConstructor.newInstance(...)
.教程 http://download.oracle.com/javase/tutorial/uiswing /components/toolbar.html 提供了如何添加按钮的示例。建议您在您的环境中运行并工作。然后您应该能够通过类比到您自己的组件来扩展它。
The tutorial http://download.oracle.com/javase/tutorial/uiswing/components/toolbar.html gives examples of how to add buttons. Suggest you get this running and working in your environment.You should then be ab le to extend this by analogy to your own compponents.