将JTextArea复制为"text/html";DataFlavor [英] Copy JTextArea as "text/html" DataFlavor

查看:69
本文介绍了将JTextArea复制为"text/html";DataFlavor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 JTextArea ,并且我正在使用 Highlighter 按照以下我的SSCCE对我的某些文本应用语法高亮显示:

I have a JTextArea and I am using a Highlighter to apply some syntax highlighting to some of my text as per my SSCCE below:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;

public class SSCCE extends JFrame {
  public SSCCE() {
    final JTextArea aMain = new JTextArea();
    aMain.setFont(new Font("Consolas", Font.PLAIN, 11));
    aMain.setMargin(new Insets(5, 5, 5, 5));
    aMain.setEditable(false);
    add(aMain);

    aMain.setText("The quick brown fox jumped over the lazy dog.");
    Highlighter h = aMain.getHighlighter();
    try {
      h.addHighlight(10, 15, new DefaultHighlighter.DefaultHighlightPainter(new Color(0xFFC800)));
    }
    catch (BadLocationException e) { 
      e.printStackTrace(); 
    }

    aMain.getActionMap().put("Copy", new AbstractAction() {
      public void actionPerformed(ActionEvent e) {
        aMain.copy();
      }
    });
    aMain.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "Copy");

    setTitle("SSCCE");
    setSize(350, 150);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setVisible(true);
  }

  public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
      public void run() {
        new SSCCE();
      }
    });
  }
}

当用户选择一部分文本并按CTRL + C时,我将调用 JTextArea 类的 copy()方法.这会将文本作为纯文本"复制到系统剪贴板上,并且我丢失了应用于文本的任何突出显示.我正在寻找一种复制样式信息的功能,该样式信息包括突出显示的"text/html"或"text/rtf".我相信我需要使用 Transferable DataFlavor 类,但是我正在努力将某些东西放在一起-我不知道如何从 JTextArea获取数据以正确的格式放置在剪贴板上.

When the user selects a portion of text and presses CTRL+C then I am calling the copy() method of the JTextArea class. This copies the text onto the system clipboard as Plain Text and I lose any highlighting I have applied to my text. I am looking for the ability to copy the style information which includes the highlights as either "text/html" or "text/rtf". I believe I need to use the Transferable and DataFlavor classes, but I am struggling putting something together - I don't know how to get the data from the JTextArea in the correct format to place onto the clipboard.

我基本上是在尝试复制突出显示的内容,然后将其粘贴到Microsoft Word或具有突出显示原样的类似应用程序中.样式数据是否以正确的格式提供,还是我必须通过枚举所有突出显示来手动构造HTML标记?

I am basically trying to copy the highlighting and then paste it into Microsoft Word or similar application with the highlighting intact. Is the style data available in the correct format or do I manually have to construct a HTML markup by enumerating all the highlights?

推荐答案

好的,基本上,因为荧光笔只是绘制"在 JTextArea 上,实际上并没有调整字体的样式.文字,您有点需要自己做

Okay, so basically, because the highlighter is just "painted" over the JTextArea and doesn't actually adjust the style of the text, you kind of need to do it all yourself

基本上,您需要:

  • 获取所有当前亮点的列表
  • 从文档中提取文本
  • 将其包装为html
  • 创建合适的基于HTML的可转让文件
  • 将html标记复制到剪贴板

容易...

import java.awt.Color;
import java.awt.Font;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.InputStream;
import java.io.Reader;
import java.io.StringBufferInputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.JFrame;
import static javax.swing.JFrame.EXIT_ON_CLOSE;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;

public class SSCCE extends JFrame {

    public SSCCE() {
        final JTextArea aMain = new JTextArea();
        aMain.setFont(new Font("Consolas", Font.PLAIN, 11));
        aMain.setMargin(new Insets(5, 5, 5, 5));
        aMain.setEditable(false);
        add(aMain);

        aMain.setText("The quick brown fox jumped over the lazy dog.");
        Highlighter h = aMain.getHighlighter();
        try {
            h.addHighlight(10, 15, new DefaultHighlighter.DefaultHighlightPainter(new Color(0xFFC800)));
        } catch (BadLocationException e) {
            e.printStackTrace();
        }

        aMain.getActionMap().put("Copy", new AbstractAction() {
            public void actionPerformed(ActionEvent e) {
                Highlighter h = aMain.getHighlighter();
                Highlighter.Highlight[] highlights = h.getHighlights();
                StringBuilder sb = new StringBuilder(64);
                sb.append("<html><body>");
                boolean markedUp = false;
                for (Highlighter.Highlight highlight : highlights) {
                    int start = highlight.getStartOffset();
                    int end = highlight.getEndOffset();

                    try {
                        String text = aMain.getDocument().getText(start, end - start);

                        sb.append("<span style = 'background-color: #FFC800'>");
                        sb.append(text);
                        sb.append("</span>");
                        markedUp = true;
                    } catch (BadLocationException ex) {
                        ex.printStackTrace();
                    }
                }
                sb.append("</body></html>");
                if (markedUp) {
                    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
                    clipboard.setContents(new HtmlSelection(sb.toString()), null);
                }
            }
        });
        aMain.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "Copy");

        setTitle("SSCCE");
        setSize(350, 150);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new SSCCE();
            }
        });
    }

    private static class HtmlSelection implements Transferable {

        private static List<DataFlavor> htmlFlavors = new ArrayList<>(3);

        static {

            try {
                htmlFlavors.add(new DataFlavor("text/html;class=java.lang.String"));
                htmlFlavors.add(new DataFlavor("text/html;class=java.io.Reader"));
                htmlFlavors.add(new DataFlavor("text/html;charset=unicode;class=java.io.InputStream"));
            } catch (ClassNotFoundException ex) {
                ex.printStackTrace();
            }

        }

        private String html;

        public HtmlSelection(String html) {
            this.html = html;
        }

        public DataFlavor[] getTransferDataFlavors() {
            return (DataFlavor[]) htmlFlavors.toArray(new DataFlavor[htmlFlavors.size()]);
        }

        public boolean isDataFlavorSupported(DataFlavor flavor) {
            return htmlFlavors.contains(flavor);
        }

        public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException {
            if (String.class.equals(flavor.getRepresentationClass())) {
                return html;
            } else if (Reader.class.equals(flavor.getRepresentationClass())) {
                return new StringReader(html);
            } else if (InputStream.class.equals(flavor.getRepresentationClass())) {
                return new StringBufferInputStream(html);
            }
            throw new UnsupportedFlavorException(flavor);
        }
    }
}

我已将其粘贴到文本编辑器中,并在浏览器中打开并粘贴到Word中

I've pasted this to a text editor and opened in a browser and pasted into to Word

以上内容基于 查看全文

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