kknaguib
kknaguib

Reputation: 749

Thread updating GUI on dispatcher thread causes exception

I have 2 threads, one is a thread that runs the "server" for my app, and the other is the event dispatcher for the GUI as shown:

    public static void main(String[] args) 
    {
    //Connections
    Runnable r2 = new Runnable() {
        @Override
        public void run() 
        {
            App.connectToServer();
        }
    };


    //Launch main window
    SwingUtilities.invokeLater(new Runnable() {
        public void run() 
        {
            //Installs theme
            WebLookAndFeel.install();

            //Launches main window
            BootWindow myMainWindow = new BootWindow();
        }
    });

    Thread thr2 = new Thread(r2);
    thr2.start();
}

//Get instance
public static App getInstance()
{
    if ( instance == null )
    {
        // Creating window instance
        instance = new App();
    }
    return instance;
}

//Server connections
private static void connectToServer()
{
    System.out.println("Connecting to the eTrade Manager Server..");
    etmServer server = new etmServer();
    server.connectEtmServer();

}

In the app's server thread there's a method that listens to new messages that come from a server, this method then calls the updateStatus method in a class that's in the GUI's thread and tries to update a panel's background color:

Method that's listening:

@Override
public void ProcessSystemStatus(SystemStatusUpdateWrapper systemUpdate) 
{
    System.out.println("----System Update----");
    System.out.println("Connection ID: " + systemUpdate.getConnectionId());
    System.out.println("System Status: " + systemUpdate.getSystemStatus());
    System.out.println("Risk State: " + systemUpdate.getRiskState());
    System.out.println("---------End---------");

    Summary smryWindow = new Summary();
    smryWindow.updateStatus("Qtime", systemUpdate.getSystemStatus());
}

update method in the GUI thread

public void updateStatus(String panelName, String status)
{
    if(panelName == "Qtime")
    {
        if(status == "ENABLED")
        {
            qtimeStatusPanel.setBackground(Color.GREEN);

            try
            {
                qtimeStatusPanel.validate();
                qtimeStatusPanel.repaint();
            }
            catch (Exception ex)
            {
                System.err.println(ex.getMessage());
            }
        }
        else
        {
            qtimeStatusPanel.setBackground(Color.RED);
        }

    }
}

When the updateStatus gets called it throws an exception:

java.util.ConcurrentModificationException
at java.util.WeakHashMap$HashIterator.nextEntry(WeakHashMap.java:762)
at java.util.WeakHashMap$EntryIterator.next(WeakHashMap.java:801)
at java.util.WeakHashMap$EntryIterator.next(WeakHashMap.java:799)
at com.alee.managers.style.StyleManager.applySkin(StyleManager.java:300)

I'm not sure how to handle this, any advice?

Upvotes: 0

Views: 182

Answers (1)

trashgod
trashgod

Reputation: 205865

The WeakHashMap API specifies that "if the map is structurally modified at any time after the iterator is created, in any way except through the iterator's own remove() method, the iterator will throw a ConcurrentModificationException." Verify that you are using the iterator, as shown here.

Your program may also be incorrectly synchronized. You can update the GUI on the event dispatch thread using EventQueue.invokeLater(), as shown here.

Upvotes: 1

Related Questions