首页 > 解决方案 > 将 pojo 列表复制到剪贴板

问题描述

朗:爪哇

我们正在尝试以表格格式将 pojo 列表复制到剪贴板。

要点:我们在这里要实现的目标:

1.将pojo列表转换为表格格式

2.如果用户将它复制到一些excel表格中,那么它应该很容易复制,或者即使用户尝试在记事本中复制它也应该以表格格式打印。

3. 将一些元数据添加到剪贴板以确定我们何时再次导入表的pojo。

为了将 pojo 列表转换为表格格式,我使用了jtable,但我无法将所有 jtable 内容导出到剪贴板。

谁能建议我是否应该遵循 jtable 方法并将表格复制到剪贴板或任何其他解决方案也可用。


更新:正如评论中所建议的,我尝试使用口味

public class ClipboardTest implements ClipboardOwner {
    public static void main(String[] args) {
        ClipboardTest clipboardTest = new ClipboardTest();
        clipboardTest.copyToClipboard();
        //clipboardTest.getFromClipboard();

    }

    public void copyToClipboard() {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Pojo data = new Pojo("1", "2", "ame2", "2", "2");
        MyObjectSelection dataSelection = new MyObjectSelection(data);
        StringSelection selection = new StringSelection("testing string");
        clipboard.setContents(dataSelection, ClipboardTest.this);
        System.out.println("copied to clipboard");
    }

    public void getFromClipboard() {
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        Transferable clipboardContent = clipboard.getContents(this);

        DataFlavor[] flavors = clipboardContent.getTransferDataFlavors();
        System.out.println("flavors.length = " + flavors.length);
        for (int i = 0; i < flavors.length; i++) {
            System.out.println("flavor[" + i + "] = " + flavors[i]);
        }
    }

    // ClipboardOwner implementation

    @Override
    public void lostOwnership(Clipboard clipboard, Transferable transferable) {
        System.out.println("ClipboardTest: Lost ownership");
    }

}


---
myobjectselection.java


public class MyObjectSelection implements Transferable, ClipboardOwner {
    private static DataFlavor dmselFlavor = new DataFlavor(Pojo.class,
            "Test data flavor");
    private Pojo selection;

    public MyObjectSelection(Pojo selection) {
        this.selection = selection;
    }

    // Transferable implementation

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        System.out.println("getTransferDataFlavors");
        DataFlavor[] ret = { dmselFlavor };
        return ret;
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        return dmselFlavor.equals(flavor);
    }

    @Override
    public synchronized Object getTransferData(DataFlavor flavor)
            throws UnsupportedFlavorException {
        if (isDataFlavorSupported(flavor)) {
            return this.selection;
        } else {
            throw new UnsupportedFlavorException(dmselFlavor);
        }
    }

    // ClipboardOwner implementation

    @Override
    public void lostOwnership(Clipboard clipboard, Transferable transferable) {
        System.out.println("MyObjectSelection: Lost ownership");
    }

}

-- pojo.java

public class Pojo  implements Serializable{
/**
     * 
     */
    private static final long serialVersionUID = 1L;
private String name;
private String name1;
private String name2;
private String name3;
    private String name4;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName1() {
        return name1;
    }

    public void setName1(String name1) {
        this.name1 = name1;
    }

    public String getName2() {
        return name2;
    }

    public void setName2(String name2) {
        this.name2 = name2;
    }

    public String getName3() {
        return name3;
    }

    public void setName3(String name3) {
        this.name3 = name3;
    }

    public String getName4() {
        return name4;
    }

    public void setName4(String name4) {
        this.name4 = name4;
    }

    public Pojo(String name, String name1, String name2, String name3,
            String name4) {
        super();
        this.name = name;
        this.name1 = name1;
        this.name2 = name2;
        this.name3 = name3;
        this.name4 = name4;
    }

}

当我尝试将字符串值复制到剪贴板时,它正在工作,但是当我尝试复制 pojo 时,它是否不起作用。

