有一个自定义侦听器用于从一个java类向另一个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
答案 0 :(得分: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
'..'表示任意参数。我通常在构造时传递一个Context,然后在其上使用对象上的setter来操作它,这取决于我想要它做什么,例如setMessage(..)更改输出或setCallListener(..)将回调重定向到另一个对象。
不确定这是你在找什么,但感觉它是这样的。
修改强>
看到你的代码之后,那么在ConnectionUtility中如何:
MultiThreader multi = new MultiThreader(socket, this);
在MultiThreader中:
public MultiThreader(Socket s, OnSendResultListener resultListener) {
socket = s;
stpe = new ScheduledThreadPoolExecutor(5);
listener = resultListener;
}
请注意,单实例方法也应该有效,只要认为这可能是最简单的解决方案,因为您可以使用 this 直接传递它(因为实现了正确的接口)。