使用Swing GUI的简单客户端-服务器程序

使用Swing GUI的简单客户端-服务器程序,第1张

使用Swing GUI的简单客户端-服务器程序

您的代码当前存在的问题:

  • 你正在创建一个Swing GUI的并运行关闭 Swing事件分派线程或EDT的。GUI应该在事件线程 启动 以便确保所有Swing代码都可以在单个线程上运行。
  • 您有一个长时间运行的while循环,它正在进行Swing突变调用,从而更新了JButton的状态。如果此代码在Swing事件线程上运行,它将阻止/冻结GUI。应该在不是EDT的后台线程中显式调用此块,并且应按照“ Swing:并发”教程中的内容,将所有Swing调用排队到事件线程中。
  • 您在不同的线程中使用了一个非易失性布尔值,可能会导致变量在应更改时未被更改
  • 您似乎立即关闭了流,从而阻止了关注点之间的充分沟通。

正在研究更干净的示例…

例如:

import java.awt.Dimension;import java.awt.event.ActionEvent;import java.io.IOException;import java.io.PrintStream;import java.net.ServerSocket;import java.net.Socket;import java.util.Scanner;import javax.swing.*;public class SimpleServerClient {    private static final int PORT = 9001;    public static void main(String[] args) {        SwingUtilities.invokeLater(() -> { try {     SimpleServer server = new SimpleServer(PORT, "Server", false);     SimpleClient client = new SimpleClient(PORT, "Client", true);     server.createGui();     client.createGui(); } catch (IOException e) {     e.printStackTrace(); }        });    }}interface SimpleGui {    void sendLine(String nextLine);}// background thread handles listening to the Scanner // which scans a Socket's InputStreamclass MyWorker extends SwingWorker<Void, Void> {    public static final String LINE = "line";    private Scanner inputScanner;    private SimpleGui gui;    private String line = "";    public MyWorker(Scanner inputScanner, SimpleGui gui) {        this.inputScanner = inputScanner;        this.gui = gui;    }    @Override    protected Void doInBackground() throws Exception {        while (inputScanner.hasNext()) { // get line from Scanner      // use the setter method in case we want to use a PropertyChangeListener later setLine(inputScanner.nextLine()); // send line to the GUI gui.sendLine(getLine());        }        return null;    }    public String getLine() {        return line;    }    // again rigged up to allow use of PropertyChangeListeners    public void setLine(String line) {        this.line = line;        firePropertyChange(LINE, null, line);    }}// pre that both the client and server GUI classes shareabstract class DefaultGui implements SimpleGui {    // this guy ***must**** be volitile!    private volatile boolean myTurn;    protected Scanner inputScanner;    protected PrintStream out;    protected JButton button = new JButton("Blank");    protected Socket socket;    protected String name;    protected int port;    public DefaultGui(int port, String name, boolean myTurn) {        this.port = port;        this.name = name;        this.myTurn = myTurn;    }    @Override    public void sendLine(String nextLine) {        button.setText(nextLine);        myTurn = true;    }    public void createGui() {        button.addActionListener(e -> actionPerformed(e));        JPanel panel = new JPanel();        panel.setPreferredSize(new Dimension(300, 300));        panel.add(button);        Jframe frame = new Jframe(getName());        frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE);        frame.add(panel);        frame.pack();        frame.setLocationByPlatform(true);        frame.setVisible(true);    }    protected void actionPerformed(ActionEvent e) {        if (!myTurn) { return;        }        out.println(getName());        button.setText(getName());        myTurn = false;    }    public String getName() {        return name;    }}class SimpleServer extends DefaultGui {    private ServerSocket serverSocket;    public SimpleServer(int port, String name, boolean myTurn) throws IOException {        super(port, name, myTurn);        serverSocket = new ServerSocket(port);        new Thread(() -> { try {     // accept() blocks the current thread, so must be called on a background thread     socket = serverSocket.accept();     inputScanner = new Scanner(socket.getInputStream());     out = new PrintStream(socket.getOutputStream(), true);     new MyWorker(inputScanner, this).execute(); } catch (IOException e) {     e.printStackTrace(); }        }).start();    }    }class SimpleClient extends DefaultGui {    public SimpleClient(int port, String name, boolean myTurn) throws IOException {        super(port, name, myTurn);        socket = new Socket("localhost", port);        inputScanner = new Scanner(socket.getInputStream());        out = new PrintStream(socket.getOutputStream());        new MyWorker(inputScanner, this).execute();    }    }


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5033916.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-15
下一篇 2022-11-15

发表评论

登录后才能评论

评论列表(0条)

保存