如何使用另一个线程的服务器更新JavaSwingGUI?
我有一个JavaSwing应用程序,它启动了一个新线程,每次输入客户端试图建立连接时,它都会使用一个执行器池打开一个套接字服务器 应用程序需要两个按钮,一个用于启动,另一个用于停止服务器。我想要的是显示服务器状态,并禁用相反的按钮,直到其状态改变 这是我现在拥有的,但我不知道当线程停止时如何与EDT通信。我能做的就是检查如何使用另一个线程的服务器更新JavaSwingGUI?,java,swing,sockets,thread-synchronization,Java,Swing,Sockets,Thread Synchronization,我有一个JavaSwing应用程序,它启动了一个新线程,每次输入客户端试图建立连接时,它都会使用一个执行器池打开一个套接字服务器 应用程序需要两个按钮,一个用于启动,另一个用于停止服务器。我想要的是显示服务器状态,并禁用相反的按钮,直到其状态改变 这是我现在拥有的,但我不知道当线程停止时如何与EDT通信。我能做的就是检查isRunning()方法 用一个SwingWorker会更好吗 public class ServerManager implements Runnable { pr
isRunning()
方法
用一个SwingWorker会更好吗
public class ServerManager implements Runnable {
private Executor mExecutor = Executors.newSingleThreadExecutor();
private ServerSocket mServerSocket = null;
private int mDefaultPort = 43012;
private volatile boolean isRunning = false;
public ServerManager (int port){
mDefaultPort = port;
}
@Override
public void run() {
try {
mServerSocket = new ServerSocket(mDefaultPort);
isRunning = true;
while (isRunning){
mExecutor.execute(new IncomingClientThread(mServerSocket.accept()));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if(mServerSocket != null){
stop();
System.out.println("Server closed");
}
}
}
public void stop(){
try {
mServerSocket.close();
isRunning = false;
} catch (IOException e) {
throw new RuntimeException("Error closing server", e);
}
}
public synchronized boolean isRunning() {
return isRunning;
}
public int getServerPort (){
return mDefaultPort;
}
}
这就是我在GUI线程中所做的:我只使用一个按钮,每次按下它时都会更改它的文本,但是如果服务器由于某种原因断开连接,按钮将保持不变
connectButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
if(mServer.isStopped()){
new Thread (mServer).start();
connectButton.setText("Desconectar");
infoLabel.setText("Servidor online en IP: " + NetworkUtils.getLocalIpAddress()
+ " puerto: " + mServer.getServerPort());
System.out.println(mServer.getIpAddress());
}else{
mServer.stop();
connectButton.setText("Conectar");
infoLabel.setText("Offline");
}
}
});
任何帮助都会来的!
谢谢。一个可能的解决方案是为它提供SwingWorker的部分功能——为它提供一个SwingPropertyChangeSupport对象,并允许您的GUI侦听和响应状态更改 e、 g
关键是永远不要在setter方法之外更改isRunning属性。因此,我所做的是@Hovercraft Full Eels推荐的: 在线程类中:
public class ServerManager implements Runnable {
...
public static final String IS_RUNNING = "IS_RUNNING";
private SwingPropertyChangeSupport pChange = new SwingPropertyChangeSupport(this);
public void setIsRunning (boolean isRunning){
boolean newValue = isRunning;
boolean oldValue = this.isRunning;
this.isRunning = isRunning;
pChange.firePropertyChange(IS_RUNNING, oldValue, newValue);
}
public void addPropertyChangeListener (PropertyChangeListener listener){
pChange.addPropertyChangeListener(IS_RUNNING, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener){
pChange.removePropertyChangeListener(IS_RUNNING, listener);
}
...
}
在GUI类中:
public class StatusPane extends JPanel{
private ServerManager mServer;
public StatusPane() {
...
mServer = new ServerManager();
mServer.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(evt.getPropertyName() + " cambia su valor de "
+ evt.getOldValue() + " a " + evt.getNewValue());
}
});
...
}
}
哇,我错了,我在更改部分代码,但没有注意到。谢谢你的回答,我的朋友。我对事件侦听器有点陌生,所以我必须深入研究它,但现在我明白了。ey@Hovercraft,我已经将所有侦听器内容移动到一个单例枚举中,以跟踪服务器状态和我将添加的其他侦听器,只是为了将其与网络逻辑分离。你觉得可以吗?
public class StatusPane extends JPanel{
private ServerManager mServer;
public StatusPane() {
...
mServer = new ServerManager();
mServer.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
System.out.println(evt.getPropertyName() + " cambia su valor de "
+ evt.getOldValue() + " a " + evt.getNewValue());
}
});
...
}
}