我的GWT应用程序使用TinyMCE还是SmartGWT富文本编辑器?

3

我希望为我的GWT应用程序添加一个富文本编辑器。 TinyMCE是一个选择,SmartGWT中的富文本编辑器也是如此。你有关于如何在两者之间进行选择的建议吗?

3个回答

7
我不会轻易地对TinyMCE置之不理 - 它比GWT的富文本编辑器有许多优点 - 对我来说,它是插件 - 我需要一个能够生成bbcode而不是html的富文本编辑器 - 不幸的是,使用GWT的组件无法做到这一点。因此,我扩展了TinyMCE的标准bbcode插件以满足我的需求,完成了。

下面是我用来将TinyMCE集成到GWT中的一个类(稍微修改了原始类Aaron Watkins,以解决拖放问题和其他一些问题 ;)):

编辑:稍作修改以包括David的建议

/**
 * Created on 20/08/2007
 *
 * Wrapper for TinyMCE
 * NOTE: Expects Javascript includes to be in enclosing HTML
 *
 * Author: Aaron Watkins (aaronDOTjDOTwatkinsATgmailDOTcom)
 * Website: http://www.goannatravel.com
 * Home Page for initial release of this widget: http://consult.goannatravel.com/code/gwt/tinymce.php
 *
 * Copyright [Aaron Watkins]
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.HasText;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * TinyMCE -
 *
 * A wrapper widget for using TinyMCE. It contains a number of JSNI methods that
 * I have found useful during development
 *
 * @author Aaron Watkins
 */
public class TinyMCE extends Composite implements HasText {

    private TextArea ta;
    private String id;

    public TinyMCE(int width, int height) {
        super();

        VerticalPanel panel = new VerticalPanel();
        initWidget(panel);
        panel.setWidth("100%");

        id = HTMLPanel.createUniqueId();
        ta = new TextArea();
        ta.setCharacterWidth(width);
        ta.setVisibleLines(height);
        DOM.setElementAttribute(ta.getElement(), "id", id);
        DOM.setStyleAttribute(ta.getElement(), "width", "100%");
        panel.add(ta);
    }

    /**
     * getID() -
     *
     * @return the MCE element's ID
     */
    public String getID() {
        return id;
    }

    protected static native String getEditorContents(
        String elementId) /*-{
        return $wnd.tinyMCE.get(elementId).getContent();
    }-*/;

    protected static native void setEditorContents(
        String elementId, String html) /*-{
        $wnd.tinyMCE.execInstanceCommand(
        elementId, 'mceSetContent', false, html, false);
    }-*/;

    public void setText(String text) {
        setEditorContents(id, text);
    }

    public String getText() {
        return getEditorContents(id);
    }

    public void setEnabled(boolean enabled) {
        ta.setEnabled(enabled);
    }

    /**
     * @see com.google.gwt.user.client.ui.Widget#onLoad()
     */
    protected void onLoad() {
        super.onLoad();

        DeferredCommand.addCommand(new Command() {
            public void execute() {
                setWidth("100%");
                setTextAreaToTinyMCE(id);
                focusMCE(id);
            }
        });
    }

    /**
     * focusMCE() -
     *
     * Use this to set the focus to the MCE area
     * @param id - the element's ID
     */
    protected native void focusMCE(String id) /*-{
        $wnd.tinyMCE.execCommand('mceFocus', true, id);
    }-*/;

    /**
     * resetMCE() -
     *
     * Use this if reusing the same MCE element, but losing focus
     */
    public native void resetMCE() /*-{
        $wnd.tinyMCE.execCommand('mceResetDesignMode', true);
    }-*/;

    /**
     * unload() -
     *
     * Unload this MCE editor instance from active memory.
     * I use this in the onHide function of the containing widget. This helps
     * to avoid problems, especially when using tabs.
     */
    public void unload() {
        unloadMCE(id);
    }

    /**
     * unloadMCE() -
     *
     * @param id - The element's ID
     * JSNI method to implement unloading the MCE editor instance from memory
     */
    protected native void unloadMCE(String id) /*-{
        $wnd.tinyMCE.execCommand('mceFocus', false, id);
        $wnd.tinyMCE.execCommand('mceRemoveControl', false, id);
    }-*/;

