【问题标题】:Is there an RTF display widget in SWTSWT 中是否有 RTF 显示小部件
【发布时间】:2010-09-10 01:08:50
【问题描述】:

我想在 SWT(实际上是 Eclipse RCP)应用程序中显示一个 RTF 文档。

我知道有一个用于显示和编辑 RTF 文本的 Swing 小部件,但它是 Swing 并且在其他平台中使用时在外观和感觉上非常陌生(更不用说据我所知它没有显示图像并且对格式化的支持有限)

其他选项是在 windows 上使用 COM 接口,但这仅适用于 windows 平台,并且需要在客户计算机上安装 ActiveX RichEdit 控件...这会使应用程序的部署非常可怕...

在 Eclipse/SWT 应用程序中显示富文档的其他选项是什么?

【问题讨论】:

    标签: java eclipse swt rtf


    【解决方案1】:

    您可以使用 swt.custom.StyledText。这有很多功能可以改变文本的外观。但我不认为它现在可以加载或保存 RTF。

    我曾经用它编写了一个 HTML 编辑器,但它非常困难,因为与 HTML/RTF 的工作方式相比,为部分文本添加样式的 StyledText 模型是如此陌生。

    AFAIK 您可以直接从此控件打印,该控件在内部创建内容的 RTF 表示。但这并不是你所要求的。

    【讨论】:

    • StyledText 会在复制时将 RTF 保存到剪贴板。获取 RTF 值的一种完全破解方法是全选、复制并从剪贴板中提取 RTF 值。
    • 是的,你是对的,这不是我问的。 StyledText 只能将文本作为 RTF 复制到剪贴板,并且根本不将 RTF 作为输入处理......使用 StyledText 作为 RTF 查看器/编辑器的基础可能是一种开始方式,但作为一个小部件本身,它不是什么我想要...
    【解决方案2】:

    我不确定不使用 ActiveX 的方法。如果您确实朝着这个方向发展,您可能需要查看IBM Container for ActiveX Documents,它应该可以更好地集成文档。

    【讨论】:

    • 我们现在想出的只是我想要的一半。基本上我们使用 JNI 来调用原生 Windows RTF 控件(WodPad 使用的那个)——这样我们就不必担心讨厌的 ActiveX 部署问题,但它仍然是一个 hack
    【解决方案3】:

    为什么不先使用 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?

    【讨论】:

    • 不错的技巧......虽然我有点害怕这种转换如何与我们目前在 RTF 文档中使用的各种制表位选项一起发挥作用。
    【解决方案4】:

    您可能希望将 Swing 控件与 AWT/SWT bridge 一起使用。我用它来将 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=680$9310
    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);
        }
    
    }
    

    【讨论】:

    • 不是真的 - 我不能强迫每个人都安装 OOo 和我的应用程序,我也不能指望人们在每个桌面上都安装 OOo(地狱,即使是 MS Office 也不是在每个目标桌面上都可用)
    • 我不确定你需要做多少“安装”。将JAR和OO的所有DLL安装在应用程序目录中就足够了,正确设置-Djava.library.path并且它应该可以工作。
    • 您可以做某事并不意味着您应该做某事。我给你选择;你必须决定哪个选项适合所有你没有提到的小细节,因为你不想在这个问题上花三天时间:)
    【解决方案5】:
    【解决方案6】:

    实际上,我刚刚发现了另一个很有前途的小部件:

    http://onpositive.com/richtext

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-08
      • 1970-01-01
      • 1970-01-01
      • 2019-12-20
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多