我正在尝试创建一个可以通过套接字发送带有文本的日志的小应用程序。由于插座被接受,该插座的输入流将存储在这样的哈希图中。
private HashMap<Integer,InputStream> allinputsstreams = new
HashMap<Integer,InputStream>();
之后,我将为该当前Inputstream创建一个新的Jframe
public LogListener(int socketid, SocketListener socketlistener, Gui gui) {
this.socketid = socketid;
this.gui = gui;
this.inputstream = socketlistener.getClient(socketid);
JFrame frame = new JFrame("Log listener");
frame.setLocationRelativeTo(null);
frame.setPreferredSize(new Dimension(framewidth,frameheight));
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
logarea = new JTextArea();
frame.add(logarea);
frame.pack();
frame.setVisible(true);
frame.addWindowListener(this);
listenthread = new Thread(this);
listenthread.start();
}
然后,我使用列表中的Inputstream接收数据并将其写入Jframe
public void run() {
input = new DataInputStream(inputstream);
while(!formclosed) {
try {
String addtext = input.readUTF();
addtext = formatText(addtext);
logarea.setText(logarea.getText() + addtext);
} catch (EOFException e) {
System.out.println("Looks like the client has been closed.");
return;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
这适用于接收1个Jframe上的数据,但是一旦我打开2个Jframes(意味着两次打开相同的InputStream(,那么输入流就没有了。我期望至少1个inputstream仍然可以使用。
听起来您正在尝试以两个不同的视图以从输入流显示数据。您真的不能两次阅读普通的InputStream
;相反,您需要某种缓冲。因此,我建议以两种方式之一修改您的代码,而不是尝试阅读两次,这两者都涉及仅对每个流进行单个读取循环:
-
修改您的读取循环以更新内部缓冲区,而不是调用
logarea.setText(logarea.getText() + addtext);
。每当读取循环更新缓冲区时,都应通知任何感兴趣的视图(通过您实现的某种观察者模式(,内容已更改。 -
修改读取循环以更新所有感兴趣的视图,而不是为每个
JFrame
提供单独的读取循环。读取循环需要访问日志区域列表,而不是单个logarea
。它将使用您现在使用的logarea
使用相同的逻辑来循环并更新每个日志区域。
关键是永远不要有两个读取循环访问相同的输入流。