Pregunta

Me gustaría mostrar un documento RTF en una aplicación SWT (en realidad, Eclipse RCP).

Sé que hay un widget Swing para mostrar y editar texto RTF, pero es Swing y tiene una apariencia bastante extraña cuando se usa en otra plataforma (sin mencionar que, hasta donde yo sé, no mostraba imágenes y solo tenía soporte limitado para formatear)

Otras opciones es usar la interfaz COM en Windows, pero eso funciona sólo en la plataforma Windows y requiere que se instale un control ActiveX RichEdit en la máquina del cliente...lo que puede hacer que la implementación de la aplicación sea bastante horrenda...

¿Cuáles son las otras opciones para mostrar documentos enriquecidos dentro de la aplicación Eclipse/SWT?

¿Fue útil?

Solución 5

En realidad, acabo de encontrar otro widget que es bastante prometedor:

http://onpositive.com/richtext

Otros consejos

Puede utilizar swt.custom.StyledText.Tiene muchas funciones para cambiar el aspecto del texto.Pero no creo que pueda cargar o guardar RTF en este momento.

Una vez escribí un editor HTML con él, pero es bastante difícil, ya que el modelo StyledText para agregar estilos a una parte del texto es muy extraño en comparación con la forma en que funciona HTML/RTF.

AFAIK, puede imprimir directamente desde este control, que crea internamente una representación RTF del contenido.Pero eso no es exactamente lo que pediste.

¿Por qué no leer primero el texto RTF en un StyledDocument usando RTFEditorKit y luego escribir el StyledDocument en un StringWriter usando HTMLEditorKit?

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();

¿Y luego mostrar el HTML?

Es posible que desee utilizar el control Swing con el Puente AWT/SWT.Usé esto para integrar OpenOffice en una aplicación 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);
            }
        }
    }

}

Puedes usar el control de esta manera:

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 es una 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);
    }

}

No estoy seguro de cómo hacerlo sin usar ActiveX.Si va en esta dirección, es posible que desee investigar el Contenedor IBM para documentos ActiveX, que se supone que permitirá una mejor integración de los documentos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top