我目前正在编写一个即时通讯应用程序。我从运行正常的基本客户端/服务器设置开始。但是,当我从登录启动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();
}