文本在我的多客户端聊天GUI应用程序中不可见?

时间:2017-08-22 12:03:55

标签: java eclipse multithreading user-interface client-server

编辑我已经实现了一个多客户端聊天服务器,最终我将转换为紧急响应'服务器客户端'的ad hoc网络。目前,我的程序已启动并运行,但在聊天窗口中,我在文本框中输入的内容未出现在eventLog(客户端或服务器)中。我不知道造成这个错误的原因是什么?

我该如何解决这个问题?

以下是代码的一部分:

public class ServerGUI extends JFrame implements ActionListener, WindowListener{

    private static final long serialVersionUID =1L;
    // the stop and start buttons
    private JButton stopStart;
    // JTextArea for the communication interface
    private JTextArea commWin, eventLog;
    // the port number
    private JTextField tport;
    // My server
    private VServer serv;

    // server constructor
//
//
//
//      
        commWin = new JTextArea(120,120);
        commWin.setEditable(false);
        appendComm("VANET Communication Window.\n");
        middle.add(new JScrollPane(commWin));

        eventLog = new JTextArea(120,120);
        eventLog.setEditable(false);
        appendEvent("Events log.\n");
        middle.add(new JScrollPane(eventLog));

        add(middle);
//
//
//
    }

    // append message to the two JTextArea
    void appendComm(String str){
        commWin.append(str);
        commWin.setCaretPosition(commWin.getText().length() -1);
    }

    void appendEvent(String str){
        eventLog.append(str);
        eventLog.setCaretPosition(commWin.getText().length() -1);
    }

    // start or stop when clicked
    public void actionPerformed(ActionEvent e){
        if(serv !=null){
            serv.stop();
            serv = null;
            tport.setEditable(true);
            stopStart.setText("Start");
            return;
        }

        int port;
        try{
            port = Integer.parseInt(tport.getText().trim());
        } catch(Exception ex) {
            appendEvent("Invalid port number");
            return;
        }

        // create a new Server
        serv = new VServer(port, this);
        // and start it as a thread
        new ServerRunning().start();
        stopStart.setText("Stop");
        tport.setEditable(false);
    }

    // entry point to start the server
    public static void main(String[] arg){
        // start server at default port
        new ServerGUI(1234);
    }

    // in case X is clicked, the application closes
    // Connection needs to be closed as well to free the port
    public void windowClosing(WindowEvent e){
        if(serv != null){
            try{
                serv.stop();
            } catch(Exception ec) {}
            serv = null;
        }

        // dispose the frame
        dispose();
        System.exit(0);
    }

    // Ignore the other WindowListener methods

    // a thread to run the server
    class ServerRunning extends Thread {
        public void run(){
            serv.start();
            // in case server fails
            stopStart.setText("Start");
            tport.setEditable(true);
            appendEvent("Server crashed\n");
            serv = null;
        }
    }
}

ClientGUI.java 的某些部分:

//
//

public class ClientGUI extends JFrame implements ActionListener {

    private static final long serialVersionUID =1L;
    private JLabel label;
    private JTextField tfield;
    private JTextField tfieldserv, tport;
    private JButton signin, signoff, ActiveNodes;
    private JTextArea tarea;
    private boolean connected;
    private VClient client;
    private int defaultport;
    private String defaulthost;

