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



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

如果我启动服务器并直接连接客户端(即不从 Login.java 启动它),客户端和服务器都可以完美运行并且可以一起交谈。

奇怪的是,当我从登录启动 Client.java 时.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
            }
        }
    }
}

客户端.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("nn" + 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("nnClosing 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'
                    }
                }
        );
    }
}

替换这个

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();

检查这个问题,它将帮助您从主 JFrame 显示登录 JFrame(您需要创建该帧)如何使 JFrame 按钮在 Netbeans 中打开另一个 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(); 
}

最新更新