Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Instant Messenger-从登录表单启动时客户端无法正常运行_Java - Fatal编程技术网

Java Instant Messenger-从登录表单启动时客户端无法正常运行

Java Instant Messenger-从登录表单启动时客户端无法正常运行,java,Java,我目前正在编写一个即时通讯应用程序。我从一个运行正常的基本客户机/服务器设置开始。但是,当我从Login.java启动Client()类时(在第一次运行Server.java之后),JFrame会出现,但完全为空,即对话面板、用户文本输入字段等元素不存在。这很奇怪,因为服务器指示客户端已连接,但我无法在客户端窗体中键入/查看任何内容 如果我启动服务器并直接连接客户机(即不从Login.java启动它),那么客户机和服务器都可以完美地工作,并且可以一起进行对话 奇怪的是,当我在服务器不运行的情况下

我目前正在编写一个即时通讯应用程序。我从一个运行正常的基本客户机/服务器设置开始。但是,当我从Login.java启动
Client()类时(在第一次运行Server.java之后),JFrame会出现,但完全为空,即对话面板、用户文本输入字段等元素不存在。这很奇怪,因为服务器指示客户端已连接,但我无法在客户端窗体中键入/查看任何内容

如果我启动服务器并直接连接客户机(即不从Login.java启动它),那么客户机和服务器都可以完美地工作,并且可以一起进行对话

奇怪的是,当我在服务器不运行的情况下从Login.java启动Client.java时,窗口显示为它应该显示的样子,元素保持不变(但显然无法使用,因为它没有连接到服务器)。此外,当我关闭Server.Java时,Client.Java将恢复为显示所有元素,但在没有服务器连接的情况下仍然无法使用

非常感谢您的帮助。 谢谢

Login.Java:

import java.awt.*;//contains layouts, buttons etc.
import java.awt.event.*; //contains actionListener, mouseListener etc.
import javax.swing.*; //allows GUI elements

public class Login extends JFrame implements ActionListener, KeyListener {
    private JLabel usernameLabel = new JLabel("Username/Email:");
    private JLabel userPasswordLabel = new JLabel("Password:");
    public JTextField usernameField = new JTextField();
    private JPasswordField userPasswordField = new JPasswordField();
    private JLabel status = new JLabel("Status: Not yet logged in.");
    private JButton loginButton = new JButton("Login");
    private JButton registerButton = new JButton("New User");

    public Login() {
        super("Please Enter Your Login Details...");//titlebar
        setVisible(true);
        setSize(400, 250);
        this.setLocationRelativeTo(null); //places frame in center of screen
        this.setResizable(false); //disables resizing of frame
        this.setLayout(null); //allows me to manually define layout of text fields etc.
        ImageIcon icon = new ImageIcon("bin/mm.png");
        JLabel label = new JLabel(icon);
        this.add(usernameLabel);
        this.add(userPasswordLabel);
        this.add(usernameField);
        this.add(userPasswordField);
        this.add(loginButton);
        this.add(registerButton);
        this.add(status);
        this.add(label);
        label.setBounds(0, 0, 400, 70);
        usernameLabel.setBounds(30, 90, 120, 30); //(10, 60, 120, 20);
        userPasswordLabel.setBounds(30, 115, 80, 30);//(10, 85, 80, 20);
        usernameField.setBounds(150, 90, 220, 30);
        userPasswordField.setBounds(150, 115, 220, 30);
        loginButton.setBounds(150, 160, 110, 25);
        registerButton.setBounds(260, 160, 110, 25);
        status.setBounds(30, 190, 280, 30);
        status.setForeground(new Color(50, 0, 255)); //sets text colour to blue
        loginButton.addActionListener(this);
        registerButton.addActionListener(this);
        registerButton.setEnabled(false);
        userPasswordField.addKeyListener(this);
    }

    @Override
    public void keyTyped(KeyEvent e) {
    }

