原文出自:公众号Throwable 原文链接:https:mp。weixin。qq。comsc9s47YfINZDsKnN4RCBQ前提 某一天点开掘金的写作界面的时候,发现了内置Markdown编辑器有一个Github的图标,点进去就是一个开源的Markdown编辑器项目bytemd(https:github。combytedancebytemd): 这是一个NodeJs项目,由字节跳动提供。联想到之前业余的时候做过一些Swing或者JavaFx的Demo,记得JavaFx中有一个组件WebView已经支持Html5、CSS3和ES5,这个组件作为一个嵌入式浏览器,可以轻松地渲染一个URL里面的文本内容或者直接渲染一个原始的Html字符串。另外,由于原生的JavaFx的视觉效果比较丑,可以考虑引入Swing配合IntelliJIDEA的主题提供更好的视觉效果。本文的代码基于JDK11开发。引入依赖 很多人吐槽过Swing组件的视觉效果比较差,原因有几个:技术小众,现在有更好的组件进行混合开发和跨平台开发基于上一点原因,导致很少人会去开发Swing组件的UI,其实Swing的每个组件都可以重新实现UI的表现效果composejb(JetBrains)组件很晚才发布出来,刚好碰上Swing官方停止维护,后面应该更加少人会使用Swing做GUI开发 使用Swing并且成功了的方案最知名的就是JetBrains全家桶。目前来看,为了解决这个丑的问题,现在有比较简单的处理方案:方案一:使用composejb(名字有点不好听,官方仓库为https:github。comJetBrainscomposejb)开发,这个是JetBrains系列的通用组件,基于Swing做二次封装,不过必须使用语言Kotlin,有点强买强卖的嫌疑,这列贴两个官方的图参考一下: 方案二:FormDev(之前推出过Swing布局器的开发商,官网https:www。formdev。comflatlaf)提供的FlatLaf(FlatLookandFeel),提供了LightDarkIntelliJandDarculathemes,而且依赖少,使用起来十分简单,个人认为当前这个是SwingUI组件视觉效果首选 引入FlatLaf和OpenFx的依赖:dependencygroupIdcom。formdevgroupIdflatlafartifactIdversion1。5versiondependencydependencygroupIdcom。formdevgroupIdflatlafintellijthemesartifactIdversion1。5versiondependencydependencygroupIdorg。openjfxgroupIdjavafxmediaartifactIdversion11。0。2versiondependencydependencygroupIdorg。openjfxgroupIdjavafxswingartifactIdversion11。0。2versiondependencydependencygroupIdorg。openjfxgroupIdjavafxwebartifactIdversion11。0。2versiondependencydependencygroupIdorg。openjfxgroupIdjavafxbaseartifactIdversion11。0。2versiondependencydependencygroupIdorg。openjfxgroupIdjavafxgraphicsartifactIdversion11。0。2versiondependencydependencygroupIdorg。openjfxgroupIdjavafxcontrolsartifactIdversion11。0。2versiondependency布局和实现 布局的实现比较简单: 最终的H5文本渲染在WebView组件中(JFXPanel是JavaFxSwing的适配器,WebView是JavaFx的组件,但是这里使用的外层容器都是Swing组件),具体的编码实现如下:publicclassMarkdownEditor{privatestaticfinalintW1200;privatestaticfinalintH1000;privatestaticfinalStringTITLEmarkdowneditor;publicstaticStringCONTENT!DOCTYPEhtmlhtmllangenheadmetacharsetUTF8metanameviewportcontentwidthdevicewidth,initialscale1。0titleByteMDexampletitlelinkrelstylesheethrefhttps:unpkg。combytemddistindex。min。csslinkrelstylesheethrefhttps:unpkg。comgithubmarkdowncssstyle。bytemd{height:calc(100vh50px);}。footer{width:100;height:30px;left:0;position:absolute;bottom:0;textalign:center;}styleheadbodybytemdbodyhtml;static{初始化主题try{UIManager。setLookAndFeel(FlatIntelliJLaf。class。getName());}catch(Exceptione){thrownewIllegalStateException(themeiniterror,e);}}privatestaticJFramebuildFrame(intw,inth,LayoutManagerlayoutManager){JFrameframenewJFrame();frame。setLayout(layoutManager);frame。setTitle(TITLE);frame。setDefaultCloseOperation(WindowConstants。EXITONCLOSE);frame。setSize(w,h);ToolkittoolkitToolkit。getDefaultToolkit();intx(int)(toolkit。getScreenSize()。getWidth()frame。getWidth())2;inty(int)(toolkit。getScreenSize()。getHeight()frame。getHeight())2;frame。setLocation(x,y);returnframe;}privatestaticvoidinitAndDisplay(){构建窗体JFrameframebuildFrame(W,H,newBorderLayout());JFXPanelpanelnewJFXPanel();Platform。runLater((){panel。setSize(W,H);initWebView(panel,CONTENT);frame。getContentPane()。add(panel);});frame。setVisible(true);}publicstaticvoidmain(String〔〕args){SwingUtilities。invokeLater(MarkdownEditor::initAndDisplay);}privatestaticvoidinitWebView(JFXPanelfxPanel,Stringcontent){StackPanerootnewStackPane();ScenescenenewScene(root);WebViewwebViewnewWebView();WebEnginewebEnginewebView。getEngine();webEngine。setJavaScriptEnabled(true);webEngine。loadContent(content);root。getChildren()。add(webView);fxPanel。setScene(scene);}} H5文本来源于bytemd的原生JS实现例子: 所有代码加上注释大概120多行。使用JDK11运行,结果如下: 目前有2个没有解决的问题(也有可能是):JS的动作触发有轻微延迟WebView组件初始化比较慢小结 OracleJDK官方已经宣布不再维护Swing项目,按照一般的尿性后面有可能从JDK中移除,也许是因为它体现不了自身的价值(低情商:不赚钱)。Swing的开发中布局是比较反人类的,一般可能一个Swing项目布局会耗费90以上的时间,原生组件的UI设计看上去比较丑,没有丰富的扩展组件和活跃的社区,加上现在有其他更好的跨平台开发方案如Qt、ReactNative和Flutter等等,Swing被遗忘是一个既定的结局。往后除了一枝独秀的JetBrains,Swing的结局就是成为少数人业务的爱好,成为JDKGUI编程爱好者的收藏品。 Demo源码:localmarkdowneditor(https:gitee。comthrowableDogelocalmarkdowneditor)