From b5b5cb060683ada057b2306544a312b9954c5f4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AE=B8=E8=BD=B2?= Date: Sat, 23 Sep 2023 11:50:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E6=8F=92=E4=BB=B6=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E9=A1=B5=E9=9D=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 13 ++ src/main/java/module-info.java | 4 + .../ui/pluginstage/PluginManagementPane.java | 149 +++++++++++++++--- .../views/root/top/menu/TopMenuBar.java | 2 +- 4 files changed, 145 insertions(+), 23 deletions(-) diff --git a/pom.xml b/pom.xml index f9d8aa1..df454d8 100644 --- a/pom.xml +++ b/pom.xml @@ -25,6 +25,19 @@ system ${project.basedir}/libs/richtextfx-fat-0.11.1.jar + + + org.commonmark + commonmark + 0.21.0 + + + + org.openjfx + javafx-web + ${javafx.version} + + diff --git a/src/main/java/module-info.java b/src/main/java/module-info.java index 56f1293..dd4e960 100644 --- a/src/main/java/module-info.java +++ b/src/main/java/module-info.java @@ -17,6 +17,10 @@ module org.jcnc.jnotepad { requires org.kordamp.ikonli.antdesignicons; requires richtextfx.fat; requires java.desktop; + requires org.commonmark; + requires javafx.web; + + exports org.jcnc.jnotepad; exports org.jcnc.jnotepad.model.enums; exports org.jcnc.jnotepad.app.config; diff --git a/src/main/java/org/jcnc/jnotepad/ui/pluginstage/PluginManagementPane.java b/src/main/java/org/jcnc/jnotepad/ui/pluginstage/PluginManagementPane.java index c92718a..3a0566e 100644 --- a/src/main/java/org/jcnc/jnotepad/ui/pluginstage/PluginManagementPane.java +++ b/src/main/java/org/jcnc/jnotepad/ui/pluginstage/PluginManagementPane.java @@ -5,9 +5,12 @@ import atlantafx.base.controls.ToggleSwitch; import atlantafx.base.theme.Styles; import javafx.geometry.Insets; import javafx.scene.Node; - -import java.awt.Desktop; - +import javafx.scene.control.Button; +import javafx.scene.web.WebEngine; +import javafx.scene.web.WebView; +import org.commonmark.parser.Parser; +import org.commonmark.renderer.html.HtmlRenderer; +import javafx.scene.control.ScrollPane; import javafx.scene.control.*; import javafx.scene.image.Image; import javafx.scene.image.ImageView; @@ -18,7 +21,11 @@ import javafx.scene.text.Text; import org.jcnc.jnotepad.util.LogUtil; import org.slf4j.Logger; +import java.awt.*; +import java.io.IOException; import java.net.URI; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; @@ -31,11 +38,24 @@ import java.util.Map; */ public class PluginManagementPane extends BorderPane { + /** + * 图标大小常量 + */ public static int ICON_SIZE = 40; + + /** + * 日志记录器 + */ Logger logger = LogUtil.getLogger(this.getClass()); - + /** + * 自定义分割面板 + */ private CustomSplitPane customSplitPane; + + /** + * 用于存储Tile与其内容节点的映射关系 + */ private final Map tileContentMap = new HashMap<>(); /** @@ -50,10 +70,10 @@ public class PluginManagementPane extends BorderPane { */ private void init() { // 创建选项卡面板 - TabPane tabPane = new TabPane(); + TabPane rootTabPane = new TabPane(); // 创建市场、已安装和设置选项卡 - Tab marketTab = new Tab("发现"); + Tab marketTab = new Tab("市场"); Tab installedTab = new Tab("已安装"); Tab myTab = new Tab("设置"); @@ -75,8 +95,8 @@ public class PluginManagementPane extends BorderPane { customSplitPane.setLeftContent(getScrollPane()); // 创建示例按钮并添加到已安装和设置选项卡中 - installedTabContent.setCenter(new Button("2")); - myTabContent.setCenter(new Button("3")); + installedTabContent.setCenter(new Button("已安装")); + myTabContent.setCenter(new Button("设置")); // 将选项卡内容设置到选项卡中 marketTab.setContent(marketTabContent); @@ -84,10 +104,10 @@ public class PluginManagementPane extends BorderPane { myTab.setContent(myTabContent); // 将选项卡添加到选项卡面板中 - tabPane.getTabs().addAll(marketTab, installedTab, myTab); + rootTabPane.getTabs().addAll(marketTab, installedTab, myTab); // 将选项卡面板设置为插件管理面板的中心内容 - this.setCenter(tabPane); + this.setCenter(rootTabPane); } /** @@ -175,7 +195,6 @@ public class PluginManagementPane extends BorderPane { return tile; } - /** * 创建专属于每个插件的CustomSplitPane内容。 * @@ -190,6 +209,102 @@ public class PluginManagementPane extends BorderPane { var authorBox = new HBox(10); var author = new Text("JCNC团队"); + var authorLink = getAuthorLink(); + authorBox.getChildren().addAll(author, authorLink); + + var state = new Text("未启用"); + + var main = new VBox(10); + + // 创建TabPane并添加标签页 + TabPane tabPane = new TabPane(); + + Tab detailsTab = new Tab("细节"); + detailsTab.setClosable(false); + Tab featuresTab = new Tab("实现功能"); + featuresTab.setClosable(false); + Tab changelogTab = new Tab("更新日志"); + changelogTab.setClosable(false); + + // 在标签页中添加内容 + VBox detailsContent = new VBox(10); + + // 创建一个WebView来显示Markdown内容 + WebView webView = new WebView(); + WebEngine engine = webView.getEngine(); + + // 从外部文件加载Markdown内容 + String markdownContent = loadMarkdownFromFile("README.md"); + String htmlContent = markdownToHtml(markdownContent); + + // 加载HTML内容到WebView + engine.loadContent(htmlContent); + // 将WebView添加到detailsContent + detailsContent.getChildren().addAll(webView); + + VBox featuresContent = new VBox(10); + VBox changelogContent = new VBox(10); + + detailsTab.setContent(detailsContent); + featuresTab.setContent(featuresContent); + changelogTab.setContent(changelogContent); + + tabPane.getTabs().addAll(detailsTab, featuresTab, changelogTab); + + main.getChildren().addAll(tabPane); + + content.getChildren().addAll(titleLabel, authorBox, state, main); + + // 将内容包装在滚动面板中 + ScrollPane scrollPane = new ScrollPane(content); + scrollPane.setFitToWidth(true); + scrollPane.setFitToHeight(true); + + return scrollPane; + } + + /** + * 将Markdown内容转换为HTML格式。 + * + * @param markdownContent Markdown格式的内容 + * @return HTML格式的内容 + */ + private String markdownToHtml(String markdownContent) { + // 创建Markdown解析器 + Parser parser = Parser.builder().build(); + + // 解析Markdown内容 + + org.commonmark.node.Node document = parser.parse(markdownContent); + + // 创建HTML渲染器 + HtmlRenderer renderer = HtmlRenderer.builder().build(); + + // 将Markdown文档渲染为HTML + return renderer.render(document); + } + + /** + * 从文件加载Markdown内容。 + * + * @param filePath 文件路径 + * @return 加载的Markdown内容 + */ + private String loadMarkdownFromFile(String filePath) { + try { + return new String(Files.readAllBytes(Paths.get(filePath))); + } catch (IOException e) { + logger.info("正在运行" + "loadMarkdownFromFile"); + return ""; + } + } + + /** + * 获取作者链接。 + * + * @return 作者链接 + */ + private Hyperlink getAuthorLink() { var authorLink = new Hyperlink("插件仓库地址"); authorLink.setVisited(true); authorLink.setStyle("-fx-text-fill: blue; -fx-visited-link-color: blue;"); @@ -219,16 +334,6 @@ public class PluginManagementPane extends BorderPane { logger.info("启动" + authorLink + "失败!"); } }); - - authorBox.getChildren().addAll(author, authorLink); - - - - var descriptionLabel = new Text("插件描述插件描述插件描述"); - - - content.getChildren().addAll(titleLabel, authorBox, descriptionLabel); - - return content; + return authorLink; } } diff --git a/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java b/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java index 18e1bb5..4798632 100644 --- a/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java +++ b/src/main/java/org/jcnc/jnotepad/views/root/top/menu/TopMenuBar.java @@ -277,7 +277,7 @@ public class TopMenuBar extends MenuBar { PluginManagementPane pluginManagementPane = new PluginManagementPane(); - Scene scene = new Scene(pluginManagementPane, 900, 500); + Scene scene = new Scene(pluginManagementPane, 900, 600); newStage.setScene(scene); newStage.show(); });