【问题标题】:inline copy paste JEditorPane HTML内联复制粘贴 JEditorPane HTML
【发布时间】:2013-06-30 12:29:12
【问题描述】:

我正在拼命地尝试在 HTML 模式下在 JTextPane 中实现自定义复制/粘贴。 大部分工作正常,我使用 EditorKit.write() 获取 html 内容,然后使用 editorKit.read() 粘贴它。完美世界。

但是,当我在编辑器中有:<p> test </p> 并且我尝试复制“es”以获得 <p> tesest </p>,我得到了

<p>tes</p>
<p>es</p>
<p>t</p>

知道了这一点,我试图找出一种方法来粘贴“内联”应该是内联的部分,并阻止在复制过程中被阻止的部分。通常,

如果我有:

<p>mon beau sapin</p>
<p>roi des forêts</p>
<p>que j'aime ta verdure</p>

如果我复制:

beau sapin</p>
<p>roi des forêts</p>
<p>que

我希望在“mon”之后粘贴它:

<p>mon beau sapin</p>
<p>roi des forêts</p>
<p>que beau sapin</p>
<p>roi des forêts</p>
<p>que j'aime ta verdure</p>

我反而得到了:

<p>mon</p>
<p>beau sapin</p>
<p>roi des forêts</p>
<p>que</p>
<p>beau sapin</p>
<p>roi des forêts</p>
<p>que j'aime ta verdure</p>

我尝试了各种方法,例如删除第一行和最后一行的&lt;p&gt;&lt;/p&gt;(EditorKit.read 自行添加回来),使用 editorKit.insertHTML(但我应该放什么样的标签?),插入行线(大多数时候,我在另一个 p 中获得一个 p)等等。

但真正的问题是不可能在 htmlDocument 中写出您想要的内容。如何在指定位置写sapin&lt;/p&gt; &lt;p&gt;roi? EditorKit.read ?它将添加&lt;p&gt;sapin&lt;/p&gt; &lt;p&gt;roi&lt;/p&gt; Editorkit.insertHTML ?我需要精确的包装标签...

我向你展示我的最后一次尝试:

    private static void insertHTMLContent(JMathTextPane jtp, String html, int offset) {
        Document doc = Jsoup.parse(html);
        Elements elts = doc.body().children();
        //unwrap the last and first element
        if(elts.size()>2) { elts.last().unwrap(); }
        if(elts.size()>=1) { elts.first().unwrap(); }
        //We add a fake DIV element and remove it just at the next line
        editorKit.insertHTML(jtp.htmlDoc, offset, "<div id='copie'>"+doc.body().html()+"</div>", 0, 0, HTML.Tag.DIV);
        jtp.getHTMLdoc().setOuterHTML(jtp.getHTMLdoc().getElement("copie"),doc.body().html());
    }

我无法向您展示结果:EditorKit.write 尝试自行修复 html。但是 HTMLDocument 完全是一团糟。

供您尝试:

public class Test {

private static JTextPane editor = new Editor();
private static JMenuBar menu = new Menu();
private static String clipboard = "";

private static Action copy = new Copy();
private static Action paste = new Paste();

public static void main(String[] args) {
    JFrame f = new JFrame();
    f.setContentPane(editor);
    f.setJMenuBar(menu);
    f.setSize(600, 400);
    f.setVisible(true);
}

public static class Editor extends JTextPane {
    public Editor() {
        this.setDocument(new HTMLDocument());
        this.setEditorKit(new HTMLEditorKit());
    }
}

public static class Menu extends JMenuBar {
    public Menu() {
        add(new JButton(copy));
        add(new JButton(paste));

        getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_DOWN_MASK), "copy");
        getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_DOWN_MASK), "paste");
        getActionMap().put("copy", copy);
        getActionMap().put("paste", paste);
    }
}

public static class Copy extends AbstractAction {
    public Copy() {super("copy");}
    @Override
    public void actionPerformed(ActionEvent e) {
        StringWriter w = new StringWriter();
        try {
            editor.getEditorKit().write(w, editor.getDocument(), editor.getCaretPosition(), editor.getSelectedText().length());
        } catch (Exception ex) {Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);}
        clipboard = w.toString();
    }
}
public static class Paste extends AbstractAction {
    public Paste() {super("paste");}
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            editor.getEditorKit().read(new StringReader(clipboard), editor.getDocument(), editor.getCaretPosition());
        } catch (Exception ex) {Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);}
    }
}
}

对不起,我太长了。我接受任何帮助。

【问题讨论】:

  • 如需尽快获得更好的帮助,请发帖SSCCE

标签: java swing copy-paste jtextpane dom


【解决方案1】:

恐怕没有简单的方法。当您粘贴时,您希望保留原始段落并避免创建新的&lt;p&gt;,对吗?问题是当前段落和复制的段落可能具有不同的属性。例如。当前是左对齐,但复制的一个是右对齐。

如何解决此案?为了简化这个工具包,只需创建 &lt;p&gt; 元素。

您可以尝试从剪贴板内容创建一个独立的 HTMLDocument,并遍历文档的结构,提取元素(段落和文本)并将它们插入到原始文档中。

【讨论】:

  • 你如何迭代它?您是否介意包含一些示例代码,因为这将非常有帮助。
  • @StephaneGrenier 你可以尝试合并 2 个文档的例子作为地下室java-sl.com/tip_merge_documents.html
  • 在这种情况下,我想找到一种方法来找到与选择相对应的原始 html,这意味着提取整个 html 并且能够找到“selectionsStart”和“selectionEnd”位置。有什么办法吗?
  • 您可以使用套件的 write 方法传递基于选择开始/结束的值
【解决方案2】:

对于更多读者,我用一个非常简单的技巧解决了这个问题。我只是在需要时删除了粘贴文本前后添加的\n

public static void copyContent(JTextPane jtp, String text, int offset) {
    try {
        boolean start = offset>0 ? !jtp.getText(offset-1, 1).equals("\n") : false;
        Position p = jtp.getDocument().createPosition(offset);
        new HTMLEditorKit().read(new StringReader(html), jtp.getHTMLdoc(), offset);
        if(start) {jtp.getDocument().remove(offset, 1);}
        if(offset>0) {jtp.getDocument().remove(p.getOffset()-1, 1);}
    } catch (IOException | BadLocationException ex) {
        Logger.getLogger(EditeurIO.class.getName()).log(Level.SEVERE, null, ex);
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 2019-04-05
    相关资源
    最近更新 更多