3

別のクラスからあるクラスの jTextArea に追加できるかどうか疑問に思っていますか? 基本的に、常に計算を実行している単純なクラスがあり、独自のクラスで作成した GUI で出力を表示したいと考えています。プログラムは System.out.println を介して正常に実行されますが、これをテキストエリアで表示したいと考えています。ご指導いただきありがとうございます。

更新 - 以下のコードは私が実行しているものです。問題の領域は次のとおりです (これはかなり大きなクラスのメソッドです)。

System.out.println("From Server:" + sentenceFromServer);

この出力を、下のクラスの下にある別のクラスにある別の jTextArea に書き込む必要があります。

クライアントクラス

public void run() {
   SocketForm form = new SocketForm();
    //File file=null;

  long startTime; // Starting time of program, in milliseconds.
  long endTime;   // Time when computations are done, in milliseconds.
  double time; 
  System.out.println("Variables Set");
  String serverName = "localhost";
   try {
    //if (args.length >= 1)
       // serverName = args[0];
  InetAddress serverIPAddress = InetAddress.getByName(serverName);

    //get server port;
    int serverPort = form.cliportNo;
    //if (args.length >= 2)
      //  serverPort = Integer.parseInt(args[1]);
    //create socket
    DatagramSocket clientSocket = new DatagramSocket();
    //get input from keybaord
    byte[] sendData = new byte[byteSize];
    //BufferedReader inFromUser = new BufferedReader(new InputStreamReader (System.in));
    //while (true){
    //String sentence = inFromUser.readLine();
    startTime = System.currentTimeMillis();
    //sendData = sentence.getBytes();
    System.out.println("About to identify image");
    String fileName = "/Users/Andrew/Desktop/pic.jpg";
    File f = new File(fileName);

    FileInputStream fis = null;
    try {
        fis = new FileInputStream(f);
        System.out.println("Total file size to read in bytes is : " + fis.available());

    } catch (IOException e) {}


 Path path = Paths.get("/Users/Andrew/Desktop/pic.jpg");
 //byte[] data = Fles.readAllBytes(path);
  sendData = Files.readAllBytes(path);   

    try {
    for( int index = 0; index < sendData.length ; index += byteSize ) {
     DatagramPacket packet = new DatagramPacket( sendData, index, Math.min( byteSize, sendData.length-index ), serverIPAddress, serverPort);
     clientSocket.send(packet);
    //DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverIPAddress, serverPort);

    //receive datagram
    byte[] receiveData = new byte [byteSize];

    DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
    clientSocket.receive(receivePacket);
    //print output
    String sentenceFromServer = new String(receivePacket.getData());
    System.out.println("From Server:" + sentenceFromServer);
    }
    System.out.println("The End");
    }
    catch (Exception e) {}
    //close client socket
            //clientSocket.close();
        endTime = System.currentTimeMillis();
  time = endTime - startTime;
      System.out.println("Time :" + time);
   // }
}
   catch (Exception e) {}
}

SocketForm クラス (GUI)

public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(SocketForm.class.getName()).log(java.util.logging.Level.SEV
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new SocketForm().setVisible(true);
        }
    });
}
// Variables declaration - do not modify                     
private javax.swing.ButtonGroup buttonGroup1;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTabbedPane jTabbedPane1;
public static javax.swing.JTextArea jTextArea1;
private javax.swing.JTextField jTextField1;
private javax.swing.JTextField jTextField2;

// End of variables declaration                   

}

4

1 に答える 1

3

提案:

  • GUI クラスにパブリック メソッドを指定します。このメソッドpublic void appendText(String text)は、テキスト文字列を JTextArea に単純に追加します。
  • テキストを JTextArea に追加したい外部クラスは、このメソッドを持つクラスへの有効な参照のみを必要とし、それを呼び出す必要があります。
  • Swing イベント スレッドである EDT でのみこのメソッドを呼び出すように注意する必要があります。
  • これは実行時間の長いコードから実行するため、この実行時間の長いコードは Swing イベント スレッドから切り離して実行する必要があります。SwingWorker はこれに適しています。非常に役立つので、Google でチュートリアルを調べてください。
  • Swing Event D ispatch ThreadまたはEDTSwingWorker<Void, String>でサーバーから JTextArea に文字列を送信するには、特に公開/処理メソッドのペアを使用することを検討する必要があります。
  • 上記のコードで示したように、空の catch ブロックを使用しないでくださいcatch (IOException e) {}。これは、目を閉じてオートバイを運転するのと同等のコーディングです。はい、最初は楽しいように見えるかもしれませんが、ほとんどの場合、うまくいきません。

あなたの状態を編集
:

「あなたが言うように、EDTで実行するのにしか適していない場合、すでに実行されているスレッド内でこれをどのように定義できますか?」

私は2つの方法を知っています:

  1. バックグラウンド スレッドには SwingWorker を使用し、これには publish/process メソッドのペアを使用します。よく説明されている SwingWorker チュートリアルを確認するか、
  2. 標準のバックグラウンド スレッドを使用し、メソッドに渡す Runnable 内に Swing 呼び出しを配置し​​ますSwingUtilities.invokeLater(...)
于 2013-10-20T01:21:49.840 に答える