当前位置: 首页 > news >正文

编写一个markdown文本编辑器工具

文章目录

    • 1、UI组件/依赖库选择。
      • 1.1、左侧Markdown编辑区UI组件选择。
      • 1.2、webview组件选择
      • 1.3、markdown转html开源库选择。
    • 2、核心技术实现
      • 2.1、左侧Markdown编辑区实现
      • 2.2、右侧webview预览实现
      • 2.3、markdown转html实现
    • 3、运行效果
      • 3.1、界面展示

1、UI组件/依赖库选择。

编辑器采用左右分割布局,左侧为Markdown编辑区,右侧为实时预览区,相关组件或依赖选择现成的开源库整合实现,减少开发成本。

1.1、左侧Markdown编辑区UI组件选择。

网上找了一下,仅发现RSyntaxTextArea https://github.com/bobbylight/rsyntaxtextarea这个组件比较适合。
RSyntaxTextArea的功能::

  • 现成的文本编辑界面
  • Markdown语法高亮显示
  • 可定制的编辑功能
  • 开源免费使用

1.2、webview组件选择

要创建markdown编辑,需要一个webview组件,在java里面可用的webview组件有:

  1. javafx.scene.web.WebView,开源免费,基于webkit内核
  2. jcef,开源免费,基于Chromium
  3. JxBrowser,商业收费,基于Chromium
    在考虑免费和整合方便上,选择了javafx.scene.web.WebView。

1.3、markdown转html开源库选择。

  1. CommonMark-java

    • 基于CommonMark规范实现
    • 轻量级,易于集成
    • 支持标准Markdown语法
  2. Flexmark-java

    • 功能丰富的Markdown处理器
    • 支持CommonMark和GitHub Flavored Markdown
    • 可扩展性强,支持自定义扩展
  3. Markdown4j

    • 简单易用的Markdown解析器
    • 基于JavaScript的markdown.js移植
    • 适合基本的Markdown转换需求
  4. Txtmark

    • 轻量级Markdown处理器
    • 性能较好
    • 支持基本Markdown语法

Flexmark-java支持最完整,选择了它。

2、核心技术实现

2.1、左侧Markdown编辑区实现

编辑区采用RSyntaxTextArea,初始化代码如下:

   // 初始化面板private void initPanel() {textArea = new RSyntaxTextArea();textArea.setCodeFoldingEnabled(true);textArea.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_MARKDOWN);textArea.setAntiAliasingEnabled(true);textArea.setFont(Config.getFont());textArea.setLineWrap(Config.isIsLineWrap());textArea.addCaretListener(e -> {try{int pos = textArea.getCaretPosition();//获取行数int row = textArea.getLineOfOffset(pos) + 1;//获取列数int col = pos - textArea.getLineStartOffset(row - 1) + 1;rowValueLabel.setText(String.valueOf(row));columnValueLabel.setText(String.valueOf(col));}catch(Exception ex){log.log(Level.SEVERE, "   无法获得当前光标位置 ", ex);}});scrollPane = new RTextScrollPane(textArea);this.add(scrollPane, BorderLayout.CENTER);}

2.2、右侧webview预览实现

预览区采用javafx.scene.web.WebView,初始化代码如下:

private void initWebView(JFXPanel fxPanel){WebView webView = new WebView();webEngine = webView.getEngine();webEngine.setOnAlert((WebEvent<String> wEvent) -> {System.out.println("alert========: " + wEvent.getData());});webEngine.setOnError((WebErrorEvent wEvent) -> {System.out.println("error========: " + wEvent.getMessage());});String body = "";String markdown = textArea.getText();if (!StrUtil.isEmpty(markdown)){body = Markdown2Html.toHtml(markdown);}webEngine.loadContent(getHtml(body), "text/html");Scene scene = new Scene(new StackPane(webView));fxPanel.setScene(scene);}

2.3、markdown转html实现

左侧编辑区增加文本变动监听器,使用flexmark-java将Markdown文本转换为HTML,并通过WebView加载。关键步骤包括:

// 监听文本编辑,如果文本内容有更新,则将markdown转为html,并更新webview。
class MdDocumentListener implements DocumentListener {public void insertUpdate(DocumentEvent e) {}public void removeUpdate(DocumentEvent e) {}public void changedUpdate(DocumentEvent e) {String markdown = editor.getTextArea().getText();String html = Markdown2Html.toHtml(markdown);Platform.runLater(() -> {JSObject obj = (JSObject) webEngine.executeScript("window");obj.setMember("javaContent", html);webEngine.executeScript("addHtml(javaContent)");});}
}
public class Markdown2Html {private static Parser parser = null;private static HtmlRenderer renderer = null;public static String toHtml(String markdown) {MutableDataSet options = new MutableDataSet();options.set(Parser.EXTENSIONS, Arrays.asList(TablesExtension.create(),FootnoteExtension.create(),TaskListExtension.create()));if (parser == null){parser = Parser.builder(options).build();renderer = HtmlRenderer.builder(options).build();}Node document = parser.parse(markdown);return renderer.render(document);}
}

3、运行效果

3.1、界面展示

启动应用后,界面呈现左右分割布局:左侧为支持语法高亮的文本编辑区,底部显示当前光标所在的行和列位置;右侧为实时渲染的预览区。
在这里插入图片描述

http://www.dtcms.com/a/304789.html

相关文章:

  • 7月29号打卡
  • 无需反复登录!当贝AI聚合通义Qwen3-235B等14大模型
  • 大文件的切片上传和断点续传前后端(Vue+node.js)具体实现
  • JetBrains IDE插件开发及发布
  • java导入pdf(携带动态表格,图片,纯java不需要模板)
  • 15K的Go开发岗,坐标北京
  • 第七章 MCP协议
  • Wndows Docker Desktop-Unexpected WSL error错误
  • 报告研读——80页数据资产化实践指南报告-2024【附全文阅读】
  • 天铭科技×蓝卓 | “1+2+N”打造AI驱动的汽车零部件行业智能工厂
  • 为什么全景渲染更耗时?关键因素解析
  • 3D游戏引擎的“眼睛“:相机系统深度揭秘与技术实现
  • 【ARM】FPU,VFP,ASE,NEON,SVE...是什么意思?
  • Synopsys:消息管理
  • 2025年1中科院1区顶刊SCI-投影迭代优化算法Projection Iterative Methods-附完整Matlab免费代码
  • Vivado常用IP
  • GaussDB 数据库架构师修炼(十) 性能诊断常用视图
  • Rust基础-part8-模式匹配、常见集合
  • 嵌入式开发问题:warning: #177-D: variable “key“ was declared but never referenced
  • 2025年Solar应急响应公益月赛-7月笔记ing
  • Generative AI in Game Development
  • Class24AlexNet
  • STM32——HAL库
  • HBase、MongoDB 和 Redis 的区别详解
  • 图片查重从设计到实现(7) :使用 Milvus 实现高效图片查重功能
  • Redis内存使用耗尽情况分析
  • 达梦数据库DM用户管理-三权分立与四权分立,用户创建与维护,用户与模式的关系,用户相关权限
  • Spring Boot 简单接口角色授权检查实现
  • Rust 实战二 | 开发简易版命令行工具 grep
  • uv工具使用记录(Linux系统)