我有一个我正在研究的项目,在这个项目中,我想让开发人员能够包含他们自己的插件,而无需更改整个代码。
这是我迄今为止开发的内容。 这是插件正在使用的接口。
package com.pennion.pennpad;
public interface action{
void doAction();
}
这是加载插件的主要代码。
Map menuMap=new HashMap();
Map actionCommands=new HashMap();
public void load3rdPartyMenu() throws Exception{
String userHome=System.getProperty("user.home");
String sep=File.getSeparator();
String fileString=userHome+sep+"pennion"+sep+"pennpad"+sep+"plugins"+sep+"plugins.conf";
File cfgFile=new File(fileString);
BufferedReader in=new BufferedReader(new InputStreamReader(new FileStreamReader(cfgFile)));
String ln="";
boolean menuFound=false;
while((ln=in.readLine())!=null){
if(!menuFound){
if(ln.equals("//!==Menu!==//")){
menuFound=true;
} else{
menuFound=false;
}
} else{
String pluginName="";
String pluginDescription="";
String KeyMask="";
String[] split=ln.split("||");
pluginName=split[0];
KeyMask=split[1];
pluginDescription=split[2];
ClassLoader pluginLoader=ClassLoader.getClassLoader();
Class c=pluginLoader.loadClass("com.pennion.3rdparty."+pluginName);
Map keyMap=new HashMap();
String[] kmSplit=KeyMask.split("+");
if(kmSplit[0].equals("CTRL")){
keyMap.put("ActionEvent",ActionEvent.CTRL_MASK);
} else if(kmSplit[0].equals("SHIFT")){
keyMap.put("ActionEvent",ActionEvent.SHIFT_MASK);
} else if(kmSplit[0].equals("ALT")){
keyMap.put("ActionEvent",ActionEvent.ALT_MASK);
} else if(kmSplit[0].equals("ALT_CTRL")||kmSplit[0].equals("CTRL_ALT")){
keyMap.put("ActionEvent",ActionEvent.CTRL_MASK+ActionEvent.ALT_MASK);
} else if(kmSplit[0].equals("SHIFT_CTRL")||kmSplit[0].equals("CTRL_SHIFT")){
keyMap.put("ActionEvent",ActionEvent.CTRL_MASK+ActionEvent.SHIFT_MASK);
} else if(kmSplit[0].equals("ALT_SHIFT")||kmSplit[0].equals("SHIFT_ALT")){
keyMap.put("ActionEvent",ActionEvent.SHIFT_MASK+ActionEvent.ALT_MASK);
}
keyMap.put("KeyBind",getKeyBinding(kmSplit[1]));
this.addMenuItem("Plugin",pluginName,keyMap.get("KeyBind"),keyMap.get("ActionEvent"),keyMap.get("KeyBind"),pluginName,c);
}
}
}
public int getKeyBinding(String k){
if(k.equals("A")){
return KeyEvent.VK_A;
} else if(k.equals("B")){
return KeyEvent.VK_B;
} else if(k.equals("C")){
return KeyEvent.VK_C;
} else if(k.equals("D")){
return KeyEvent.VK_D;
} else if(k.equals("E")){
return KeyEvent.VK_E;
} else if(k.equals("F")){
return KeyEvent.VK_F;
} else if(k.equals("G")){
return KeyEvent.VK_G;
} else if(k.equals("H")){
return KeyEvent.VK_H;
} else if(k.equals("I")){
return KeyEvent.VK_I;
} else if(k.equals("J")){
return KeyEvent.VK_J;
} else if(k.equals("K")){
return KeyEvent.VK_K;
} else if(k.equals("L")){
return KeyEvent.VK_L;
} else if(k.equals("M")){
return KeyEvent.VK_M;
} else if(k.equals("N")){
return KeyEvent.VK_N;
} else if(k.equals("O")){
return KeyEvent.VK_O;
} else if(k.equals("P")){
return KeyEvent.VK_P;
} else if(k.equals("Q")){
return KeyEvent.VK_Q;
} else if(k.equals("R")){
return KeyEvent.VK_R;
} else if(k.equals("S")){
return KeyEvent.VK_S;
} else if(k.equals("T")){
return KeyEvent.VK_T;
} else if(k.equals("U")){
return KeyEvent.VK_U;
} else if(k.equals("V")){
return KeyEvent.VK_V;
} else if(k.equals("W")){
return KeyEvent.VK_W;
} else if(k.equals("X")){
return KeyEvent.VK_X;
} else if(k.equals("Y")){
return KeyEvent.VK_Y;
} else if(k.equals("Z")){
return KeyEvent.VK_Z;
} else if(k.equals("1")){
return KeyEvent.VK_1;
} else if(k.equals("2")){
return KeyEvent.VK_2;
} else if(k.equals("3")){
return KeyEvent.VK_3;
} else if(k.equals("4")){
return KeyEvent.VK_4;
} else if(k.equals("5")){
return KeyEvent.VK_5;
} else if(k.equals("6")){
return KeyEvent.VK_6;
} else if(k.equals("7")){
return KeyEvent.VK_7;
} else if(k.equals("8")){
return KeyEvent.VK_8;
} else if(k.equals("9")){
return KeyEvent.VK_9;
} else if(k.equals("0")){
return KeyEvent.VK_0;
} else{
return 0;
}
}
我需要一种将加载的类强制转换为动作的方法,因为到目前为止,它被编译器视为一个类,无法添加到actionCommands hashmap中。
是否有更简单的方法来处理加载的String要求哪个KeyEvent?
答案 0 :(得分:7)
你不能直接将类强制转换为某种东西。
您可以创建它的对象,然后将其投射到您的界面。
Object obj = clazz.newInstance();
Action actionObj = (Action) obj;
遵循惯例,类名以大写字母开头。
答案 1 :(得分:4)
到目前为止,在您展示的代码中,您只有Class
,而不是该类的实例。
在某些时候,您需要从Class
构建一个实例;该实例是您将投射到Action
的内容。
/* Load the plugin class. */
Class<?> clz = Class.forName("com.y.plugins.MyCustomAction");
/* Make sure the named class is the right type. */
Class<? extends Action> sub = clz.asSubclass(Action.class);
/* Get the default constructor. */
Constructor<? extends Action> ctor = sub.getConstructor();
/* Create an instance of "MyCustomAction". */
Action custom = ctor.newInstance();
答案 2 :(得分:0)
对于您的第一个问题,您必须创建已加载类的实例,然后将其转换为..
所以,
cInstance = c.newInstance();
((action)cInstance).doAction();
对于你的第二个问题,我想不出更快的方法将字符串解码为静态变量。