如何从另一个线程使用服务器更新java swing gui?

2024-01-06

我有一个 Java Swing 应用程序,每当传入的客户端尝试建立连接时,它都会启动一个新线程,该线程使用执行程序池来打开套接字服务器。

该应用程序需要两个按钮,一个用于启动服务器,另一个用于停止服务器。我想要的是显示服务器状态,并禁用相反的按钮,直到其状态发生变化。

这就是我现在所拥有的,但我不知道当线程停止时如何与 EDT 通信。我能做的就是检查isRunning() method.

使用 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.,

public class ServerManager implements Runnable {
  public static final String IS_RUNNING = "is running"; // for the Event's name
  private SwingPropertyChangeSupport propChngSupport = new SwingPropertyChangeSupport(this);
  private volatile boolean isRunning  = false;
  // other variables

  // addPropertyChangeListener(...) {...} goes here
  // removePropertyChangeListener(...)  {...} goes here

  public void setIsRunning(boolean isRunning) {
    boolean newValue = isRunning;
    boolean oldValue = this.isRunning;
    this.isRunning = isRunning;
    propChngSupport.firePropertyChange(IS_RUNNING, oldValue, newValue);    
  }

  public void run() {
    // ....
  }

  // other methods
}

关键是永远不要在其 setter 方法之外更改 isRunning 属性。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何从另一个线程使用服务器更新java swing gui? 的相关文章

随机推荐