用于基于SWT的应用程序的RichText编辑器组件
生活随笔
收集整理的這篇文章主要介紹了
用于基于SWT的应用程序的RichText编辑器组件
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本文將完成使用SWT實(shí)現(xiàn)我們自己的RichText編輯器組件的任務(wù)。 在為我的一位客戶(hù)開(kāi)發(fā)基于桌面的應(yīng)用程序時(shí),我遇到了這樣一個(gè)可視化組件的需求,并希望添加一項(xiàng)功能,以允許用戶(hù)使用粗體,斜體,刪除線等功能來(lái)寫(xiě)富文本注釋。 那時(shí),我開(kāi)始研究網(wǎng)絡(luò),以便找到一個(gè)開(kāi)放源代碼庫(kù),該庫(kù)可以使我免于從頭開(kāi)始部署它的工作,而我遇到了“已完成”實(shí)現(xiàn)的列表 。 讓我們?cè)谶@里列出我對(duì)這種組件的需求:
- 它應(yīng)該是本地SWT組件,而不是Eclipse View或Editor,并且必須可嵌入任何SWT組合中。
- 它應(yīng)允許使用粗體,斜體,刪除線等基本格式。
- 它應(yīng)該支持剪貼板的基本操作,例如復(fù)制,剪切和粘貼。
- 它應(yīng)該使用基本HTML輸出文本。
- 它需要能夠解析所生成的基本HTML,以允許版本。
下一個(gè)稱(chēng)為RichStringBuilder,它將用作幫助程序類(lèi),以將StyledText組件的內(nèi)容格式化為基本HTML:
import java.util.Stack;public final class RichStringBuilder {public static final String LINE_DELIMITER = "<br/>";private StringBuilder builder;private Stack fontStyleStack;public RichStringBuilder() {builder = new StringBuilder();fontStyleStack = new Stack();}public RichStringBuilder append(String text) {builder.append(text);return this;}public RichStringBuilder appendLineBreak() {builder.append(LINE_DELIMITER);return this;}public RichStringBuilder startParagraph() {builder.append("<p>");return this;}public RichStringBuilder startFontStyle(FontStyle fontStyle) {fontStyleStack.push(fontStyle);internalStartFontStyle(fontStyle);return this;}public RichStringBuilder startFontStyles(FontStyle... fontStyles) {for (FontStyle fs : fontStyles) {startFontStyle(fs);}return this;}public RichStringBuilder endFontStyles(int count) {for (int i = 0;i < count;i++) {endStyle();}return this;}public RichStringBuilder endStyle() {if (fontStyleStack.size() > 0) {FontStyle style = fontStyleStack.pop();internalEndFontStyle(style);}return this;}public RichStringBuilder endParagraph() {flushStyles();builder.append("</p>");return this;}public void flushStyles() {while (fontStyleStack.size() > 0) {endStyle();}}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (null == o) return false;if (!(o instanceof RichStringBuilder)) return false;return ((RichStringBuilder) o).builder.equals(builder);}@Overridepublic int hashCode() {return builder.hashCode();}@Overridepublic String toString() {return builder.toString();}private void internalStartFontStyle(FontStyle fontStyle) {switch (fontStyle) {case BOLD:builder.append("<b>");break;case ITALIC:builder.append("<i>");break;case STRIKE_THROUGH:builder.append("<del>");break;case UNDERLINE:builder.append("<ins>");break;}}private void internalEndFontStyle(FontStyle fontStyle) {switch (fontStyle) {case BOLD:builder.append("</b>");break;case ITALIC:builder.append("</i>");break;case STRIKE_THROUGH:builder.append("</del>");break;case UNDERLINE:builder.append("</ins>");break;}}}第三個(gè)是基于SAX的內(nèi)容處理程序,它將基本HTML解析為StyledText控件時(shí)將啟動(dòng)事件:
import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; import java.util.List; import java.util.Stack;import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory;import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyleRange; import org.xml.sax.Attributes; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler;public final class RichTextParser {public static RichTextParser parse(String formattedText)throws ParserConfigurationException, SAXException, IOException {return new RichTextParser(formattedText);}private StringBuilder text = new StringBuilder();private List styleRanges = new ArrayList();private RichTextParser(String formattedText)throws ParserConfigurationException, SAXException, IOException {StringReader reader = new StringReader(formattedText);SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();DefaultHandler handler = new RichTextContentHandler();parser.parse(new InputSource(reader), handler);}public String getText() {return text.toString();}public StyleRange[] getStyleRanges() {return styleRanges.toArray(new StyleRange[styleRanges.size()]);}private class RichTextContentHandler extends DefaultHandler {private Stack<List> stylesStack = new Stack<List>();private String lastTextChunk = null;@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {lastTextChunk = new String(ch, start, length);}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {// If there is not any previous text chunk parsed then returnif (lastTextChunk == null) return;// If the tag found is not a supported one then returnif (!"p".equals(qName) || !"b".equals(qName) || !"i".equals(qName) ||!"ins".equals(qName) || !"del".equals(qName)) {return;}List lastStyles = lastFontStyles(true);if (lastStyles != null) {StyleRange range = transform(lastStyles);range.start = currentIndex() + 1;range.length = lastTextChunk.length();styleRanges.add(range);}text.append(lastTextChunk);lastTextChunk = null;}@Overridepublic void startElement(String uri, String localName, String qName,Attributes atts) throws SAXException {// If the tag found is not a supported one then returnif (!"p".equals(qName) || !"b".equals(qName) || !"i".equals(qName) ||!"ins".equals(qName) || !"del".equals(qName)) {return;}List lastStyles = lastFontStyles(false);if (lastTextChunk == null) {if (lastStyles == null) {lastStyles = new ArrayList();stylesStack.add(lastStyles);}} else {if (lastStyles != null) {StyleRange range = transform(lastStyles);range.start = currentIndex() + 1;range.length = lastTextChunk.length();styleRanges.add(range);}text.append(lastTextChunk);lastTextChunk = null;}if ("b".equals(qName)) {lastStyles.add(FontStyle.BOLD);} else if ("i".equals(qName)) {lastStyles.add(FontStyle.ITALIC);} else if ("ins".equals(qName)) {lastStyles.add(FontStyle.UNDERLINE);} else {lastStyles.add(FontStyle.STRIKE_THROUGH);}}private StyleRange transform(List styles) {StyleRange range = new StyleRange();range.start = currentIndex() + 1;range.length = lastTextChunk.length();for (FontStyle fs : styles) {if (FontStyle.BOLD == fs) {range.fontStyle = (range.fontStyle & SWT.BOLD);} else if (FontStyle.ITALIC == fs) {range.fontStyle = (range.fontStyle & SWT.ITALIC);} else if (FontStyle.STRIKE_THROUGH == fs) {range.strikeout = true;} else if (FontStyle.UNDERLINE == fs) {range.underline = true;}}return range;}private List lastFontStyles(boolean remove) {List lastStyles = null;if (stylesStack.size() > 0) {if (remove) {lastStyles = stylesStack.pop();} else {lastStyles = stylesStack.peek();}}return lastStyles;}private int currentIndex() {return text.length() - 1;}}} 結(jié)論 實(shí)現(xiàn)您自己的SWT RichText控件可能不是滿(mǎn)足您需求的最佳選擇,您將需要權(quán)衡這樣做的利弊,以及是否有必要投資其中一種現(xiàn)成的商業(yè)解決方案。 但是,我想通過(guò)本文演示如何在SWT對(duì)話框和視圖中嵌入您自己的(簡(jiǎn)單且輕量級(jí)的)富文本編輯器,與從中獲得的好處相比,它很容易實(shí)現(xiàn),并且需要花費(fèi)很少的精力。 參考:來(lái)自Code Nibbles博客的JCG合作伙伴 Alonso Dominguez的RichText編輯器組件,用于基于SWT的應(yīng)用程序 。翻譯自: https://www.javacodegeeks.com/2012/07/richtext-editor-component-for-swt-based.html
總結(jié)
以上是生活随笔為你收集整理的用于基于SWT的应用程序的RichText编辑器组件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 广东为什么叫岭南 广东叫岭南的原因分析
- 下一篇: 登录:应用程序错误通知