    /**
     * updateContent() -
     *
     * Update the internal referenced content. Use this if you programatically change
     * the original text area's content (eg. do a clear)
     * @param id - the ID of the text area that contains the content you wish to copy
     */
    protected native void updateContent(String id) /*-{
        $wnd.tinyMCE.activeEditor = $wnd.tinyMCE.get(id);
        $wnd.tinyMCE.activeEditor.setContent($wnd.document.getElementById(id).value);
    }-*/;

    /**
     * getTextArea() -
     *
     */
    protected native void getTextData(String id) /*-{
        $wnd.tinyMCE.activeEditor = $wnd.tinyMCE.get(id);
        $wnd.tinyMCE.activeEditor.save();
        $wnd.tinyMCE.triggerSave();
    }-*/;

    /**
     * encodeURIComponent() -
     *
     * Wrapper for the native URL encoding methods
     * @param text - the text to encode
     * @return the encoded text
     */
    protected native String encodeURIComponent(String text) /*-{
        return encodeURIComponent(text);
    }-*/;

    /**
     * setTextAreaToTinyMCE() -
     *
     * Change a text area to a tiny MCE editing field
     * @param id - the text area's ID
     */
    protected native void setTextAreaToTinyMCE(String id) /*-{
        $wnd.tinyMCE.execCommand('mceAddControl', true, id);
    }-*/;

    /**
     * removeMCE() -
     *
     * Remove a tiny MCE editing field from a text area
     * @param id - the text area's ID
     */
    public native void removeMCE(String id) /*-{
        $wnd.tinyMCE.execCommand('mceRemoveControl', true, id);
    }-*/;
}

记得在你的HTML文件中初始化TinyMCE,类似于以下代码(关键设置是mode : "textareas",其余设置可以安全更改):

<script type="text/javascript" src="js/tiny_mce/tiny_mce.js"></script>
    <script type="text/javascript">
    tinyMCE.init({
        theme : "advanced",
        skin : "default",
        mode : "textareas",
        plugins : "bbcode",
        theme_advanced_buttons1 : "bold,italic,strikethrough,separator,justifyleft,justifycenter,justifyright,justifyfull,separator,bullist,numlist,separator,sup,sub,|,undo,redo,separator,cut,copy,paste,|,fontsizeselect,forecolor,backcolor",
        theme_advanced_buttons2 : "blockquote,link,unlink,image,styleselect,removeformat,|,charmap,code",
        theme_advanced_buttons3 : "",
        theme_advanced_toolbar_location : "bottom",
        theme_advanced_toolbar_align : "center",
        theme_advanced_styles : "Code=codeStyle;Quote=quoteStyle;PHP Code=phpCodeStyle",
        entity_encoding : "raw",
        add_unload_trigger : false,
        remove_linebreaks : false,
        button_tile_map : true
    });
    </script> 

您还可以尝试一些其他的包装器,例如http://www.ohloh.net/p/tinymce-gwt


谢谢你,igro;我已经开始使用你发布的代码。在Firefox中它运行得非常好。奇怪的是,在GWT托管的浏览器中,setText(String)方法似乎不起作用。 - David
我编辑了我的帖子,加入了你的代码David,希望现在能够正常工作(因为我已经有一段时间没有使用那个类了,而且它是针对我相当奇特的应用程序进行调整的——TinyMCE区域可以被拖动等,这使得一切都变得更加困难——TinyMCE不喜欢你对其绑定的底层DOM元素做任何操作)。 - Igor Klimer

3
如果你已经在使用GWT,那么不使用GWT富文本编辑器组件,无疑是自掘坟墓,可以选择SmartGWT库或其他库中的组件。
值得注意的是,GWT也有RichTextArea class

0
由于某些原因,Aaron Watkins的代码在GWT托管模式下无法正常工作。我通过更改编辑器内容的设置和检索方式来解决了这个问题。
我添加了以下两个方法:
protected static native String getEditorContents(
   String elementId) /*-{
   return $wnd.tinyMCE.get(elementId).getContent();
}-*/;

protected static native void setEditorContents(
   String elementId, String html) /*-{
   $wnd.tinyMCE.execInstanceCommand(
     elementId, 'mceSetContent', false, html, false);
}-*/;

...并将setText()和getText()方法替换为以下内容:

public void setText(String text) {
   setEditorContents(id, text);
}

public String getText() {
   return getEditorContents(id);
}

我不确定这是否是“最佳实践” - 我相信Aaron有他做事情的原因 - 但它使我的代码在Firefox和GWT托管浏览器中都可以工作。


这个答案是接下来的一个,不确定为什么StackOverflow搞乱了顺序。 - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接