Reputation: 185
As the title says, when i try to dynamically add an element to a JList
, which is inside a JScrollPane
, it becomes empty. I think it has something to do with multithreading.
The GUI is a simple monitoring interface for a server I am working on. I'll post parts of the code I think is responsable for this:
But first, this is the frame:
public class EventMonitor extends JFrame{
private JList eventList;
private DefaultListModel<String> dlm ;
JScrollPane jPane;
public EventMonitor()
{
super("Server Monitor");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLayout(new FlowLayout());
dlm = new DefaultListModel<String> ();
eventList = new JList();
jPane = new JScrollPane(eventList);
jPane.setPreferredSize(new Dimension(950, 600));
add(jPane);
}
public void addEvent(String event)
{
dlm.addElement(event);
eventList.setModel(dlm);
jPane.revalidate();
jPane.repaint();
}
}
In main()
from Server
class:
//some code
eventMonitor = new EventMonitor();
eventMonitor.setBounds(250, 250, 1000, 650);
eventMonitor.setVisible(true);
//some other code
eventMonitor.addEvent("Server is waiting for new connections..."); // this is shown in the list
while(true)
{
ClientHandler clientHandler = new ClientHandler(listener.accept());// listener is ServerSocket
clientList.add(clientHandler);
clientHandler.start();
}
This is what makes the list go empty: inClientHandler
constructor:
public ClientHandler(Socket socket){
//some code
Server.addEvent("The client is: " + user.GetName() + ", with the ip:" + user.GetIPv4() + ", and using the port: " + user.GetPORT());
//some more code
} // where Server.addEvent(String event) just calls eventMonitor.addEvent(event)
After this, 'run
' from 'ClientHandler'
listens for messages and they are posted via Server.addEvent()
, and it works without a problem, but when another client connects it goes empty again. The first event shown after the one in ClientHandler
constructor makes the list whole (showing the event that made it empty too)
Upvotes: 1
Views: 104
Reputation: 1500903
It looks like you're blocking the UI thread in the loop - when you call accept()
, that's going to wait for a new connection, which means the UI thread can't repaint the UI. You should do that in a separate thread.
All UI interactions should be performed in the UI thread though, e.g. using SwingUtilities.invokeLater
.
Upvotes: 2