commit c07515b18c304a2f3cb5bf2c802b872872230a22
Author: dai_48k <1981669259@qq.com>
Date: Tue Apr 1 15:58:54 2025 +0800
init
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..911c624
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,13 @@
+
+# 程序生成
+BKPG/target
+BKPG_DEMO/target
+BKPG_PROTOCAL/target
+PLUGIN_BKPG_GROUP_PROCESS/target
+
+ext/*.jar
+
+
+
+# 个人项目
+PLUGIN_BKPG_Company
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..4c989c1
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/../../../../../:\projects_self\java\BKPG_PROj\.idea/dataSources/
+/dataSources.local.xml
+# Editor-based HTTP Client requests
+/httpRequests/
diff --git a/.idea/artifacts/PLUGIN_BKPG_Company_jar.xml b/.idea/artifacts/PLUGIN_BKPG_Company_jar.xml
new file mode 100644
index 0000000..339d191
--- /dev/null
+++ b/.idea/artifacts/PLUGIN_BKPG_Company_jar.xml
@@ -0,0 +1,8 @@
+
+
+ $PROJECT_DIR$/ext
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/compiler.xml b/.idea/compiler.xml
new file mode 100644
index 0000000..7325d85
--- /dev/null
+++ b/.idea/compiler.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
new file mode 100644
index 0000000..cedf2b2
--- /dev/null
+++ b/.idea/encodings.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml
new file mode 100644
index 0000000..712ab9d
--- /dev/null
+++ b/.idea/jarRepositories.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__junit_junit_4_11.xml b/.idea/libraries/Maven__junit_junit_4_11.xml
new file mode 100644
index 0000000..7ecf64f
--- /dev/null
+++ b/.idea/libraries/Maven__junit_junit_4_11.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
new file mode 100644
index 0000000..4d677a8
--- /dev/null
+++ b/.idea/libraries/Maven__org_hamcrest_hamcrest_core_1_3.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/libraries/Maven__top_dreamcenter_bkpg_BKPG_PROTOCAL_1_0_SNAPSHOT.xml b/.idea/libraries/Maven__top_dreamcenter_bkpg_BKPG_PROTOCAL_1_0_SNAPSHOT.xml
new file mode 100644
index 0000000..bfc8e29
--- /dev/null
+++ b/.idea/libraries/Maven__top_dreamcenter_bkpg_BKPG_PROTOCAL_1_0_SNAPSHOT.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..aa75cb7
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..54a8179
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..e96534f
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,124 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BKPG/BKPG.iml b/BKPG/BKPG.iml
new file mode 100644
index 0000000..c8cf16d
--- /dev/null
+++ b/BKPG/BKPG.iml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BKPG/pom.xml b/BKPG/pom.xml
new file mode 100644
index 0000000..9259af6
--- /dev/null
+++ b/BKPG/pom.xml
@@ -0,0 +1,60 @@
+
+
+
+ 4.0.0
+
+
+ BKPG_PROj
+ top.dreamcenter
+ ${revision}
+
+
+ top.dreamcenter.bkpg
+ BKPG
+
+ BKPG
+
+
+
+ junit
+ junit
+
+
+ top.dreamcenter.bkpg
+ BKPG_PROTOCAL
+ ${revision}
+ compile
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ jar-with-dependencies
+
+ false
+
+
+ top.dreamcenter.bkpg.App
+
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
+
diff --git a/BKPG/src/main/java/top/dreamcenter/bkpg/App.java b/BKPG/src/main/java/top/dreamcenter/bkpg/App.java
new file mode 100644
index 0000000..8c65ea6
--- /dev/null
+++ b/BKPG/src/main/java/top/dreamcenter/bkpg/App.java
@@ -0,0 +1,58 @@
+package top.dreamcenter.bkpg;
+
+import top.dreamcenter.bkpg.ui.MainFrame;
+
+import java.awt.*;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.net.URL;
+
+/**
+ * 应用管理器
+ *
+ */
+public class App
+{
+ public static void main(String[] args){
+ final MainFrame[] mainFrame = {new MainFrame()};
+ mainFrame[0].setVisible(true);
+
+
+ if (SystemTray.isSupported()){
+ URL url = App.class.getClassLoader().getResource("img/icon.png");
+
+
+ Image icon = Toolkit.getDefaultToolkit().createImage(url);
+ SystemTray tray = SystemTray.getSystemTray();
+
+
+ PopupMenu popupMenu = new PopupMenu();
+ MenuItem reloadItem = new MenuItem("Reload");
+ reloadItem.addActionListener(e -> {
+ mainFrame[0].setVisible(false);
+ mainFrame[0].reloadFrame();
+ mainFrame[0].setVisible(true);
+ });
+ MenuItem exitItem = new MenuItem("Exit");
+ exitItem.addActionListener(e -> System.exit(0));
+ popupMenu.add(reloadItem);
+ popupMenu.add(exitItem);
+
+ TrayIcon trayIcon = new TrayIcon(icon, "任务管理器", popupMenu);
+ trayIcon.addMouseListener(new MouseAdapter() {
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ if (e.getButton() == 1) {
+ mainFrame[0].setVisible(!mainFrame[0].isVisible());
+ }
+ }
+ });
+
+ try {
+ tray.add(trayIcon);
+ } catch (AWTException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+}
diff --git a/BKPG/src/main/java/top/dreamcenter/bkpg/entity/MiniAppJListWrap.java b/BKPG/src/main/java/top/dreamcenter/bkpg/entity/MiniAppJListWrap.java
new file mode 100644
index 0000000..31fbc83
--- /dev/null
+++ b/BKPG/src/main/java/top/dreamcenter/bkpg/entity/MiniAppJListWrap.java
@@ -0,0 +1,23 @@
+package top.dreamcenter.bkpg.entity;
+
+import top.dreamcenter.bkpg.protocal.MiniApp;
+
+/**
+ * 应用包装
+ */
+public class MiniAppJListWrap {
+ private MiniApp miniApp;
+
+ public MiniAppJListWrap(MiniApp miniApp) {
+ this.miniApp = miniApp;
+ }
+
+ public MiniApp getMiniApp() {
+ return miniApp;
+ }
+
+ @Override
+ public String toString() {
+ return miniApp.getName();
+ }
+}
diff --git a/BKPG/src/main/java/top/dreamcenter/bkpg/ui/MainFrame.java b/BKPG/src/main/java/top/dreamcenter/bkpg/ui/MainFrame.java
new file mode 100644
index 0000000..dffe732
--- /dev/null
+++ b/BKPG/src/main/java/top/dreamcenter/bkpg/ui/MainFrame.java
@@ -0,0 +1,98 @@
+package top.dreamcenter.bkpg.ui;
+
+import top.dreamcenter.bkpg.entity.MiniAppJListWrap;
+import top.dreamcenter.bkpg.protocal.MiniApp;
+import top.dreamcenter.bkpg.util.MiniAppRegister;
+
+import javax.swing.*;
+import java.awt.*;
+import java.net.URL;
+import java.util.*;
+import java.util.stream.Collectors;
+
+public class MainFrame extends JFrame {
+
+
+ private final HashMap container;
+
+ public MainFrame() {
+
+ container = MiniAppRegister.registerApps();
+
+ // 基础设置
+ setSize(600,400);
+ setLocationRelativeTo(null);
+ setLayout(null);
+ setTitle("JM管理器");
+ setResizable(false);
+ URL resource = MainFrame.class.getClassLoader().getResource("img/icon.png");
+ Image icon = Toolkit.getDefaultToolkit().createImage(resource);
+ setIconImage(icon);
+
+ initializeContent();
+
+ }
+
+ private void initializeContent() {
+
+ // 面板
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.setBounds(156, 2,424,358);
+ panel.setBackground(new Color(250,250,250));
+ panel.add(new JLabel("欢迎使用JM管理器"), BorderLayout.NORTH);
+
+ // 任务列表
+ DefaultListModel model = new DefaultListModel<>();
+ for (Map.Entry next : container.entrySet()) {
+ model.addElement(new MiniAppJListWrap(next.getValue()));
+ }
+ JList list = new JList<>(model);
+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ list.addListSelectionListener(e -> {
+ if (!e.getValueIsAdjusting()){
+ panel.removeAll();
+
+ MiniAppJListWrap entity = list.getSelectedValue();
+
+ panel.add(entity.getMiniApp().getPanel());
+ panel.updateUI();
+ }
+ });
+ JScrollPane tasksPanelS = new JScrollPane(list);
+ tasksPanelS.setBounds(2,2,150,358);
+
+
+ add(tasksPanelS);
+ add(panel);
+ }
+
+ public void reloadFrame() {
+
+ // 1. 保护中的程序列表
+ Map protectedApps = container.entrySet().stream()
+ .filter(item -> item.getValue().protect())
+ .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
+
+ // 2. 新的程序列表
+ HashMap list = MiniAppRegister.registerApps();
+ list.forEach((key, value) -> {
+ if (!protectedApps.containsKey(key)) {
+ protectedApps.put(key, value);
+ }
+ });
+
+ // 放入容器
+ container.clear();
+ container.putAll(protectedApps);
+
+
+
+ getContentPane().removeAll();
+ initializeContent();
+
+ revalidate();
+ repaint();
+
+ }
+}
diff --git a/BKPG/src/main/java/top/dreamcenter/bkpg/util/JarFileFilter.java b/BKPG/src/main/java/top/dreamcenter/bkpg/util/JarFileFilter.java
new file mode 100644
index 0000000..ddab804
--- /dev/null
+++ b/BKPG/src/main/java/top/dreamcenter/bkpg/util/JarFileFilter.java
@@ -0,0 +1,12 @@
+package top.dreamcenter.bkpg.util;
+
+import java.io.File;
+import java.io.FilenameFilter;
+
+public class JarFileFilter implements FilenameFilter {
+
+ @Override
+ public boolean accept(File dir, String name) {
+ return name.endsWith(".jar");
+ }
+}
diff --git a/BKPG/src/main/java/top/dreamcenter/bkpg/util/MiniAppRegister.java b/BKPG/src/main/java/top/dreamcenter/bkpg/util/MiniAppRegister.java
new file mode 100644
index 0000000..2349e9b
--- /dev/null
+++ b/BKPG/src/main/java/top/dreamcenter/bkpg/util/MiniAppRegister.java
@@ -0,0 +1,95 @@
+package top.dreamcenter.bkpg.util;
+
+import top.dreamcenter.bkpg.protocal.MiniApp;
+import top.dreamcenter.bkpg.protocal.MiniAppGroup;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+/**
+ * 应用注册器
+ */
+public class MiniAppRegister {
+ /**
+ * 注册 ext 文件夹下的扩展应用
+ * @return
+ */
+ public static HashMap registerApps() {
+ HashMap miniAppContainer = new HashMap<>();
+
+ Class miniAppClass = MiniApp.class;
+ Class miniAppGroupClass = MiniAppGroup.class;
+
+ // 找到ext 文件夹 并且初始化ext路径类加载器
+ String extDirectory = "ext";
+ File file = new File(extDirectory);
+
+ // 解析ext 目录下的 Jar文件
+ File[] files = file.listFiles(new JarFileFilter());
+ if (files == null) return new HashMap<>();
+
+ // 遍历jar文件
+ for (File tmp : files) {
+ JarFile jarFile = null;
+ try {
+ jarFile = new JarFile("/" + tmp.getAbsoluteFile());
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ // 解析jar包
+ if (jarFile != null) {
+ Enumeration entries = jarFile.entries();
+ while (entries.hasMoreElements()){
+ JarEntry jarEntry = entries.nextElement();
+ // 解析class文件
+ if (jarEntry.getName().endsWith(".class") && !jarEntry.getName().contains("$")){
+ String classRoute = jarEntry.getName().replaceAll("/", ".").replace(".class", "");
+
+ try {
+ // 装载类
+ URLClassLoader loader = new URLClassLoader(new URL[]{tmp.toURI().toURL()});
+ Class> clazz = loader.loadClass(classRoute);
+
+ // 校验是否符合协议
+ if (miniAppClass.isAssignableFrom(clazz)) { // 单应用
+ // 注册进容器
+ Object obj = clazz.getConstructor().newInstance();
+ miniAppContainer.put(classRoute, (MiniApp) obj);
+ } else if(miniAppGroupClass.isAssignableFrom(clazz)){ // 组合应用
+ // 注册进容器
+ Object obj = clazz.getConstructor().newInstance();
+ MiniAppGroup group = (MiniAppGroup) obj;
+ List miniApps = group.getMiniApps();
+
+ // 检查返回值是否为空,如果为空则不处理
+ if (miniApps != null) {
+ for (int i = 0; i < miniApps.size(); i++) {
+ MiniApp app = miniApps.get(i);
+ miniAppContainer.put(classRoute + "-" + app.getName(), app);
+ }
+ }
+
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ }
+ }
+ }
+
+
+ // 返回结果
+ return miniAppContainer;
+ }
+
+}
diff --git a/BKPG/src/main/resources/META-INF/MANIFEST.MF b/BKPG/src/main/resources/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..17375ff
--- /dev/null
+++ b/BKPG/src/main/resources/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0
+Main-Class: top.dreamcenter.bkpg.App
+
diff --git a/BKPG/src/main/resources/img/icon.png b/BKPG/src/main/resources/img/icon.png
new file mode 100644
index 0000000..54c3b2a
Binary files /dev/null and b/BKPG/src/main/resources/img/icon.png differ
diff --git a/BKPG/src/test/java/top/dreamcenter/bkpg/AppTest.java b/BKPG/src/test/java/top/dreamcenter/bkpg/AppTest.java
new file mode 100644
index 0000000..65d435c
--- /dev/null
+++ b/BKPG/src/test/java/top/dreamcenter/bkpg/AppTest.java
@@ -0,0 +1,20 @@
+package top.dreamcenter.bkpg;
+
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+/**
+ * Unit test for simple App.
+ */
+public class AppTest
+{
+ /**
+ * Rigorous Test :-)
+ */
+ @Test
+ public void shouldAnswerWithTrue()
+ {
+ assertTrue( true );
+ }
+}
diff --git a/BKPG_DEMO/BKPG_DEMO.iml b/BKPG_DEMO/BKPG_DEMO.iml
new file mode 100644
index 0000000..71cf44a
--- /dev/null
+++ b/BKPG_DEMO/BKPG_DEMO.iml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BKPG_DEMO/pom.xml b/BKPG_DEMO/pom.xml
new file mode 100644
index 0000000..fd589bc
--- /dev/null
+++ b/BKPG_DEMO/pom.xml
@@ -0,0 +1,36 @@
+
+
+ 4.0.0
+
+
+ BKPG_PROj
+ top.dreamcenter
+ ${revision}
+
+
+ top.dreamcenter.bkpg
+ BKPG_DEMO
+
+
+
+ top.dreamcenter.bkpg
+ BKPG_PROTOCAL
+ ${revision}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+ ${project.parent.basedir}/ext
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp.java b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp.java
new file mode 100644
index 0000000..77e7940
--- /dev/null
+++ b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp.java
@@ -0,0 +1,28 @@
+package top.dreamcenter.bkpg.demo;
+
+import top.dreamcenter.bkpg.demo.ui.MainPanel;
+import top.dreamcenter.bkpg.protocal.MiniApp;
+
+import javax.swing.*;
+
+public class DemoApp implements MiniApp {
+
+ private static final String DEMO_APP = "案例程序";
+
+ @Override
+ public String getName() {
+ return DEMO_APP;
+ }
+
+ @Override
+ public JPanel getPanel() {
+ MainPanel mainPanel = new MainPanel();
+ mainPanel.add(new JLabel(getName()));
+ return mainPanel;
+ }
+
+ @Override
+ public boolean protect() {
+ return false;
+ }
+}
diff --git a/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp2.java b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp2.java
new file mode 100644
index 0000000..f9d097a
--- /dev/null
+++ b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp2.java
@@ -0,0 +1,17 @@
+package top.dreamcenter.bkpg.demo;
+
+import top.dreamcenter.bkpg.protocal.template.ProcessAppTemplate;
+
+public class DemoApp2 extends ProcessAppTemplate {
+ private static final String DEMO_APP = "案例程序2";
+
+ @Override
+ public String getName() {
+ return DEMO_APP;
+ }
+
+ @Override
+ public String getCmdStr() {
+ return "ping 81.70.80.152 -t";
+ }
+}
diff --git a/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp3.java b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp3.java
new file mode 100644
index 0000000..7b9e4f1
--- /dev/null
+++ b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoApp3.java
@@ -0,0 +1,15 @@
+package top.dreamcenter.bkpg.demo;
+
+import top.dreamcenter.bkpg.protocal.template.ProcessAppTemplate;
+
+public class DemoApp3 extends ProcessAppTemplate {
+ @Override
+ public String getName() {
+ return "案例程序3";
+ }
+
+ @Override
+ public String getCmdStr() {
+ return "ipconfig";
+ }
+}
diff --git a/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoGroupApp.java b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoGroupApp.java
new file mode 100644
index 0000000..511690f
--- /dev/null
+++ b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/DemoGroupApp.java
@@ -0,0 +1,35 @@
+package top.dreamcenter.bkpg.demo;
+
+import top.dreamcenter.bkpg.protocal.MiniApp;
+import top.dreamcenter.bkpg.protocal.MiniAppGroup;
+import top.dreamcenter.bkpg.protocal.template.ProcessAppTemplate;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class DemoGroupApp implements MiniAppGroup {
+ @Override
+ public List getMiniApps() {
+
+ List list = new LinkedList<>();
+
+ for (int i = 0; i < 3; i++) {
+ int finalI = i;
+ MiniApp miniApp = new ProcessAppTemplate() {
+ @Override
+ public String getCmdStr() {
+ return "ping www.baidu.com -n " + (finalI + 1);
+ }
+
+ @Override
+ public String getName() {
+ return "GroupDemo" + finalI;
+ }
+ };
+ list.add(miniApp);
+ }
+
+ return list;
+ }
+
+}
diff --git a/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/ui/MainPanel.java b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/ui/MainPanel.java
new file mode 100644
index 0000000..5497877
--- /dev/null
+++ b/BKPG_DEMO/src/main/java/top/dreamcenter/bkpg/demo/ui/MainPanel.java
@@ -0,0 +1,15 @@
+package top.dreamcenter.bkpg.demo.ui;
+
+import javax.swing.*;
+
+public class MainPanel extends JPanel {
+
+ public MainPanel() {
+
+ JLabel label = new JLabel("这是一个demo");
+
+ add(label);
+ setVisible(true);
+ }
+
+}
diff --git a/BKPG_PROTOCAL/BKPG_PROTOCAL.iml b/BKPG_PROTOCAL/BKPG_PROTOCAL.iml
new file mode 100644
index 0000000..04b1188
--- /dev/null
+++ b/BKPG_PROTOCAL/BKPG_PROTOCAL.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/BKPG_PROTOCAL/pom.xml b/BKPG_PROTOCAL/pom.xml
new file mode 100644
index 0000000..e514314
--- /dev/null
+++ b/BKPG_PROTOCAL/pom.xml
@@ -0,0 +1,17 @@
+
+
+ 4.0.0
+
+ top.dreamcenter.bkpg
+ BKPG_PROTOCAL
+ 1.0-SNAPSHOT
+
+
+ UTF-8
+ 8
+ 8
+
+
+
\ No newline at end of file
diff --git a/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/MiniApp.java b/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/MiniApp.java
new file mode 100644
index 0000000..06264b1
--- /dev/null
+++ b/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/MiniApp.java
@@ -0,0 +1,27 @@
+package top.dreamcenter.bkpg.protocal;
+
+import javax.swing.*;
+
+/**
+ * 程序基类
+ */
+public interface MiniApp {
+
+ /**
+ * 获取应用名称
+ * @return 应用名称
+ */
+ String getName();
+
+ /**
+ * 获取应用面板
+ * @return 面板
+ */
+ JPanel getPanel();
+
+ /**
+ * 保护应用,重启的时候是否重新装载
+ * @return
+ */
+ boolean protect();
+}
diff --git a/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/MiniAppGroup.java b/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/MiniAppGroup.java
new file mode 100644
index 0000000..e67c51c
--- /dev/null
+++ b/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/MiniAppGroup.java
@@ -0,0 +1,16 @@
+package top.dreamcenter.bkpg.protocal;
+
+import java.util.List;
+
+/**
+ * 程序组合包
+ */
+public interface MiniAppGroup {
+
+ /**
+ * 获取所有的组合
+ * @return 组合
+ */
+ List getMiniApps();
+
+}
diff --git a/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/template/ProcessAppTemplate.java b/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/template/ProcessAppTemplate.java
new file mode 100644
index 0000000..f1d6d7d
--- /dev/null
+++ b/BKPG_PROTOCAL/src/main/java/top/dreamcenter/bkpg/protocal/template/ProcessAppTemplate.java
@@ -0,0 +1,191 @@
+package top.dreamcenter.bkpg.protocal.template;
+
+import top.dreamcenter.bkpg.protocal.MiniApp;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 进程启动模板
+ */
+public abstract class ProcessAppTemplate implements MiniApp, ActionListener {
+
+ private Process process;
+
+ private JTextArea textArea;
+
+ private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
+
+ /**
+ * 需要执行的命令
+ * @return CMD命令
+ */
+ public abstract String getCmdStr();
+
+ @Override
+ public JPanel getPanel() {
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.setBackground(Color.WHITE);
+
+ JPanel centerPanel = new JPanel();
+ centerPanel.setLayout(new FlowLayout());
+ centerPanel.setBackground(Color.WHITE);
+
+ // 标题
+ JLabel title = new JLabel(getName());
+
+ // 按钮组
+ JButton startBtn = new JButton("启动");
+ JButton stopBtn = new JButton("停止");
+
+ startBtn.setBackground(Color.WHITE);
+ stopBtn.setBackground(Color.WHITE);
+
+ startBtn.addActionListener(this);
+ stopBtn.addActionListener(this);
+
+ startBtn.setActionCommand("start");
+ stopBtn.setActionCommand("stop");
+
+ centerPanel.add(startBtn);
+ centerPanel.add(stopBtn);
+
+ // 输出
+ if (textArea == null) {
+ textArea = new JTextArea();
+ }
+ textArea.setBackground(Color.DARK_GRAY);
+ textArea.setForeground(Color.WHITE);
+ textArea.setRows(15);
+ JScrollPane scrollPane = new JScrollPane(textArea);
+
+ panel.add(title, BorderLayout.NORTH);
+ panel.add(centerPanel, BorderLayout.CENTER);
+ panel.add(scrollPane, BorderLayout.SOUTH);
+
+ return panel;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ switch (e.getActionCommand()){
+ case "start": btnStartMethod(); break;
+ case "stop": btnStopMethod(); break;
+ default:
+ System.out.println("未找到的命令:" + e.getActionCommand());
+ }
+ }
+
+ /**
+ * 按钮 - 启动
+ */
+ private void btnStartMethod() {
+ new Thread(() -> {
+ successWrite("尝试启动程序...");
+ if (process != null) {
+ failWrite("已启动过。");
+ return;
+ }
+ try {
+ process = Runtime.getRuntime().exec(getCmdStr());
+ successWrite("启动成功!");
+ heartbeatCheck();
+ String tmp;
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK"));
+ BufferedReader errReader = new BufferedReader(new InputStreamReader(process.getErrorStream(), "GBK"));
+
+ while ((tmp = reader.readLine()) != null) {
+ successWrite(tmp);
+ }
+
+ while ((tmp = errReader.readLine()) != null) {
+ failWrite(tmp);
+ }
+
+ reader.close();
+ errReader.close();
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }).start();
+ }
+
+ /**
+ * 按钮 - 停止
+ */
+ private void btnStopMethod() {
+ if (process ==null) {
+ failWrite("未启动。");
+ return;
+ }
+ if (process.isAlive()) process.destroy();
+ process = null;
+ successWrite("已终止。");
+ }
+
+
+ /**
+ * 写入正确信息
+ * @param raw 原文
+ */
+ private void successWrite(String raw) {
+ textArea.append(formatOutput(true, raw));
+ }
+
+ /**
+ * 写入错误信息
+ * @param raw 原文
+ */
+ private void failWrite(String raw) {
+ textArea.append(formatOutput(false, raw));
+ }
+
+ /**
+ * 输出格式化
+ * @param code 是否成功结果
+ * @param raw 原文
+ * @return 输出结果
+ */
+ private String formatOutput(boolean code,String raw) {
+ return (code ? "O" : "E") + " " + dateFormat.format(Calendar.getInstance().getTime()) + " " + raw + "\n";
+ }
+
+ /**
+ * 5 分钟心跳检测,如果心跳停止,则自动释放进程
+ */
+ private void heartbeatCheck() {
+ new Thread(() -> {
+ while (true) {
+ if (process == null) break;
+ else if (!process.isAlive()) {
+ failWrite("心跳停止");
+ process.destroy();
+ process = null;
+ successWrite("已释放资源");
+ break;
+ }
+ try {
+ TimeUnit.SECONDS.sleep(5);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+ }).start();
+ }
+
+ @Override
+ public boolean protect() {
+ return process != null && process.isAlive();
+ }
+}
diff --git a/BKPG_PROj.iml b/BKPG_PROj.iml
new file mode 100644
index 0000000..c035f0b
--- /dev/null
+++ b/BKPG_PROj.iml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PLUGIN_BKPG_GROUP_PROCESS/PLUGIN_BKPG_GROUP_PROCESS.iml b/PLUGIN_BKPG_GROUP_PROCESS/PLUGIN_BKPG_GROUP_PROCESS.iml
new file mode 100644
index 0000000..4ccc645
--- /dev/null
+++ b/PLUGIN_BKPG_GROUP_PROCESS/PLUGIN_BKPG_GROUP_PROCESS.iml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PLUGIN_BKPG_GROUP_PROCESS/pom.xml b/PLUGIN_BKPG_GROUP_PROCESS/pom.xml
new file mode 100644
index 0000000..0129a28
--- /dev/null
+++ b/PLUGIN_BKPG_GROUP_PROCESS/pom.xml
@@ -0,0 +1,38 @@
+
+
+ 4.0.0
+
+
+ BKPG_PROj
+ top.dreamcenter
+ ${revision}
+
+
+ top.dreamcenter.bkpg.plugin.group
+ PLUGIN_BKPG_GROUP_PROCESS
+
+ PLUGIN_BKPG_GROUP_PROCESS
+
+
+
+ top.dreamcenter.bkpg
+ BKPG_PROTOCAL
+ ${revision}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+ ${project.parent.basedir}/ext
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PLUGIN_BKPG_GROUP_PROCESS/src/main/java/top/dreamcenter/bkpg/group/ProcessGroupApp.java b/PLUGIN_BKPG_GROUP_PROCESS/src/main/java/top/dreamcenter/bkpg/group/ProcessGroupApp.java
new file mode 100644
index 0000000..42bf796
--- /dev/null
+++ b/PLUGIN_BKPG_GROUP_PROCESS/src/main/java/top/dreamcenter/bkpg/group/ProcessGroupApp.java
@@ -0,0 +1,52 @@
+package top.dreamcenter.bkpg.group;
+
+import top.dreamcenter.bkpg.protocal.MiniApp;
+import top.dreamcenter.bkpg.protocal.MiniAppGroup;
+import top.dreamcenter.bkpg.protocal.template.ProcessAppTemplate;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ProcessGroupApp implements MiniAppGroup {
+ @Override
+ public List getMiniApps() {
+
+ List list = new LinkedList<>();
+
+
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream("ext/ProgressGroup.txt")))) {
+
+ String line;
+ while ((line = reader.readLine()) != null) {
+ String[] split = line.split(": ");
+
+ String appName = split[0];
+ String appCmd = split[1];
+
+ MiniApp miniApp = new ProcessAppTemplate() {
+ @Override
+ public String getCmdStr() {
+ return appCmd;
+ }
+
+ @Override
+ public String getName() {
+ return appName;
+ }
+ };
+
+ list.add(miniApp);
+ }
+
+ } catch (Exception e){
+ System.err.println(e.getMessage());
+ return list;
+ }
+
+ return list;
+ }
+
+}
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3d518ca
--- /dev/null
+++ b/README.md
@@ -0,0 +1,118 @@
+
+## 项目架构
+
+主工程
+
+模块 | 作用
+--- | ---
+BKPG | 主应用程序
+BKPG_PROTOCAL | 三方扩展协议
+BKPG_DEMO | 简单示例扩展
+
+官方扩展插件工程
+
+模块 | 作用
+--- | ---
+PLUGIN_BKPG_GROUP_PROCESS | 命令组
+
+
+## 生产环境
+
+- JAVA : 8
+
+## 主应用程序执行逻辑
+
+1. 应用启动,绘制UI,挂载到系统托盘
+2. 扫描注册ext目录下的jar包(扫描实现了MiniApp的类)
+3. 程序挂载
+
+## 扩展协议
+
+### 可用协议
+
+```text
+MiniApp 基础协议
+ ┗ ProcessAppTemplate 命令执行协议模板
+↑
+MiniAppGroup 程序组合包
+```
+
+### 协议结构定义
+
+MiniApp
+ - String getName(); // 获取应用名称
+ - JPanel getPanel(); // 获取应用面板
+ - boolean protect(); // 保护应用,重启是否重新装载
+
+MiniAppGroup
+ - List\ getMiniApps(); // 获取所有的应用
+
+ProcessAppTemplate: MiniApp
+ - String getName(); // 获取应用名称
+ - String getCmdStr(); // 需要执行的命令
+ - 其余基类函数已默认实现
+
+
+### 详细说明
+
+**MiniApp** 为基础协议,所有的扩展实现都需要继承或者实现该协议,
+主应用程序只会扫描到实现了该接口的类,并且注册到容器中。
+MiniAppGroup是对MiniApp的扩展,旨在一次性批量注入MiniApp,
+同样也会被扫描到,其下的miniApp也都会被注册。
+
+MiniApp中,getName 是用于获取任务名称的,不用担心重复导致程序异常
+(因为注册时采用的是类完整访问路径注册的), 不过建议名称具有标志性,
+这样才能快速识别该任务所具备的特质。
+
+getPanel 是绘制的面板,即右面板,实际的操作区,可以自定义,
+也可以采用模板快速构建(如ProcessAppTemplate)。
+如果自定义,或者制作模板,需要注意以下几点:
+
+1. 长连接的任务,强烈建议做好资源的调度,适量增加 任务控制按钮
+ (启动、终止);如果可监测,建议增加连接心跳监测机制,
+ 在一定时间后,自动断开连接。
+2. 从A任务切换到B任务,A任务面板会销毁,调用B任务面板,
+ 但是任务的实例不会销毁,所以,你可以将一些数据存于全局变量来存储
+ 上一会话的某些状态量。
+3. 主程序面板的大小是固定的,所以,为了界面协调,建议纵向布局,
+ 并且内容较多的话,适量增加滚动条。
+4. 任务自身不建议开辟太大的内存空间,以免出现任务切换卡顿现象,
+ 如果一定要用大量内存,也做好完备的内存管控,避免出现OOM的情况。
+
+protect() 是保护函数,如果返回true,则表示在BKPG进行RELOAD时,该App不会被注销,
+而是保持实例不变,状态也都保持。这通常作为服务器服务非常关键,比如想要添加一个指令,
+需要RELOAD但是原有服务不能关闭,如果设置为true就可以实现保护。
+
+**ProcessAppTemplate** 为命令执行协议模板,为抽象类,继承实现了MiniApp接口,
+用于执行命令行指令,需要实现两个接口,一个是getName,作用同上,另外一个是该抽象类
+独有的,getCmdStr,需要设置命令行的完整执行指令。当点击面板的执行按钮时,
+会启动一个线程来执行该命令,并且每5s会检测一次命令心跳,如果心跳失去连接,
+则会释放资源。可以作为一些应用或者服务的启动端。
+
+
+为了更加高效的添加命令(常用),
+官方内置了一个命令AppGroup: **PLUGIN_BKPG_GROUP_PROCESS** 。
+通过配置ext/ProgressGroup.txt来添加指令应用,
+指令名称和指令用英文冒号和一个空格隔开【: 】,会自动创建多组ProcessAppTemplate。
+
+
+
+### 第三方扩展指南
+首先,下载BKPG_PROTOCAL协议JAR包,引入自己的项目中,作为环境依赖。
+之后在自己项目中实现MiniApp/MiniAppGroup接口或者ProcessAppTemplate抽象类即可。
+将JAR包生成路径配置到ext目录下,此时生成JAR包,点击主程序系统托盘右键的RELOAD选项,
+即可看到JAR包中的MiniApp都已经加载完毕了。
+
+你可以参考BKPG_DEMO的项目或者直接套用该demo来架构一个项目。
+注意,最后打包时,不应该包含BKPG_PROTOCAL这个依赖,是冗余的,建议排除在外。
+
+一个JAR包项目中可以包含多个MiniApp,这些MiniApp如果没有特殊机制劫持,
+最后全部会被装载进入到容器之中。
+
+如果您开发了自己的工具包,并且认为非常具有价值,你也可以分享自己的JAR包给别人,
+或者分享给官方,由我们加入README进行大众分享。
+
+
+
+
+
diff --git a/ext/ProgressGroup.txt b/ext/ProgressGroup.txt
new file mode 100644
index 0000000..a39b65a
--- /dev/null
+++ b/ext/ProgressGroup.txt
@@ -0,0 +1,2 @@
+PING百度: ping www.baidu.com
+PING主站: ping www.dreamcenter.top
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..0a588c0
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+ top.dreamcenter
+ BKPG_PROj
+ ${revision}
+ pom
+
+ BKPG_PROj
+ A tool to manage all self process.
+
+
+ BKPG
+ BKPG_DEMO
+ PLUGIN_BKPG_GROUP_PROCESS
+
+
+
+ 1.0-SNAPSHOT
+ 4.11
+ UTF-8
+ 8
+ 8
+
+
+
+
+
+ junit
+ junit
+ ${junit.version}
+ test
+
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.4.2
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.6.0
+
+
+
+
+
+
\ No newline at end of file