Java复制到剪贴板

时间:2016-09-05 15:43:58

标签: java swing while-loop clipboard autoit

我正在用Java编写简单的应用程序。 程序从剪贴板获取数据,转换它,然后再次将其发送到剪贴板。 问题是,并不总是这些数据被发送回剪贴板,我不知道为什么。 你能帮帮我吗?

import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;

public class mainApp {
    DateFormat timeFormat = SimpleDateFormat.getTimeInstance();
    public static void main(String[] args) {
        mainApp app = new mainApp();
        app.menu();
    }

    void menu() {
        int choice = 0;
        while (choice != 2) {
            Scanner reader = new Scanner(System.in);
            System.out.println("1. Get data");
            System.out.println("2. Exit");
            choice = reader.nextInt();
            switch (choice) {
                case 1:
                    getData();
                    break;
                case 2:
                    break;
                default:
                    break;
            }
        }
    }

    void getData() {
        try {
            Process process = Runtime.getRuntime().exec("cpToClipboard.exe");
            System.out.println(timeFormat.format(new Date()) + ": Copying data");

            String data = (String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor);
            System.out.println(timeFormat.format(new Date()) + ": Data copied");
            System.out.println(timeFormat.format(new Date()) + ": " + data);
            System.out.println(timeFormat.format(new Date()) + ": Transferring.");

            String dataSplit[] = data.split(";");
            String getTicket = "";
            String getNrShop = "";
            String getNrPSD = "";
            String getPerson = "";
            String getTelephone = "";

            for (String dataSplitted : dataSplit) {
                String dataParameters[] = dataSplitted.split("=");
                switch (dataParameters[0]) {
                    case "TicketNumber":
                        getTicket = dataParameters[1];
                        System.out.println("Ticket number: " + getTicket);
                        break;
                    case "ClientNumber":
                        getNrShop = dataParameters[1];
                        System.out.println("Client number: " + getNrShop);
                        break;
                    case "Client":
                        getNrPSD = dataParameters[1];
                        System.out.println("Client: " + getNrPSD);
                        break;
                    case "Person":
                        getPerson = dataParameters[1];
                        System.out.println("Person: " + getPerson);
                        break;
                    case "Telephone":
                        getTelephone = dataParameters[1];
                        System.out.println("Phone Number: " + getTelephone);
                        break;
                    default:
                        break;
                }
            }

            System.out.println(timeFormat.format(new Date()) + ": Transferred.");

            String cpToClp = getNrShop + " " + getNrPSD + "\nPerson: " + getPerson + ", tel.: " + getTelephone + "\nTicker Number: " + getTicket + "\n";
            System.out.println(timeFormat.format(new Date()) + " " + cpToClp);
            System.out.println(timeFormat.format(new Date()) + ": Copying to Clipboard");

            StringSelection stringSelection = new StringSelection(cpToClp);
            Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
            clipboard.setContents(stringSelection, null);

            System.out.println(timeFormat.format(new Date()) + ": Data copied to clipboard.");
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

因此。从剪贴板我收到了风格的数据: "TicketNumber=517010593;ClientNumber=14:32;Client=0;Person=X‌​YZ XYZ;Telephone=546321635;"。 我的程序正确阅读。我转换这些数据所以我没有任何“=”或“;”。 转换后我应该收到:

Client name 
Person: Name Surname, tel.: 0530919237: 
Ticket Number: 23264235 

此数据应复制到clipbaord,并不总是被复制。对于10次测试,只有4或5是好的。在坏情况下,剪贴板与我的程序第一步中从剪贴板接收的相同

1 个答案:

答案 0 :(得分:2)

当您运行Runtime.getRuntime().exec("cpToClipboard.exe")时,启动 cpToClipboard命令。但它并不等待它回归。

所以现在你的Java程序和cpToClipboard并行运行,你可能有竞争条件:

  • 如果发生cpToClipboard在Java程序读取之前将数据放入剪贴板 - 一切都很好 - Java程序读取它,并将其替换为替换它所需的内容

  • 但是如果cpToClipboard在之后将数据写入,那么Java程序会尝试读取它,那么剪贴板中的数据将是cpToClipboard放在那里的数据。

  • 此外,cpToClipboard可能会将部分内容放入剪贴板,然后再完成。因此,Java程序将读取其中的一部分,然后编写其结果,然后cpToClipboard将其输出的第二部分写入剪贴板。

简而言之,当你并行运行时,你需要有特殊的方法来锁定剪贴板。但为什么要并行运行呢?通常情况下,我认为您要等到cpToClipboard执行所需操作并终止,然后才能处理剪贴板。

执行此操作的适当方法是在您获得的流程上调用waitFor()方法。

Process process = Runtime.getRuntime().exec("cpToClipboard.exe");
int result = process.waitFor();
if ( result == 0 ) {

    // Process the information in the clipboard as you do now

}

(当然,所有这些都必须在try-catch中,因为waitFor()在理论上也会抛出InterruptedException

使用process.destroy() 正确的方法 - 此杀死子流程,而不是允许它正常工作和终止。