SWT中是否有RTF显示小部件
我想在SWT(实际上是Eclipse RCP)应用程序中显示RTF文档。
我知道有一个用于显示和编辑RTF文本的Swing小部件,但是在其他平台上使用时,它是Swing且外观和感觉都非常陌生(更不用说,据我所知,它不显示图像,仅具有对格式的有限支持)
其他选项是在Windows上使用COM接口,但仅在Windows平台上有效,并且要求在客户计算机上安装ActiveX RichEdit cont。
在Eclipse / SWT应用程序中显示丰富文档的其他其他选择是什么?
解决方案
回答
我们可以使用swt.custom.StyledText。它具有许多可更改文本外观的功能。但是我不认为它现在可以加载或者保存RTF。
我曾经用它编写一个HTML编辑器,但是这很困难,因为与HTML / RTF的工作方式相比,StyledText模型向文本的一部分添加样式非常陌生。
我们可以从此控件直接打印AFAIK,该控件在内部创建内容的RTF表示形式。但这不完全是我们要的。
回答
我不确定没有使用ActiveX的方法。如果我们确实朝这个方向发展,那么我们可能需要研究IBM ActiveX文档容器,该容器应该可以更好地集成文档。
回答
为什么不先使用RTFEditorKit将RTF文本读入StyledDocument,然后使用HTMLEditorKit将StyledDocument写入StringWriter?
String rtf = "whatever"; BufferedReader input = new BufferedReader(new StringReader(rtf)); RTFEditorKit rtfKit = new RTFEditorKit(); StyledDocument doc = (StyledDocument) rtfKit.createDefaultDocument(); rtfEdtrKt.read( input, doc, 0 ); input.close(); HTMLEditorKit htmlKit = new HTMLEditorKit(); StringWriter output = new StringWriter(); htmlKit.write( output, doc, 0, doc.getLength()); String html = output.toString();
然后显示HTML?
回答
我们可能想将Swing控件与AWT / SWT桥一起使用。我用它将OpenOffice嵌入到SWT应用程序中:
package ooswtviewer; import java.awt.Panel; import com.sun.star.awt.XView; import com.sun.star.beans.Property; import com.sun.star.beans.UnknownPropertyException; import com.sun.star.beans.XPropertySet; import com.sun.star.comp.beans.Frame; import com.sun.star.comp.beans.NoConnectionException; import com.sun.star.comp.beans.OOoBean; import com.sun.star.comp.beans.OfficeDocument; import com.sun.star.drawing.XDrawView; import com.sun.star.frame.XController; import com.sun.star.frame.XDesktop; import com.sun.star.frame.XFrame; import com.sun.star.frame.XFramesSupplier; import com.sun.star.frame.XLayoutManager; import com.sun.star.frame.XModel; import com.sun.star.lang.WrappedTargetException; import com.sun.star.ui.XUIElement; import com.sun.star.uno.Any; import com.sun.star.uno.UnoRuntime; import com.sun.star.uno.XInterface; import com.sun.star.view.XViewSettingsSupplier; /** * Code based on example from http://www.eclipsezone.com/eclipse/forums/t48966.html * * @author Aaron digulla */ public class OOoSwtViewer extends Panel { private static final String RESOURCE_TOOLBAR_TEXTOBJECTBAR = "private:resource/toolbar/textobjectbar"; private static final String RESOURCE_TOOLBAR_STANDARDBAR = "private:resource/toolbar/standardbar"; private static final String RESOURCE_MENUBAR = "private:resource/menubar/menubar"; private static final long serialVersionUID = -1408623115735065822L; private OOoBean aBean; public OOoSwtViewer() { super(); aBean = new OOoBean(); setLayout(new java.awt.BorderLayout()); add(aBean, java.awt.BorderLayout.CENTER); aBean.setAllBarsVisible (false); } public XPropertySet getXPropertySet () { return getXPropertySet (getFrame ()); } public XPropertySet getXPropertySet (Object o) { return (XPropertySet)UnoRuntime.queryInterface (XPropertySet.class, o); } public Frame getFrame () { try { return aBean.getFrame (); } catch (NoConnectionException e) { throw new OOException ("Error getting frame from bean", e); } } public XLayoutManager getXLayoutManager () { try { return (XLayoutManager)UnoRuntime.queryInterface (XLayoutManager.class, getXPropertySet ().getPropertyValue ("LayoutManager")); } catch (Exception e) { throw new OOException ("Error getting LayoutManager from bean's properties", e); } } public void setMenuBarVisible (boolean visible) { if (visible) getXLayoutManager ().showElement (RESOURCE_MENUBAR); else getXLayoutManager ().hideElement (RESOURCE_MENUBAR); } public void setStandardBarVisible (boolean visible) { if (visible) getXLayoutManager ().showElement (RESOURCE_TOOLBAR_STANDARDBAR); else getXLayoutManager ().hideElement (RESOURCE_TOOLBAR_STANDARDBAR); } public void setTextObjectBarVisible (boolean visible) { if (visible) getXLayoutManager ().showElement (RESOURCE_TOOLBAR_TEXTOBJECTBAR); else getXLayoutManager ().hideElement (RESOURCE_TOOLBAR_TEXTOBJECTBAR); } private Thread loadThread; private Exception loadException; public void setDocument(final String url) { loadThread = new Thread () { public void run() { try { aBean.loadFromURL(url, null); aBean.aquireSystemWindow(); setTextObjectBarVisible (false); // for (XUIElement e: getXLayoutManager ().getElements ()) // { // XInterface i = (XInterface)e.getRealInterface (); // System.out.println (e); // System.out.println (i); // printProperties (getXPropertySet (e)); // } /* System.out.println ("frame:"); printProperties (getXPropertySet ()); frame: Title=test - OpenOffice.org Writer IndicatorInterception=Any[Type[com.sun.star.task.XStatusIndicator], null] LayoutManager=Any[Type[com.sun.star.frame.XLayoutManager], [Proxy:26506390,717ea70;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.frame.XLayoutManager]]] DispatchRecorderSupplier=Any[Type[com.sun.star.frame.XDispatchRecorderSupplier], null] IsHidden=false */ XController controller = aBean.getDocument ().getCurrentController (); /* System.out.println ("controller:"); printProperties (getXPropertySet (controller)); controller: IsConstantSpellcheck=true IsHideSpellMarks=false LineCount=1 PageCount=1 */ /* System.out.println ("layoutManager:"); printProperties (getXPropertySet (getXLayoutManager ())); layoutManager: AutomaticToolbars=true HideCurrentUI=false LockCount=0 MenuBarCloser=true RefreshContextToolbarVisibility=false */ /* System.out.println ("document:"); printProperties (getXPropertySet (aBean.getDocument ())); OfficeDocument doc = aBean.getDocument (); ApplyFormDesignMode=false ApplyWorkaroundForB6375613=false AutomaticControlFocus=false BasicLibraries=Any[Type[com.sun.star.script.XLibraryContainer], [Proxy:14806696,73ca178;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.script.XLibraryContainer]]] BuildId=68010 CharFontCharSet=1 CharFontCharSetAsian=1 CharFontCharSetComplex=1 CharFontFamily=3 CharFontFamilyAsian=6 CharFontFamilyComplex=6 CharFontName=Times New Roman CharFontNameAsian=Arial Unicode MS CharFontNameComplex=Tahoma CharFontPitch=2 CharFontPitchAsian=2 CharFontPitchComplex=2 CharFontStyleName= CharFontStyleNameAsian= CharFontStyleNameComplex= CharLocale=com.sun.star.lang.Locale@fb6354 CharacterCount=20 DialogLibraries=Any[Type[com.sun.star.script.XLibraryContainer], [Proxy:3556929,73a39c0;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.script.XLibraryContainer]]] ForbiddenCharacters=Any[Type[com.sun.star.i18n.XForbiddenCharacters], [Proxy:11544872,7669148;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.i18n.XForbiddenCharacters]]] HasValidSignatures=false HideFieldTips=false IndexAutoMarkFileURL= LockUpdates=false ParagraphCount=1 RecordChanges=false RedlineDisplayType=2 RedlineProtectionKey=[B@f593af RuntimeUID=10 ShowChanges=true TwoDigitYear=1930 WordCount=5 WordSeparator=() */ // System.out.println ("viewData:"); // printProperties (getXPropertySet (controller.getFrame ().getContainerWindow ())); XViewSettingsSupplier settingsSupplier = (XViewSettingsSupplier)UnoRuntime.queryInterface (XViewSettingsSupplier.class, controller); // System.out.println ("settingsSupplier:"); // printProperties (settingsSupplier.getViewSettings ()); settingsSupplier.getViewSettings ().setPropertyValue ("ShowVertRuler", Boolean.FALSE); settingsSupplier.getViewSettings ().setPropertyValue ("ShowHoriRuler", Boolean.FALSE); // Switch to Web Layout. This layout mode comes without gray border and the page borders automatically adujst to the frame settingsSupplier.getViewSettings ().setPropertyValue ("ShowOnlineLayout", Boolean.TRUE); // settingsSupplier.getViewSettings ().setPropertyValue ("ShowTextBoundaries", Boolean.TRUE); // XView view = (XView)UnoRuntime.queryInterface (XView.class, getFrame ()); // System.out.println ("drawView="+view); // printProperties (getXPropertySet (view)); /* XModel model = (XModel)UnoRuntime.queryInterface (XModel.class, doc); printProperties ("model", model); Same as getDocument() */ /* System.out.println ("Interfaces implemented by aBean.getDocument():"); for (Class c: OOoInspector.queryInterface (aBean.getDocument ())) System.out.println (" "+c.getName ()); com.sun.star.datatransfer.XTransferable com.sun.star.document.XDocumentInfoSupplier com.sun.star.document.XDocumentLanguages com.sun.star.document.XDocumentSubStorageSupplier com.sun.star.document.XEmbeddedScripts com.sun.star.document.XEventBroadcaster com.sun.star.document.XEventsSupplier com.sun.star.document.XLinkTargetSupplier com.sun.star.document.XRedlinesSupplier com.sun.star.document.XStorageBasedDocument com.sun.star.document.XViewDataSupplier com.sun.star.drawing.XDrawPageSupplier com.sun.star.embed.XVisualObject com.sun.star.frame.XLoadable com.sun.star.frame.XModel com.sun.star.frame.XModel2 com.sun.star.frame.XModule com.sun.star.frame.XStorable com.sun.star.frame.XStorable2 com.sun.star.script.provider.XScriptProviderSupplier com.sun.star.style.XAutoStylesSupplier com.sun.star.style.XStyleFamiliesSupplier com.sun.star.text.XBookmarksSupplier com.sun.star.text.XChapterNumberingSupplier com.sun.star.text.XDocumentIndexesSupplier com.sun.star.text.XEndnotesSupplier com.sun.star.text.XFootnotesSupplier com.sun.star.text.XLineNumberingProperties com.sun.star.text.XNumberingRulesSupplier com.sun.star.text.XPagePrintable com.sun.star.text.XReferenceMarksSupplier com.sun.star.text.XTextDocument com.sun.star.text.XTextEmbeddedObjectsSupplier com.sun.star.text.XTextFieldsSupplier com.sun.star.text.XTextFramesSupplier com.sun.star.text.XTextGraphicObjectsSupplier com.sun.star.text.XTextSectionsSupplier com.sun.star.text.XTextTablesSupplier com.sun.star.ui.XUIConfigurationManagerSupplier com.sun.star.util.XCloseable com.sun.star.util.XCloseBroadcaster com.sun.star.util.XLinkUpdate com.sun.star.util.XModifiable com.sun.star.util.XModifiable2 com.sun.star.util.XModifyBroadcaster com.sun.star.util.XNumberFormatsSupplier com.sun.star.util.XRefreshable com.sun.star.util.XReplaceable com.sun.star.util.XSearchable com.sun.star.view.XPrintable com.sun.star.view.XPrintJobBroadcaster com.sun.star.view.XRenderable com.sun.star.xforms.XFormsSupplier */ /* System.out.println ("Interfaces implemented by controller:"); for (Class c: OOoInspector.queryInterface (controller)) System.out.println (" "+c.getName ()); com.sun.star.awt.XUserInputInterception com.sun.star.datatransfer.XTransferableSupplier com.sun.star.frame.XController com.sun.star.frame.XControllerBorder com.sun.star.frame.XDispatchInformationProvider com.sun.star.frame.XDispatchProvider com.sun.star.task.XStatusIndicatorSupplier com.sun.star.text.XRubySelection com.sun.star.text.XTextViewCursorSupplier com.sun.star.ui.XContextMenuInterception com.sun.star.view.XControlAccess com.sun.star.view.XFormLayerAccess com.sun.star.view.XSelectionSupplier com.sun.star.view.XViewSettingsSupplier */ /* System.out.println ("Interfaces implemented by frame:"); for (Class c: OOoInspector.queryInterface (getFrame ())) System.out.println (" "+c.getName ()); com.sun.star.awt.XFocusListener com.sun.star.awt.XTopWindowListener com.sun.star.awt.XWindowListener com.sun.star.document.XActionLockable com.sun.star.frame.XComponentLoader com.sun.star.frame.XDispatchInformationProvider com.sun.star.frame.XDispatchProvider com.sun.star.frame.XDispatchProviderInterception com.sun.star.frame.XFrame com.sun.star.frame.XFramesSupplier com.sun.star.task.XStatusIndicatorFactory com.sun.star.util.XCloseable com.sun.star.util.XCloseBroadcaster */ /* XFramesSupplier frames = OOoInspector.queryInterface (XFramesSupplier.class, getFrame ()); printProperties ("frames", frames); for (int i=0; i<frames.getFrames ().getCount (); i++) { XFrame frame = (XFrame)frames.getFrames ().getByIndex (i); printProperties ("Frame "+i, frame); } frames=[Proxy:16382237,6ace84c;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.frame.XFramesSupplier]] Title=test - OpenOffice.org Writer IndicatorInterception=Any[Type[com.sun.star.task.XStatusIndicator], null] LayoutManager=Any[Type[com.sun.star.frame.XLayoutManager], [Proxy:22149392,76bd794;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.frame.XLayoutManager]]] DispatchRecorderSupplier=Any[Type[com.sun.star.frame.XDispatchRecorderSupplier], null] IsHidden=false */ XPropertySet p = getXPropertySet (getFrame ()); Any any = (Any)p.getPropertyValue ("LayoutManager"); System.out.println (any); System.out.println (any.getClass ().getName ()); XLayoutManager layoutManager = (XLayoutManager)any.getObject (); printProperties ("layoutManager", layoutManager); /* printProperties ("containerWindow", getFrame ().getContainerWindow ()); containerWindow=[Proxy:11970262,6d33e60;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.awt.XWindow]] null */ /* printProperties ("componentWindow", getFrame ().getComponentWindow ()); componentWindow=[Proxy:25380515,8657cc4;msci[0];342169f1a1164ee688893a857f65b3e1,Type[com.sun.star.awt.XWindow]] null */ } catch (Exception e) { e.printStackTrace (); } } }; if (1 == 1) loadThread.start (); else loadThread.run (); } /** closes the bean viewer and tries to terminate OOo. */ public void terminate() throws NoConnectionException { setVisible(false); XDesktop xDesktop = null; xDesktop = aBean.getOOoDesktop(); aBean.stopOOoConnection(); if (xDesktop != null) xDesktop.terminate(); } /** closes the bean viewer, leaves OOo running. */ public void close() { setVisible(false); aBean.stopOOoConnection(); } public void printProperties (String name, Object obj) { System.out.println (name+"="+obj); if (obj != null) printProperties (getXPropertySet (obj)); } public void printProperties (XPropertySet set) { if (set == null) { System.out.println ("null"); return; } for (Property p: set.getPropertySetInfo ().getProperties ()) { try { System.out.println (p.Name+"="+set.getPropertyValue (p.Name)); } catch (Exception e) { throw new OOException ("Error getting value of property "+p.Name, e); } } } }
我们可以使用如下控件:
package ooswtviewer; import java.awt.BorderLayout; import java.awt.Frame; import java.awt.Panel; import java.io.File; import javax.swing.JRootPane; import org.eclipse.swt.SWT; import org.eclipse.swt.awt.SWT_AWT; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.layout.FillLayout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; /** * Code based on example from http://www.eclipsezone.com/eclipse/forums/t48966.html * * @author Aaron Digulla */ public class OOoSwtSnippet { public static void main(String[] args) { OOoSwtSnippet obj = new OOoSwtSnippet (); try { obj.run (args); } catch (Exception e) { e.printStackTrace (); } } public void run (String[] args) throws Exception { final Display display = new Display(); final Shell shell = new Shell(display); shell.setLayout(new FillLayout()); Composite composite = new Composite(shell, SWT.NO_BACKGROUND | SWT.EMBEDDED); System.setProperty("sun.awt.noerasebackground", "true"); /* Create and setting up frame */ Frame frame = SWT_AWT.new_Frame(composite); Panel panel = new Panel(new BorderLayout()) { public void update(java.awt.Graphics g) { paint(g); } }; frame.add(panel); JRootPane root = new JRootPane(); panel.add(root); java.awt.Container contentPane = root.getContentPane(); shell.setSize(800, 600); final OOoSwtViewer viewer = new OOoSwtViewer(); contentPane.add(viewer); // viewer.setDocument(NEW_WRITTER_DOCUMENT); File document = new File ("test.odt"); String url = document.getAbsoluteFile ().toURL ().toString (); url = "file:///" + url.substring (6); System.out.println ("Loading "+url); viewer.setDocument(url); shell.setText ("OOoSwtSnippet"); shell.open(); shell.addDisposeListener(new DisposeListener() { public void widgetDisposed(DisposeEvent e) { try { viewer.close(); } catch (RuntimeException exception) { exception.printStackTrace(); } } }); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
OOException是RuntimeException:
package ooswtviewer; /** * Wrapper for all OO exceptions to keep throws clauses in check * * @author Aaron Digulla */ public class OOException extends RuntimeException { public OOException () { super (); } public OOException (String message, Throwable cause) { super (message, cause); } public OOException (String message) { super (message); } public OOException (Throwable cause) { super (cause); } }
回答
http://sites.google.com/site/anshunjain/eclipse-musings/eclipse-hacks/eclipse-richt-text-editor
回答
实际上,我刚刚发现了另一个非常有前途的atm的小部件:
http://onpositive.com/richtext