标签: javajtableclipboardpojo

解决方案


对于您想要支持的每种风格,您必须提供以指定格式对对象进行编码的方法。

这意味着您可能需要为纯文本、html 和 CVS 提供编码器以涵盖基础知识。

所以,根据你的Pojo,我写了一个Transferable支持:

  • ListPojo的)
  • HTML
  • CVS
  • 纯文本
  • 并序列化(作为 的补充List,但本质上是相同的)

PojoTransferable

public class PojoTransferable implements Transferable {

    public static final DataFlavor POJO_LIST_DATA_FLAVOR = new DataFlavor(List.class, "application/x-java-pojo-list;class=java.util.List");
    public static final DataFlavor HTML_DATA_FLAVOR = new DataFlavor("text/html", "HTML");
    public static final DataFlavor CSV_DATA_FLAVOR = new DataFlavor("text/csv", "CVS");
    public static final DataFlavor PLAIN_DATA_FLAVOR = new DataFlavor("text/plain", "Plain text");
    public static final DataFlavor SERIALIZED_DATA_FLAVOR = new DataFlavor(Pojo.class, "application/x-java-serialized-object; Pojo");

    private static String[] HEADERS = new String[]{"name", "name1", "name2", "name3", "name4"};
    private static Pojo POJO_HEADER = new Pojo("name", "name1", "name2", "name3", "name4");

    private List<Pojo> pojos;

    public PojoTransferable(List<Pojo> pojos) {
        this.pojos = pojos;
    }

    @Override
    public DataFlavor[] getTransferDataFlavors() {
        return new DataFlavor[]{POJO_LIST_DATA_FLAVOR, HTML_DATA_FLAVOR, CSV_DATA_FLAVOR, SERIALIZED_DATA_FLAVOR, PLAIN_DATA_FLAVOR};
    }

    @Override
    public boolean isDataFlavorSupported(DataFlavor flavor) {
        boolean supported = false;
        for (DataFlavor mine : getTransferDataFlavors()) {
            if (mine.equals(flavor)) {
                supported = true;
                break;
            }
        }
        return supported;
    }

