-1

有一个自定义侦听器用于将消息从一个 java 类发送到另一个,但是当侦听器用于发送消息时,每次侦听器向另一个类发送消息时都会创建一个新的 JFrame 窗口,它最终的问题是是许多 Jframe 窗口的堆栈。

原因是我必须为监听器创建一个java类的实例,因为它需要实例化监听器

 listener = (OnSendResultListener) new ConnectionUtility(false);

因此,每次 java 类向另一个 java 类发送一条短文本消息时,它都会创建另一个 ConnectionUtitlity() 对象并启动一个新的 JFrame 窗口。不是我想要的。但是如果我试图通过在 ConnectionUtility 类构造函数中传递一个布尔参数来确定实例化何时是真实的(true)或侦听器何时被实例化(false)来避免这种情况,它将崩溃。所以这也无济于事,因为在为侦听器实例化时删除类的某些部分不允许它工作。

我如何使用简单的侦听器将消息从一个活动发送到另一个活动并提醒它操作,而不必实例化超类或封装类?

在 Android 中,我会为此使用广播接收器。但是在java桌面应用程序中如何让它工作?

两个 java 类 MultiThreader 和 ConnectionUtility 的示例代码

MultiThreader 类实现监听器并向 ConnectionUtility 类发送消息

 public class MultiThreader {

类的构造函数实例化从 ConnectionUtility 转换的 OnSendResultListener 对象

 public MultiThreader() {

    listener = (OnSendResultListener) new ConnectionUtility(false);
 }

侦听器接口嵌套在 MultiThreader 类内部作为内部类

public interface OnSendResultListener {

   public void onStringResult(String transferString);

}

MultiThreader类中调用监听器的方法

 public void sendStatus(String status){

     listener.onStringResult(status);

 }

在 MutliThreader 类中调用以使用侦听器将字符串消息发送到 ConnectionUtility 类

  sendStatus("File sent to server, Successful");  

connectionUtility 类从 MultiThreader 类接收消息

  public class ConnectionUtility extends javax.swing.JFrame
  implements MultiThreader.OnSendResultListener {

用于从 MultiThrader 类接收消息并指示何时收到这些消息的回调方法

  @Override
  public void onStringResult(String transferString) {

     jTextArea1.setText(displayString); // sets textArea to string received

 }

编辑:每个类的完整代码示例如下所示

public class MultiThreader implements Runnable {

private Socket socket;
public int fileSizeFromClient;
FileOutputStream fos = null;
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
DataInputStream dis = null;
DataOutputStream dos = null;
ScheduledThreadPoolExecutor stpe;
private OnSendResultListener listener;

public MultiThreader(Socket s) {
    socket = s;
    stpe = new ScheduledThreadPoolExecutor(5);
    listener = (OnSendResultListener) new ConnectionUtility();
}

@Override
public void run() {

    long serialNumber = 0;
    int bufferSize = 0;

     // get input streams
    try {
    bis = new BufferedInputStream(socket.getInputStream());
    dis = new DataInputStream(bis);
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    sendStatus("New connection strarted");

     // read in streams from server
    try {        
        fileSizeFromClient = dis.readInt();
         sendStatus("File size from client " + fileSizeFromClient);
         serialNumber = dis.readLong();
         sendStatus("Serial mumber from client " + serialNumber);
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

     try {
        bufferSize = socket.getReceiveBufferSize();
         sendStatus("Buffer size " + bufferSize);
    } catch (SocketException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    String serialString = String.valueOf(serialNumber);

    File fileDirectory = new File("C:" + File.separator + "DOWNLOAD" + File.separator + serialNumber + File.separator);
    fileDirectory.mkdir();

    File file = new File("C:" + File.separator + "DOWNLOAD" + File.separator + serialNumber + File.separator + "JISSend.pdf");
    try {
        file.createNewFile();
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }
    try {
    fos = new FileOutputStream(file);
    bos = new BufferedOutputStream(fos);
    dos = new DataOutputStream(bos);
    } catch (FileNotFoundException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    int count = 0;
    byte[] buffer = new byte[fileSizeFromClient];

    try {

      int totalBytesRead = 0;

       while(totalBytesRead < fileSizeFromClient){
       int bytesRemaining = fileSizeFromClient - totalBytesRead;
       int bytesRead = dis.read(buffer, 0, (int)Math.min(buffer.length, bytesRemaining));

        if(bytesRead == -1){
           break;
         }else{

            dos.write(buffer, 0, bytesRead);
            totalBytesRead += bytesRead;

        }
   }

        } catch (IOException ex) {
            Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {

            dos = new DataOutputStream(socket.getOutputStream());

        } catch (IOException ex) {
            Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
        }

        stpe.schedule(new CompareFiles(), 0, TimeUnit.SECONDS);
        stpe.schedule(new CloseResources(), 2, TimeUnit.SECONDS);

  } // end run method

  public class CompareFiles implements Runnable {

    @Override
    public void run() {

 int returnInt = 0;
 FileInputStream fis = null;

         File file = new File("C:/DOWNLOAD/JISSend.pdf");
    try {
        fis = new FileInputStream(file);
    } catch (FileNotFoundException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

        int fileLength = (int) file.length();

        sendStatus("Size of database file sent " + fileLength);

         if(fileLength == fileSizeFromClient){

         sendStatus("File sent to server, Successful");   
         returnInt = 1;

         }else if(fileLength != fileSizeFromClient){

         sendStatus("ERROR, file send failed");   
         returnInt = 2;

         }
        try {
            dos.writeInt(returnInt);
        } catch (IOException ex) {
            Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
        }

    } // end run method
   } // end of class comparefiles

   public class CloseResources implements Runnable {

    @Override
    public void run() {

    try {
    fos.flush();
    bis.close();
    bos.close();
    dis.close();
    dos.close();
    socket.close();
    } catch (IOException ex) {
            Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    } // end run method
    } // end of class closeResources

 public interface OnSendResultListener {
 public void onStringResult(String transferString);
 }

 public void sendStatus(String status){
 listener.onStringResult(status);
 }

 } // end class multithreader

  public class ConnectionUtility extends javax.swing.JFrame implements
  MultiThreader.OnSendResultListener {

    String  outputLine = "";

    boolean runner = true;
PrintWriter out;
BufferedReader in;
ServerSocket serversocket;
    Socket socket;
    boolean startServer = true;
    public static String displayString = "";

    private ConnectionUtility() {

     initComponents();

     this.startServer = startServer;
     this.setVisible(true);
     serverRunner();

     File fileOne = new File("C:/DBFiles");
     if(!fileOne.exists()){
         fileOne.mkdir();
     }

     File fileTwo = new File("C:/DBFilesOut");
     if(!fileTwo.exists()){
         fileTwo.mkdir();
     }  

 }

@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
 private void initComponents() {

    jLabel1 = new javax.swing.JLabel();
    jScrollPane1 = new javax.swing.JScrollPane();
    jTextArea1 = new javax.swing.JTextArea();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jLabel1.setFont(new java.awt.Font("MS UI Gothic", 0, 36)); // NOI18N
    jLabel1.setText("TankInspectionSystem");

    jTextArea1.setColumns(20);
    jTextArea1.setRows(5);
    jScrollPane1.setViewportView(jTextArea1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(72, 72, 72)
            .addComponent(jLabel1)
            .addContainerGap(76, Short.MAX_VALUE))
        .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 383, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addGap(37, 37, 37)
            .addComponent(jLabel1)
            .addGap(34, 34, 34)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 179,   javax.swing.GroupLayout.PREFERRED_SIZE)
            .addContainerGap(37, Short.MAX_VALUE))
    );

    pack();
}// </editor-fold>                        

 // Variables declaration - do not modify                     
 private javax.swing.JLabel jLabel1;
 private javax.swing.JScrollPane jScrollPane1;
 private javax.swing.JTextArea jTextArea1;
 // End of variables declaration                   

 public void serverRunner(){

      runner = true;

       try {
        serversocket = new ServerSocket(6789, 100);

         System.out.println();

    } catch (IOException ex) {
        Logger.getLogger(ConnectionUtility.class.getName()).log(Level.SEVERE, null, ex);
    }

      while(runner){

         try {
             socket = serversocket.accept();

  addAndDisplayTextToString("new connection, inet socket address >>> " + socket.getPort());
  System.out.println(displayString);


         } catch (IOException ex) {
             Logger.getLogger(ConnectionUtility.class.getName()).log(Level.SEVERE, null, ex);
         }

           MultiThreader multi = new MultiThreader(socket);
           Thread t = new Thread(multi);
           t.start();

      }  // end while runner loop

 } // end serverRunner method

 public static void addAndDisplayTextToString(String setString){

   StringBuilder stb = new StringBuilder(displayString);

   setString = setString + "\n";

   if(stb.toString() == ""){
   stb.append(setString);
   }else if(stb.toString() != ""){
       stb.insert(0, setString);
   }

    int counter = 0;

  for(int i = 0; i < stb.length(); i++){
      if(stb.substring(i, i + 1).equals("\n")){
           counter++;
      }
  }

  // get the last index of "\n"
  int lastIndex = stb.lastIndexOf("\n");

  int maximum = 4;
  if(counter >= maximum){

      stb.delete(lastIndex, stb.length());
      System.out.println();

  }

  displayString = stb.toString();

 }

 @Override
 public void onStringResult(String transferString) {
   addAndDisplayTextToString(transferString);
   jTextArea1.setText(displayString);

}

} // class ConnectionUtility
4

1 回答 1

0

如果您只想要一个对象的单个实例,无论您在哪里调用它,请执行以下操作:

public class MyObject {

    private static MyObject instance;

    public static MyObject getInstance(..) {
        if (instance != null) {
            return instance;
        }
        return instance = new MyObject(..);
    }

    // private constructor to avoid new instances 
    private MyObject(..) { .. }
}

MyObject anObject = MyObject.getInstance(..); // always returns the same instance

'..' 表示任意参数。我通常在构造时传递一个上下文,然后根据我想要它执行的操作使用对象上的设置器来操作它,例如 setMessage(..) 更改输出或 setCallListener(..) 将回调重定向到另一个对象。

不确定这是您要找的东西,但感觉是这样的。

编辑:

看到你的代码后,那么在 ConnectionUtility 怎么样:

MultiThreader multi = new MultiThreader(socket, this);

在多线程中:

public MultiThreader(Socket s, OnSendResultListener resultListener) {
    socket = s;
    stpe = new ScheduledThreadPoolExecutor(5);
    listener = resultListener;
}

请注意,单实例方法也应该可以工作,只是认为这可能是最简单的解决方案,因为您可以使用this直接传递它(因为实现了正确的接口)。

于 2013-10-02T01:23:10.890 回答