Java 具有自定义界面的插件
Java Plugins With A Custom Interface
喜欢 spigot/bukkit 插件 id 喜欢能够在文件中加载 jar 并加载它们的 classes。我设法使它与 java class 加载器一起工作,但是 class 必须扩展一个可运行的程序才能工作。我喜欢为每个插件(jar)实现自己的自定义界面。所以我可以拥有在插件加载时获得 运行 的函数等等。如果有人知道如何做到这一点,请告诉我。
插件结构
插件是一个 .jar
文件。该插件有一个包含插件属性的 plugin.properties 文件。
看起来像这样:
plugin.main=com.example.plugins.ExamplePlugin
plugin.name=Example Plugin
plugin.description=Test 123
plugin.version=1.0
该文件包含主要 class、插件名称、描述和版本。
插件必须有一个继承自抽象插件 class 的 class。这算作主要class.
代码结构
让我们从 Plugin
-class:
开始
package com.example.plugins;
public abstract class Plugin {
protected PluginProperty property;
public abstract void onEnable();
public abstract void onDisable();
public PluginProperty getProperty() {
return property;
}
public void setProperty(PluginProperty property) {
this.property = property;
}
}
如您所见,我在这里选择了摘要 class。
class包含两个抽象方法(onEnable
和onDisable
)。该插件还有一个 PluginProperty
对象。 Spigot 中这个 class 的等价物是 JavaPlugin
.
我们来看看PluginProperty
class.
package com.example.plugins;
public class PluginProperty {
private String main;
private String name;
private String description;
private double version;
public PluginProperty(String main, String name, String description, double version) {
this.main = main;
this.name = name;
this.description = description;
this.version = version;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getVersion() {
return version;
}
public void setVersion(double version) {
this.version = version;
}
}
这个 class 具有插件的所有必要属性。这里的大部分内容都是不言自明的,但我还是想讨论一下 main
.
该字符串包含插件的主插件名称 class。这和Spigot.
中的plugin.yml中的main
基本相同
装载机
这里是PluginLoader
-class:
package com.example.plugins;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Properties;
import java.util.zip.ZipException;
public class PluginLoader {
private static PluginProperty loadPluginProperties(File file) throws ZipException, IOException {
URL url = file.toURI().toURL();
String jarURL = "jar:" + url +"!/plugin.properties";
InputStream input;
URL inputURL = new URL(jarURL);
JarURLConnection conn = (JarURLConnection)inputURL.openConnection();
input = conn.getInputStream();
Properties property = new Properties();
property.load(input);
String main = property.getProperty("plugin.main");
String name = property.getProperty("plugin.name");
String description = property.getProperty("description");
double version = Double.parseDouble(property.getProperty("plugin.version"));
return new PluginProperty(main, name, description, version);
}
public static Plugin loadPlugin(File file) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
if(!file.exists()) {
return null;
}
PluginProperty property = loadPluginProperties(file);
URL url = file.toURI().toURL();
String jarURL = "jar:" + url + "!/";
URL urls[] = {new URL(jarURL)};
URLClassLoader ucl = new URLClassLoader(urls);
Plugin plugin = (Plugin) Class.forName(property.getMain(), true, ucl).getDeclaredConstructor().newInstance();
plugin.setProperty(property);
return plugin;
}
}
私有 loadPluginProperties
方法加载插件属性和 returns 所需的对象。 loadPlugin
方法将属性中指定的主要 class 加载到对象中并 returns 它。
示例
我只是给了你插件系统的基本框架。但是你应该如何使用它呢?让我们从一个示例加载程序开始。
这里是Main
-class:
package com.example.plugins;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static List<Plugin> plugins = new ArrayList<Plugin>();
public static void main(String[] args) {
File[] pluginFiles = new File("plugins").listFiles();
//Load plugins
for(File f : pluginFiles) {
if(f.isDirectory()) {
continue;
}
if(!f.getName().endsWith(".jar")) {
continue;
}
Plugin p = null;
try {
p = PluginLoader.loadPlugin(f);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | IOException e) {
System.err.println("Failed to load plugin!");
e.printStackTrace();
}
Main.plugins.add(p);
}
//Enable plugins
for(Plugin p : plugins) {
p.onEnable();
}
//Disable plugins
for(Plugin p : plugins) {
p.onDisable();
}
}
}
我不会在这里详细介绍,因为我认为它很容易解释。有问题可以在评论里问我哦
将之前写成JAR导出后,添加到新项目中的class路径中。不要忘记创建一个 plugin.properties
文件。
这是与上面指定的 .properties
文件兼容的示例插件:
package com.example.plugins;
public class ExamplePlugin extends Plugin {
@Override
public void onEnable() {
System.out.println("Hello world!");
}
@Override
public void onDisable() {
}
}
当我导出此插件并将其放入插件文件夹时,我得到以下输出:
Hello world!
结束
建议使用 JSON 或 YAML,XML 等,而不是内置的 Java 属性 文件。这是插件的基本结构。玩得开心!
喜欢 spigot/bukkit 插件 id 喜欢能够在文件中加载 jar 并加载它们的 classes。我设法使它与 java class 加载器一起工作,但是 class 必须扩展一个可运行的程序才能工作。我喜欢为每个插件(jar)实现自己的自定义界面。所以我可以拥有在插件加载时获得 运行 的函数等等。如果有人知道如何做到这一点,请告诉我。
插件结构
插件是一个 .jar
文件。该插件有一个包含插件属性的 plugin.properties 文件。
看起来像这样:
plugin.main=com.example.plugins.ExamplePlugin
plugin.name=Example Plugin
plugin.description=Test 123
plugin.version=1.0
该文件包含主要 class、插件名称、描述和版本。
插件必须有一个继承自抽象插件 class 的 class。这算作主要class.
代码结构
让我们从 Plugin
-class:
package com.example.plugins;
public abstract class Plugin {
protected PluginProperty property;
public abstract void onEnable();
public abstract void onDisable();
public PluginProperty getProperty() {
return property;
}
public void setProperty(PluginProperty property) {
this.property = property;
}
}
如您所见,我在这里选择了摘要 class。
class包含两个抽象方法(onEnable
和onDisable
)。该插件还有一个 PluginProperty
对象。 Spigot 中这个 class 的等价物是 JavaPlugin
.
我们来看看PluginProperty
class.
package com.example.plugins;
public class PluginProperty {
private String main;
private String name;
private String description;
private double version;
public PluginProperty(String main, String name, String description, double version) {
this.main = main;
this.name = name;
this.description = description;
this.version = version;
}
public String getMain() {
return main;
}
public void setMain(String main) {
this.main = main;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public double getVersion() {
return version;
}
public void setVersion(double version) {
this.version = version;
}
}
这个 class 具有插件的所有必要属性。这里的大部分内容都是不言自明的,但我还是想讨论一下 main
.
该字符串包含插件的主插件名称 class。这和Spigot.
中的plugin.yml中的main
基本相同
装载机
这里是PluginLoader
-class:
package com.example.plugins;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.net.JarURLConnection;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Properties;
import java.util.zip.ZipException;
public class PluginLoader {
private static PluginProperty loadPluginProperties(File file) throws ZipException, IOException {
URL url = file.toURI().toURL();
String jarURL = "jar:" + url +"!/plugin.properties";
InputStream input;
URL inputURL = new URL(jarURL);
JarURLConnection conn = (JarURLConnection)inputURL.openConnection();
input = conn.getInputStream();
Properties property = new Properties();
property.load(input);
String main = property.getProperty("plugin.main");
String name = property.getProperty("plugin.name");
String description = property.getProperty("description");
double version = Double.parseDouble(property.getProperty("plugin.version"));
return new PluginProperty(main, name, description, version);
}
public static Plugin loadPlugin(File file) throws IOException, InstantiationException, IllegalAccessException, ClassNotFoundException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
if(!file.exists()) {
return null;
}
PluginProperty property = loadPluginProperties(file);
URL url = file.toURI().toURL();
String jarURL = "jar:" + url + "!/";
URL urls[] = {new URL(jarURL)};
URLClassLoader ucl = new URLClassLoader(urls);
Plugin plugin = (Plugin) Class.forName(property.getMain(), true, ucl).getDeclaredConstructor().newInstance();
plugin.setProperty(property);
return plugin;
}
}
私有 loadPluginProperties
方法加载插件属性和 returns 所需的对象。 loadPlugin
方法将属性中指定的主要 class 加载到对象中并 returns 它。
示例
我只是给了你插件系统的基本框架。但是你应该如何使用它呢?让我们从一个示例加载程序开始。
这里是Main
-class:
package com.example.plugins;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static List<Plugin> plugins = new ArrayList<Plugin>();
public static void main(String[] args) {
File[] pluginFiles = new File("plugins").listFiles();
//Load plugins
for(File f : pluginFiles) {
if(f.isDirectory()) {
continue;
}
if(!f.getName().endsWith(".jar")) {
continue;
}
Plugin p = null;
try {
p = PluginLoader.loadPlugin(f);
} catch (InstantiationException | IllegalAccessException | ClassNotFoundException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | IOException e) {
System.err.println("Failed to load plugin!");
e.printStackTrace();
}
Main.plugins.add(p);
}
//Enable plugins
for(Plugin p : plugins) {
p.onEnable();
}
//Disable plugins
for(Plugin p : plugins) {
p.onDisable();
}
}
}
我不会在这里详细介绍,因为我认为它很容易解释。有问题可以在评论里问我哦
将之前写成JAR导出后,添加到新项目中的class路径中。不要忘记创建一个 plugin.properties
文件。
这是与上面指定的 .properties
文件兼容的示例插件:
package com.example.plugins;
public class ExamplePlugin extends Plugin {
@Override
public void onEnable() {
System.out.println("Hello world!");
}
@Override
public void onDisable() {
}
}
当我导出此插件并将其放入插件文件夹时,我得到以下输出:
Hello world!
结束
建议使用 JSON 或 YAML,XML 等,而不是内置的 Java 属性 文件。这是插件的基本结构。玩得开心!