    @Override
    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        Object data = null;
        if (POJO_LIST_DATA_FLAVOR.equals(flavor)) {
            data = pojos;
        } else if (HTML_DATA_FLAVOR.equals(flavor)) {
            data = new ByteArrayInputStream(formatAsHTML().getBytes());
        } else if (SERIALIZED_DATA_FLAVOR.equals(flavor)) {
            data = pojos;
        } else if (CSV_DATA_FLAVOR.equals(flavor)) {
            data = new ByteArrayInputStream(formatAsCVS().getBytes());
        } else if (PLAIN_DATA_FLAVOR.equals(flavor)) {
            data = new ByteArrayInputStream(formatAsPlainText().getBytes());
        } else {
            throw new UnsupportedFlavorException(flavor);
        }
        return data;
    }

    protected String formatAsCVS(Pojo pojo) {
        StringJoiner sj = new StringJoiner(",");
        sj.add(pojo.getName());
        sj.add(pojo.getName2());
        sj.add(pojo.getName3());
        sj.add(pojo.getName4());
        return sj.toString();
    }

    public String formatAsCVS() {
        StringBuilder sb = new StringBuilder(128);
        sb.append(formatAsCVS(POJO_HEADER));
        for (Pojo pojo : pojos) {
            sb.append(formatAsCVS(pojo));
        }
        return "";
    }

    protected Map<Integer, Integer> columnWidthsFor(Pojo pojo) {
        Map<Integer, Integer> columnWidths = new HashMap<>();
        columnWidths.put(0, pojo.getName().length());
        columnWidths.put(1, pojo.getName1().length());
        columnWidths.put(2, pojo.getName2().length());
        columnWidths.put(3, pojo.getName3().length());
        columnWidths.put(4, pojo.getName4().length());
        return columnWidths;
    }

    protected void apply(Map<Integer, Integer> pojoWidths, Map<Integer, Integer> columnWidths) {
        for (int index = 0; index < 5; index++) {
            int currentWidth = 2;
            if (columnWidths.containsKey(index)) {
                currentWidth = columnWidths.get(index);
            }
            int columnWidth = 2;
            if (pojoWidths.containsKey(index)) {
                columnWidth = pojoWidths.get(index);
            }
            columnWidths.put(index, Math.max(currentWidth, columnWidth));
        }
    }

    protected String formatAsPlainText(Pojo pojo, String format) {
        return String.format(format, pojo.getName(), pojo.getName1(), pojo.getName2(), pojo.getName3(), pojo.getName4());
    }

    public static String fill(int padding) {
        return String.format("%" + padding + "s", "").replace(" ", "-");
    }

    public String formatAsPlainText() {
        Map<Integer, Integer> columnWidths = new HashMap<>();

        apply(columnWidthsFor(POJO_HEADER), columnWidths);
        for (Pojo pojo : pojos) {
            apply(columnWidthsFor(pojo), columnWidths);
        }

        StringJoiner sjFormat = new StringJoiner("|");
        StringJoiner sjSep = new StringJoiner("+");
        for (int index = 0; index < 5; index++) {
            int currentWidth = 0;
            if (columnWidths.containsKey(index)) {
                currentWidth = columnWidths.get(index);
            }
            sjFormat.add(" %-" + currentWidth + "s ");
            sjSep.add(fill(currentWidth + 2));
        }
        sjFormat.add("%n");
        sjSep.add("\n");

        String seperator = sjSep.toString();
        String format = sjFormat.toString();
        StringBuilder sb = new StringBuilder(128);
        sb.append(formatAsPlainText(POJO_HEADER, format));
        for (Pojo pojo : pojos) {
            sb.append(seperator);
            sb.append(formatAsPlainText(pojo, format));
        }
        return sb.toString();
    }

    public String formatAsHTML() {
        StringBuilder sb = new StringBuilder(128);
        sb.append("<html><body>");
        sb.append("<table border='1'>");
        sb.append("<tr>");
        for (String header : HEADERS) {
            sb.append("<th>").append(header).append("</th>");
        }
        sb.append("</tr>");
        for (Pojo pojo : pojos) {
            sb.append("<tr>");
            sb.append("<td>").append(pojo.getName()).append("</td>");
            sb.append("<td>").append(pojo.getName1()).append("</td>");
            sb.append("<td>").append(pojo.getName2()).append("</td>");
            sb.append("<td>").append(pojo.getName3()).append("</td>");
            sb.append("<td>").append(pojo.getName4()).append("</td>");
            sb.append("</tr>");
        }
        sb.append("</table>");

        return sb.toString();
    }
}

测试...

然后我写了一个非常简单的测试......

List<Pojo> pojos = new ArrayList<>(25);
pojos.add(new Pojo("one", "two", "three", "four", "five"));

PojoTransferable pt = new PojoTransferable(pojos);
Clipboard cb = Toolkit.getDefaultToolkit().getSystemClipboard();
cb.setContents(pt, new ClipboardOwner() {
    @Override
    public void lostOwnership(Clipboard clipboard, Transferable contents) {
        System.out.println("Lost");
    }
});
try {
    Object data = cb.getData(PojoTransferable.POJO_LIST_DATA_FLAVOR);
    if (data instanceof List) {
        List listOfPojos = (List)data;
        System.out.println("listOfPojos contains " + listOfPojos.size());
        for (Object o : listOfPojos) {
            System.out.println(o);
        }
    }
} catch (UnsupportedFlavorException ex) {
    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
    Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
}

当我运行它时,它会打印出来......

listOfPojos contains 1
test.Pojo@5b480cf9

它告诉使用List味道有效(满足我们的需要),但随后我打开了文本编辑器、Word 和 Excel 并将内容粘贴到其中......

纯文本Excel单词

nb:Excel 使用了 HTML 格式,如图


推荐阅读