    @Override
    public void keyPressed(KeyEvent e) {
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == loginButton) {
            String userName = usernameField.getText();
            String password = userPasswordField.getText();
            if (userName.equals("mick") && password.equals("mick")) {
                status.setText("Status: Logged in.");
                this.setVisible(false);
                new Client("127.0.0.1").startRunning();
            } else {
                status.setText("Status: Password or username is incorrect.");
                status.setForeground(new Color(255, 0, 0)); //changes text colour to red
            }
        }
    }
}
Client.java:

import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Date; //timestamp functionality

import javax.swing.*;

public class Client extends JFrame { //inherits from JFrame
        //1. Creating instance variables
    private JTextField userText; //where user inputs text
    private JTextArea chatWindow; //where messages are displayed
    private String fullTimeStamp = new java.text.SimpleDateFormat("dd/MM/yyyy HH:mm:ss").format(new Date());
    //fullTimeStamp - MM = months; mm = minutes; HH = 24-hour cloc
    private ObjectOutputStream output; //output from Client to Server
    private ObjectInputStream input; //messages received from Server
    private String message = "";
    private String serverIP;
    private Socket connection;

    //2. Constructor (GUI)
    public Client(String host) { //host=IP address of server
        super("Mick's Instant Messenger [CLIENT]");
        serverIP = host; //placed here to allow access to private String ServerIP
        userText = new JTextField();
        userText.setEditable(false);
        userText.addActionListener(
                new ActionListener() {
                    public void actionPerformed(ActionEvent event) {
                        sendMessage(event.getActionCommand()); //For this to work, must build sendData Method
                        userText.setText(""); //resets userText back to blank, after message has been sent to allow new message(s)
                    }
                }
        );
        add(userText, BorderLayout.SOUTH);
        chatWindow = new JTextArea();
        add(new JScrollPane(chatWindow), BorderLayout.CENTER); //allows you to scroll up and down when text outgrows chatWindow
        chatWindow.setLineWrap(true); //wraps lines when they outgrow the panel width
        chatWindow.setWrapStyleWord(true); //ensures that above line wrap occurs at word end
        setSize(400, 320);
        this.setLocationRelativeTo(null); //places frame in center of screen
        setVisible(true);
    }

    //3. startRunning method
    public void startRunning() {
        try {
            connectToServer(); //unlike Server, no need to wait for connections. This connects to one specific Server.
            setupStreams();
            whileChatting();
        } catch (EOFException eofException) {
            //Display timestamp for disconnection
            showMessage("\n\n" + fullTimeStamp);
            showMessage("\nConnection terminated by CLIENT! ");
        } catch (IOException ioException) {
            ioException.printStackTrace();
        } finally {
            closeCrap();
        }
    }

    //4. Connect to Server
    void connectToServer() throws IOException {
        showMessage(" \n Attempting connection to SERVER... \n");
        connection = new Socket(InetAddress.getByName(serverIP), 6789);//Server IP can be added later
        showMessage(" Connected to: " + connection.getInetAddress().getHostName()); //displays IP Address of Server
    }

    //5. Setup streams to send and receive messages
    private void setupStreams() throws IOException {
        output = new ObjectOutputStream(connection.getOutputStream());
        output.flush();
        input = new ObjectInputStream(connection.getInputStream());
        showMessage("\n Streams are now setup! \n");
    }

    //6. While chatting method
    private void whileChatting() throws IOException {
        //Display timestamp for connection
        showMessage("\n" + fullTimeStamp);
        ableToType(true);
        String timeStamp = new java.text.SimpleDateFormat("HH:mm:ss").format(new Date());//timestamp
        do {
            try {
                message = (String) input.readObject(); //read input, treat as String, store in message variable
                showMessage("\n" + message);
            } catch (ClassNotFoundException classNotfoundException) {
                showMessage("\n I don't know that object type");
            }
            //***broken by timestamp?***    
        } while (!message.equalsIgnoreCase("SERVER " + "[" + timeStamp + "]" + ": " + "END")); //Conversation happens until Server inputs 'End'

    }