    // Constructor receiving a socket number
    ClientGUI(String host, int port){
//
//
        // The upper panel
        JPanel upperPanel = new JPanel(new GridLayout(3,1));
        // the server name and port number
        JPanel serverPort = new JPanel(new GridLayout(1,5, 1,3));
        // the two JTextField with default value for server address and port number
        tfieldserv = new JTextField(host);
        tport = new JTextField("" + port);
        tport.setHorizontalAlignment(SwingConstants.RIGHT);

        serverPort.add(new JLabel("Server Address: "));
        serverPort.add(tfieldserv);
        serverPort.add(new JLabel("Port Number: "));
        serverPort.add(tport);
        serverPort.add(new JLabel(""));

        // adds the server and port fields to GUI
        upperPanel.add(serverPort);

        // the Label and TextField
        label = new JLabel("Enter your username below", SwingConstants.CENTER);
        upperPanel.add(label);
        tfield = new JTextField("Anonymous");
        tfield.setBackground(Color.WHITE);
        upperPanel.add(tfield);
        add(upperPanel, BorderLayout.NORTH);

        // the Central Panel
        tarea = new JTextArea("VANET Disaster Management\n", 120, 120);
        JPanel middlePanel = new JPanel(new GridLayout(2,2));
        middlePanel.add(new JScrollPane(tarea));
        tarea.setEditable(false);
        add(middlePanel, BorderLayout.CENTER);

        // the three Buttons
        signin = new JButton("Sign In");
        signin.addActionListener(this);
        signoff = new JButton("Sign Off");
        signoff.addActionListener(this);
        signoff.setEnabled(false);          // You have to sign in before being able to sign off
        ActiveNodes = new JButton("Active Clients");
        ActiveNodes.addActionListener(this);
        ActiveNodes.setEnabled(false);      // You have to sign in before being able to see the Active Client list

        // the Lower Panel
        JPanel lowerPanel = new JPanel();
        lowerPanel.add(signin);
        lowerPanel.add(signoff);
        lowerPanel.add(ActiveNodes);
        add(lowerPanel, BorderLayout.SOUTH);

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setSize(600,600);
        setVisible(true);
        tfield.requestFocus();
    }

    // to append text in the text area
    void append(String str){
        tarea.append(str);
        tarea.setCaretPosition(tarea.getText().length() -1);
    }

    // called by GUI if the connection fails
    void connectionFailed(){
        signin.setEnabled(true);
        signoff.setEnabled(false);
        ActiveNodes.setEnabled(false);
        label.setText("Enter your username below");
        tfield.setText("Anonymous");

        // reset port number and host name
        tport.setText("" +defaultport);
        tfieldserv.setText(defaulthost);

        // let the client modify them
        tfieldserv.setEditable(false);
        tport.setEditable(false);

        // don't react to a carriage return after the username
        tfield.removeActionListener(this);
        connected = false;
    }

    // Button or JTextField clicked
    public void actionPerformed(ActionEvent e){
        Object obj = e.getSource();
        if(obj == signoff) {
            client.sendMsg(new CommMessage(CommMessage.Signoff, ""));
            return;
        }
        if(obj == ActiveNodes) {
            client.sendMsg(new CommMessage(CommMessage.ActiveNodes, ""));
            return;
        }

        if(connected){
            client.sendMsg(new CommMessage(CommMessage.Message, ""));
            tfield.setText("");
            return;
        }

        if(obj == signin) {
//
//
//
//
            }

            // create a new client with GUI
            client = new VClient(serv, port, username, this);
            if(!client.start())
                return;
            tfield.setText("");
            label.setText("Enter your message below");
            connected = true;

            // disable sign in Button
            signin.setEnabled(false);
            // enable the two buttons
            signoff.setEnabled(true);
            ActiveNodes.setEnabled(true);
            // disable server and port JTextField
            tfieldserv.setEditable(false);
            tport.setEditable(false);
            // when the client enter a message
            tfield.addActionListener(this);
        }
    }

    // to start the whole thing
    public static void main(String[] args) {
        new ClientGUI("localhost", 1234);
    }
}

如果需要其他文件来了解问题,请告诉我们! 我有的文件:

CommMessage.java
VServer.java
VClient.java
ServerGUI.java
ClientGUI.java

其他问题: 到目前为止,它只是一个聊天服务器,我用它作为起点(因为我是Java编程的新手)但我实际上想在这里构建一个具有中央服务器(完成大部分工作)和多个客户端的整个应用程序与它进行双向沟通。为此,我还需要合并 AUTHENTICATION 。我的想法是:远程客户端将发送连接请求,服务器打开套接字,然后客户端发送包含其名称,IP和端口号的第一个数据包。服务器应将其与预先存储的所有已注册客户端列表进行匹配,如果是其中之一,则允许通信向前移动。否则终止连接,请建议我如何在我的代码中实现它。

P.S。'V'代表VANET(Vehicular Ad Hoc NETwork - 我的项目主题)

1 个答案:

答案 0 :(得分:1)

我会回答主要问题,你的代码中有一个拼写错误

void appendEvent(String str){
    eventLog.append(str);
    eventLog.setCaretPosition(commWin.getText().length() -1);
                             // ^^^^ TYPO
}

应该是

void appendEvent(String str){
    eventLog.append(str);
    eventLog.setCaretPosition(eventLog.getText().length() -1);
}