selico 2021-09-19 09:52 采纳率: 87.5%
浏览 25
已结题

多线程通信中GUI响应事件问题

本程序实现了多客户端通过服务器进行通讯的目的,但是在将消息输入从控制台(使用scanner输入)转为从JtextField输入时出现问题。

/*服务端代码*/

import java.io.IOException;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Server:
 */
public class Server {
    public static List<String> l = new ArrayList();//store who have connected
    public static void main(String[] args) {
        //store Client thread and protect them
        Vector<UserThread> vector = new Vector <>();
        //use thread poll to manage the thread
        ExecutorService es = Executors.newFixedThreadPool(5);
       
        try {
            ServerSocket server = new ServerSocket(8888);
            System.out.println("Server is Running,Wating for Client.....");
            while(true){
                //accept Client
                Socket socket = server.accept();
                //create a new thread for every Client task.
                UserThread user = new UserThread(socket,vector);
                es.execute(user); 
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

/**
 * Client ManageThread:
 */
class UserThread implements Runnable{
    
    private String name; //Client name,unique
    private Socket socket;
    private Vector<UserThread> vector;   //Set of Client
    private ObjectInputStream oIn;    
    private ObjectOutputStream oOut;  
    private boolean flag = true;  //tag
    
    public UserThread(Socket socket, Vector<UserThread> vector) {
        this.socket = socket;
        this.vector = vector;
        vector.add(this);    //add nowtime's thread to vector
    }

    @Override
    public void run() {
        try {
            //Create inputStream and outputStream
            System.out.println("Client:" + socket.getInetAddress().getHostAddress() + " is Connected!");
            oIn = new ObjectInputStream(socket.getInputStream());
            oOut = new ObjectOutputStream((socket.getOutputStream()));
            //2、Loop to read
            while(flag){
                //Read object
                Message message = (Message)oIn.readObject();
                //Get Type
                int type = message.getType();
                //judge
                switch (type){
                    //if it is information
                    case MessageType.TYPE_SEND:
                        String to = message.getTo();
                        UserThread ut;
                        //To Find the Client you want to send message
                        int size = vector.size();
                        for (int i = 0; i < size; i++) {
                            ut = vector.get(i);
                            //if find and not yourself
                            if(to.equals(ut.name) && ut != this){
                                ut.oOut.writeObject(message); 
                            }
                        }
                        break;
                    //if it's login
                    case MessageType.TYPE_LOGIN:                       
                        name = message.getFrom();//Get the Client name
                        Server.l.add(name);
                        String[] s = Server.l.toArray(new String[Server.l.size()]);//getAllClientName
                        message.setInfo("Welcom!");//show the successful message
                        message.setClientName(s);
                        oOut.writeObject(message);   
                        break;
                }

            }



        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }

    }
}

/*message类*/
import java.io.Serializable;

/**
 * Message
 */
public class Message implements Serializable {

    private static final long serialVersionUID = 1L;  
    private String from; 
    private String to;   
    private int type; 
    private String info;
    private String[] clientName;

    public Message() {
    }

    public Message(String from, String to, int type, String info) {
        this.from = from;
        this.to = to;
        this.type = type;
        this.info = info;
    }
    public Message(String from, String to, int type, String info,String[] clientName) {
        this.from = from;
        this.to = to;
        this.type = type;
        this.info = info;
        this.clientName=clientName;
    }

    public String getFrom() {
        return from;
    }

    public void setFrom(String from) {
        this.from = from;
    }

    public String getTo() {
        return to;
    }

    public void setTo(String to) {
        this.to = to;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
    public void setClientName(String [] clientName) {
        this.clientName=clientName;
    }
    public String[] getClientName(String [] clientName) {
        return clientName;
    }

}

public class MessageType {

    public static final int TYPE_LOGIN = 0x1; //to login
    public static final int TYPE_SEND = 0x2;  //to send Info
}


下面是出现问题的客户端代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Client:
 */
public class Client extends JFrame {
    JTextField tf = new JTextField();//input
    JTextArea ta1 = new JTextArea();//show info
    JTextArea ta2 = new JTextArea();//show Client
    Container cc;
    JPanel jp1 = new JPanel(new GridLayout(1, 2));
    JScrollPane jScrollPane;
    Socket socket;
    ObjectOutputStream oOut;
    ObjectInputStream oIn;
    Message message;
    Scanner input;
    String name;
    String[] ss= new String[2];
    public Client() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        cc = this.getContentPane();
        setTitle("Client");
        setBounds(450, 100, 1000, 800);
        ta1.setBorder(BorderFactory.createEtchedBorder());
        ta2.setBorder(BorderFactory.createEtchedBorder());
        jp1.setBorder(BorderFactory.createEtchedBorder());
        jp1.add(ta1);
        jp1.add(ta2);
        jScrollPane = new JScrollPane(jp1);
        cc.add(jScrollPane, BorderLayout.CENTER);
        cc.add(tf, BorderLayout.SOUTH);
        setVisible(true);
        tf.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String s = tf.getText();
                ss =s.split("\\s+");
                //Create Message
                message = new Message();
                //Send to who?
                message.setTo(ss[0]);
                //From me
                message.setFrom(name);
                //Type
                message.setType(MessageType.TYPE_SEND);
                //Information
                message.setInfo(ss[1]);
                /*----The object is finished----*/
                //send it to Server
                try {
                    oOut.writeObject(message);
                } catch (IOException p) {
                    p.printStackTrace();
                }
                ta1.append(tf.getText()+"\n");
                ta1.setSelectionEnd(ta1.getText().length());
                ta1.append("please input To: and  Info:\n");
                tf.setText("");
            }
        });

    }

    public void connect() {
        ExecutorService es = Executors.newSingleThreadExecutor();
        input = new Scanner(System.in);
        try {
            socket = new Socket("localhost", 8888);
        } catch (IOException e) {
            e.printStackTrace();
        }
        ta1.append("Server is Successfully Connected!\n");
       
        try {
            oOut = new ObjectOutputStream(socket.getOutputStream());
            oIn = new ObjectInputStream(socket.getInputStream());
            //1.Client login
            //Send the login information to server
            ta1.append("Please input name:\n");
            name = input.nextLine();
            //only give the name and type
            message = new Message(name, null, MessageType.TYPE_LOGIN, null);
            //send to server
            oOut.writeObject(message);
            //server return message to welcome
            message = (Message) oIn.readObject();
            //print the message in client window
            ta1.append(message.getInfo() + message.getFrom()+"\n");
            //
            for(int i=0;i<message.getClientName().length;i++){
                ta2.append("Client:"+message.getClientName()[i]+"\n");
            }
            ta2.append("The Clients above is connected!");
            es.execute(new readInfoThread(oIn));
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

        public void getServer() {
//        //3.Send message
//        //use main thread
//        boolean flag = true;
//        //Loop
//        while (flag) {
//            //Create object to send
//            message = new Message();
//            //to ?
//            ta1.append("To:\n");
//            message.setTo(input.nextLine());
//            //from ?
//            message.setFrom(this.name);
//            //type of message
//            message.setType(MessageType.TYPE_SEND);
//            //Info
//            ta1.append("Info:\n");
//            message.setInfo(input.nextLine());
//            /*----a message is created----*/
//            //send it to Server
//            try {
//                oOut.writeObject(message);
//            } catch (IOException e) {
//                e.printStackTrace();
//            }
//        }
       }


    public static void main(String[] args) {

        Client client = new Client();
        client.connect();
        //client.getServer();


    }

    /**
     * ReadInfo from other Client
     */
    class readInfoThread implements Runnable {
        private ObjectInputStream oIn;
        private boolean flag = true; //tag

        public readInfoThread(ObjectInputStream oIn) {
            this.oIn = oIn;
        }

        public void setFlag(boolean flag) {
            this.flag = flag;
        }

        @Override
        public void run() {

            try {
                //Loop to read info
                while (flag) {

                    //Read
                    Message message = (Message) oIn.readObject();
                    //Show Info in window
                    ta1.append("[" + message.getFrom() + "]send message to me:\n"+ message.getInfo()+"\n");
                }
                //close all
                if (oIn != null) {
                    oIn.close();
                }

            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }


        }
    }
}

也就是说将上面客户端获取输入信息(getServer方法)的方式转变为Text输入(tf的ActionListener)后,
另一个客户端无法接收到消息(或者可能是消息根本没有被message获取)。

  • 写回答

2条回答 默认 最新

  • 阿巴阿巴0_0 2021-09-19 12:16
    关注

    你的窗体布局出了问题,你的布局本来是这个样子的。

    img


    真正的tf在隐藏在下面

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 9月28日
  • 已采纳回答 9月20日
  • 创建了问题 9月19日

悬赏问题

  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)