How to structure publish() and process() in a SwingWorker to update more than one Swing component on the EDT?

佐手、 提交于 2020-01-06 14:59:11

问题


I have a ServerSocketChannel connection process in a SwingWorker. In the Swing application itself, two JLabels should update with (1) a String (connection status) and (2) an int (# of clients connected). Below is a screenshot of the application before "Detect Clients" JButton runs the connection process. However, I am not sure how to publish() and process() so as to update more than one Swing component on the EDT. Does anyone have guidance on how to achieve this?

Because List<V> is the parameter of process(), I tried <Object> as <V>. However, this seems to run into issues of conversion from Strings/ints to Objects, and then vice versa.

The below demo code illustrates several points where updates should be published:

protected Void doInBackground() {
    try {
       // Omitted: obtain selector
       ServerSocketChannel ssc = ServerSocketChannel.open() // could fail, may need
       // to publish status
       ssc.socket().bind(serverAddress); // could fail, may need to publish status
       ssc.configureBlocking(false); // could fail, may need to publish status
       // Omitted: register ssc
       while (true) {
           int count = sel.select(1000); // may need to publish for # of clients
           // Omitted: rest of processing     
       }
    } catch (IOException e) {
        //handle error
    } 
}

回答1:


Ah, now i understand your problem. you are trying to publish 2 different bits of information. note that the List passed into the process() method could contain the results of multiple publish() calls, so passing different types of values will get confused in your process() method. instead, you should create a simple object to encapsulate all of the state you wish to pass, and always publish instances of that class (which will also solve all of your casting issues). e.g.:

public class ChannelStatus {
  public final boolean active;
  public final int numClients;
}

Then, you would always publish a ChannelStatus instance with the current number of clients and "active" status.




回答2:


You could use String as a result type. Say, for an integer (num of clients) do publish(String.valueOf(integer)), And then in your process() method try something like

try {
 int numClients = Integer.parseInt(passedString);
 //all well, it's the client number
} catch(NumberFormatException ex) {
 //not a number, must be a connection status
}

Or simply wrap the two information in a separate class with setNumClients, setConnStatus and appropriate getters, populate it as you progress, and publish the object of that class.

Do tell me if I haven't understood you properly because I have a hunch you might want PropertyChangeListeners involved here.



来源:https://stackoverflow.com/questions/12439005/how-to-structure-publish-and-process-in-a-swingworker-to-update-more-than-on

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!