问题
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