0

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?

kknaguib
  • 749
  • 4
  • 12
  • 33
  • It would appear that your `ProcessSystemStatus` method is getting called by some thread other than the EDT, but it's hard to tell without line numbers or a complete set of code. Does `ProcessSystemStatus` ultimately get called during the call to `App.connectToServer()` ? – CodeBlind Oct 08 '14 at 16:27
  • 1
    "in a class that's in the GUI's thread" That doesn't seem to make sense to me. You're in the GUI thread or you're not. It doesn't make any difference what class or even object it is. – Tom Hawtin - tackline Oct 08 '14 at 16:30
  • yes ProcessSystemStatus gets called during App.connectToServer() @BenLawry – kknaguib Oct 08 '14 at 16:34
  • The app server is on a different thread, my ultimate goal is to have the GUI update when that ProcessSystemStatus calls updateStatus and they're both running on different threads @TomHawtin-tackline – kknaguib Oct 08 '14 at 16:36
  • Your code suggests that you already know about `SwingUtilities.invokeLater` so the missing thing is to use it for UI updates. – Holger Oct 08 '14 at 16:38
  • ok how do I do that? @Holger – kknaguib Oct 08 '14 at 16:46
  • 1
    Don't use `"=="` to compare Strings. Use the `equals(...)` method. – camickr Oct 08 '14 at 16:48
  • That’s way too broad. You may study [“Concurrency in Swing”](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/index.html), [`SwingUtilities.invokeLater`](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater(java.lang.Runnable)), and [`SwingWorker`](http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingWorker.html) – Holger Oct 08 '14 at 16:53

1 Answers1

1

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.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045