示範如何使用 JDK 6 內建 Script Engine 為 Java Swing 應用建立外掛機制,透過 JavaScript 動態修改選單、載入外部元件,實現輕量級腳本化擴展。
interface Plugin {
String getName(), getDescription();
void putValueToContext(String key, Object obj);
Object execute(String function, Object... args);
List<String> getAvailiableFunctions();
}
interface PluginManager {
void install/uninstall/activate/deactivate(Plugin);
Plugin getPlugin(String name);
List<Plugin> listPlugins();
}
TodoPluginManager:單例管理外掛清單。TodoPlugin:包裝 ScriptEngine (Rhino JS),載入 .js 檔,提供 execute() 呼叫 JS 函式。RuntimeEnv:靜態取得 ScriptEngine 與 Invocable。initEnv() 建立 menubar.js 外掛,放入 pluginList 至 Context。MainFrame 將 JMenuBar 實例傳給外掛 _customizeMenuBar_(menuBar)。JavaAdapter 實作 Java 介面 (如 ActionListener)。importPackage(javax.swing);
importPackage(java.awt.event);
function buildPluginMenu() {
var menu = new JMenu("Plugin");
var item = new JMenuItem("list plugins");
item.addActionListener(new JavaAdapter(ActionListener, {
actionPerformed: function(e) {
var frame = new JFrame("plugins list");
var pane = new JEditorPane();
var s = "";
for (var i=0; i<pluginList.size(); i++) {
var p = pluginList.get(i);
s += p.getName() + ": " + p.getDescription() + "\n";
}
pane.setText(s); pane.setEditable(false);
frame.add(pane); frame.setSize(200,200); frame.setVisible(true);
}
}));
menu.add(item);
return menu;
}
function _customizeMenuBar_(menuBar) {
menuBar.add(buildPluginMenu());
menuBar.add(buildHelpMenu()); // 第二個腳本整合外部 HelpDialog
}
importPackage(Packages.org.someone.dialog);
var dlg = new HelpDialog(null, "This is Help");
無需修改 Java 代碼即可動態載入第三方 Swing 元件。