The essential problem here is how do you have the visible GUI instance communicate with the socket client? One way to do this would be to pass an instance of the GUI into the web socket client via its constructor. Then, with this GUI instance, you could pass data from the client into the GUI, and visa-versa.
Say you had a GUI that looked like so:
public class MyJFrame extends javax.swing.JFrame {
// ... code redacted ...
public void fromServer(final String message) {
// note that fromServer will of necessity be called *off* of the Swing event thread, the EDT
// and so you will want to take steps to make sure that it is only used *on* this thread:
EventQueue.invokeLater(new () -> {
// use message from the GUI here
});
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(() -> {
public void run() {
MyJFrame myJFrame = new MyJFrame();
ClientManager clientManager = ClientManager.createClient();
URI uri = null;
try {
uri = new URI("ws://localhost:8080/java/demoApp");
// create our WebSocketClient, passing in the GUI
WebSocketClient webSocketClient = new WebSocketClient(myJFrame);
// and then initiate the session using the above client
// This uses an overload of the connectToServer method that takes an object
session = clientManager.connectToServer(webSocketClient, uri);
myJFrame.setVisible(true); // start the GUI
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (DeploymentException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
Your web socket client could look something like so:
@ClientEndpoint
public class WebSocketClient {
private MyJFrame myJFrame;
public WebSocketClient(MyJFrame myJFrame) {
this.myJFrame = myJFrame;
}
@OnMessage
public void onMessage (String message, Session session) {
System.out.println("[SERVER RESPONSE]: " + message);
// MyJFrame.setButtonGrid(message); // don't call a static method but rather an instance method
myJFrame.fromServer(message);
}
}
Note:
setButtonGrid(...)
and that I call here, fromServer(...)
, to be a static method. It should instead be an instance method so that it can interact with your GUI instance.EventQueue.invokeLater(someRunnable)
but if I were doing this myself, I'd probably use a SwingWorker, passing the data in using the worker's publish/process method pair.