Reputation: 335
I am trying to create a small application that can send logs with text over a socket. As the socket is accepted the inputstream of that socket will be stored in a HashMap like this.
private HashMap<Integer,InputStream> allinputsstreams = new
HashMap<Integer,InputStream>();
after that I will create a new JFrame for that current inputstream
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();
}
Then I use the inputstream from the list to receive the data and write it on the 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();
}
}
}
This works for receiving the data on 1 JFrame, but once I open 2 JFrames(meaning opening the same inputstream twice) then none of the inputstreams work anymore. I was expecting atleast 1 inputstream would still work.
Upvotes: 0
Views: 618
Reputation: 234795
It sounds like you are trying to display the data from an input stream in two distinct views. You can't really read a plain InputStream
twice; instead, you need some kind of buffering. So rather than trying to read it twice, I suggest modifying your code in one of two ways, both of which involve using only a single read loop for each stream:
Modify your read loop to update an internal buffer instead of calling logarea.setText(logarea.getText() + addtext);
. Whenever the read loop updates the buffer, any interested views should be notified (via some sort of observer pattern that you implement) that the contents have changed.
Modify the read loop to update all interested views instead of having a separate read loop for each JFrame
. The read loop would need access to a list of log areas instead of a single logarea
. It would loop through the list and update each log area using the same logic you are now using for logarea
.
The key thing is to never have two read loops accessing the same input stream.
Upvotes: 1