2016-09-05 27 views
3

私はJavaで簡単なアプリケーションを書いています。 プログラムは、データをクリップボードから取得し、変換し、クリップボードに再度送信します。 問題は、必ずしもこのデータがクリップボードに返送されるとは限らず、なぜかわからないということです。 私を助けることができますか?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(); 
     } 
    } 
} 

So.クリップボードから私はスタイルでデータを受け取りました: "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のみが良好でした。悪い例では、クリップボードを使用すると、Runtime.getRuntime().exec("cpToClipboard.exe")それ開始cpToClipboardコマンドを実行すると私のプログラム

+1

さらに詳しい情報は、クリップボードに送信されたもの、期待している結果や行動、実際に見ていることを教えてください。どのくらいの頻度で問題が発生し、状況を悪化させる要因があるかを知っていますか? –

+0

ありがとうございますが、質問を編集してこの情報を表示してください。再度、あなたは何を期待しているのか、あなたが見ているものの両方を含める。 –

+1

'exec(" cpToClipboard.exe ")は何をすべきでしょうか? – RealSkeptic

答えて

2

の最初のステップでクリップボードから受信したと同じです。しかし、それはそれが戻るのを待つことはありません。

だから今、あなたのJavaプログラムとcpToClipboardを並列に実行していて、あなたが可能な競合状態を持っている:

  • Javaプログラムがそれを読むために取得する前にcpToClipboardがクリップボードにデータを置くことになった場合Javaプログラムはそれを読み込み、それを置き換えるために必要なものに置き換えます。

  • しかしcpToClipboardがデータを書き込む場合はJavaプログラムがそれを読むことを試みた後、クリップボード内のデータがcpToClipboardがそこに配置するものとなります。

  • また、cpToClipboardは、クリップボードに部分的な部分を入れて後で完成させることができます。したがって、Javaプログラムはその一部を読み込んでその結果を書き出し、cpToClipboardはその出力の2番目の部分をクリップボードに書き込みます。

要するに、並列で実行する場合、クリップボードをロックアウトする特別な方法が必要です。しかし、なぜ並行して実行するのですか?通常は、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 

} 

(これはすべてwaitFor()も理論的にはInterruptedExceptionをスローとして、当然のことながら、のtry-catch内でなければなりません)。このキルサブプロセスではなく、それが動作し、適切に終了することができます - process.destroy()を使用して

ない正しい方法です。

関連する問題