    //7. Close the streams and sockets
    private void closeCrap() {
        showMessage("\n\nClosing streams and sockets...");
        ableToType(false);//disable typing feature when closing streams and sockets
        try {
            output.close();
            input.close();
            connection.close();
        } catch (IOException ioException) {
            ioException.printStackTrace(); //show error messages or exceptions
        }
    }

    //8. Send Messages to Server
    private void sendMessage(String message) {
        try {
            String timeStamp = new java.text.SimpleDateFormat("HH:mm:ss").format(new Date());//timestamp
            output.writeObject("CLIENT" + " [" + timeStamp + "]" + ": " + message);
            output.flush();
            showMessage("\nCLIENT" + " [" + timeStamp + "]" + ": " + message);
        } catch (IOException ioexception) {
            chatWindow.append("\n Error: Message not sent!");
        }
    }

    //9.change/update chatWindow
    private void showMessage(final String m) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        chatWindow.setEditable(false); //disallows text editing in chatWindow
                        chatWindow.append(m); //appends text, which was passed in from above
                    }
                }
        );
    }

    //10. Lets user type
    private void ableToType(final boolean tof) {
        SwingUtilities.invokeLater(
                new Runnable() {
                    public void run() {
                        userText.setEditable(tof); //passes in 'true'
                    }
                }
        );
    }
}

检查这个问题,它将帮助您从主JFrame显示登录JFrame(您需要创建该框架)
考虑更改此代码

@Override
public void actionPerformed(ActionEvent e) {
    this.setVisible(false);
    new Client().setVisible(true);

}
为此:

@Override
public void actionPerformed(ActionEvent e) {
    Client charlie = new Client("127.0.0.1"); //Server IP Address would be placed here, where not       
    localhost.charlie.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //ensures process closes when 'X' is clicked      
    charlie.setVisible(true);
    charlie.startRunning(); 
}
替换这个

new Client("127.0.0.1").startRunning();

Thread t1 = new Thread(new Runnable() {
    public void run(){
        Client client = new Client("127.0.0.1");
        client.startRunning();
    }
});  
t1.start();

谢谢你的回复。我已经在Eclipse中构建了一个登录表单(参见代码),但无法实现建议的方法。请参阅编辑的帖子。@user3029329很抱歉遗漏了一件事,客户端构造函数需要一个主机
公共客户端(字符串主机)
,因此当您调用
新客户端()
时,您应该执行
新客户端(“此处主机”)
谢谢。当我输入“new Client().setVisible(true);”时,尽管Client()在同一个包中(请参阅我的源代码),但new Client()仍带有红色下划线。编译器说“构造函数客户端()未定义”。我可以运行表单,但当我单击按钮时,控制台会给出以下错误:线程“AWT-EventQueue-0”java.lang中出现异常。错误:未解决的编译问题:javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2018)中的javax.swing.AbstractButton$Handler.actionPerformed中未定义构造函数客户端()(AbstractButton.java:2341)…很抱歉,我不确定我是否理解您的最后一条评论。根据我所附的代码,我将如何实现您的建议?谢谢。@user3029329您如何将ip地址提供给客户端?再次感谢您的帮助。我尝试了此操作,但再次获得相同的结果,即客户端成功连接到服务器(根据服务器输出),但客户端只是一个灰色的无功能窗口,没有任何选项。奇怪的是,当我直接启动客户端时,这种情况不会发生。谢谢你的建议。我已经尝试过了,但同样的问题仍然存在。你这个天才!它与你的新线程建议配合使用。非常感谢。这个问题整天都在困扰我!!!你能解释为什么它有效吗?Y你在与GUI相同的线程中运行客户端,这就是GUI冻结(等待客户端)的原因。啊哈..我现在完全理解了。非常感谢你教我一些新东西。