新用户寻求大学任务的帮助。
该任务是创建一个多线程聊天客户端,可以压缩和加密消息,将它们发送到服务器,然后将相关消息发送给其他人。我已经开始测试代码但是我遇到了问题。请参阅,当GUI首次打开时,它将作为登录屏幕打开,并将其发送到要验证的服务器。接下来应该发生的是登录屏幕应该关闭,并且为同一JFrame内的用户打开聊天GUI。但我遇到的问题是登录屏幕冻结到位,窗口的其余部分变黑,如下所示: JFrame error
然后窗口变得完全没有响应,我必须通过Eclipse的控制台终止线程。这个问题阻止我测试我的其余代码。任何帮助赞赏。 Client类的代码如下。如果需要更多代码,请告诉我。谢谢你尽你所能的帮助!
如果代码对齐不是很好,我也很抱歉。我还在学习!
public class YourChat_Client extends JFrame {
//GUI Components
private JTextField chatField;
private JTextPane broadcastPane;
private Container c;
private JButton logonButton, btnArken, btnBen, btnDarklark, btnFree, btnSend,btnQuit, btnGroup;
private JPanel logonFieldsPanel, logonButtonPanel;
private JLabel usernameLabel, passwordLabel, chatLbl;
private JTextArea outputArea, playerArea, broadcastArea;
private JTextField username;
private JPasswordField password;
private JTextField broadcastField;
private Boolean loggedOn;
private int participantNo;
//Declare Socket
Socket socket;
YourChat_ClientThread thread;
//Data Streams
ObjectOutputStream clientOutputStream;
ObjectInputStream clientInputStream;
public YourChat_Client() {
super("YourChat_Client");
setResizable(false);
addWindowListener
( new WindowAdapter()
{ public void windowClosing(WindowEvent e)
{ System.exit(0);
}
}
);
setTitle("Login");
setVisible(true);
setSize(594,243);
setLocationRelativeTo(null);
// create and add GUI components for login screen (Taken from practical 7)
c = getContentPane();
c.setLayout(new BorderLayout());
// GUI components for the username
logonFieldsPanel = new JPanel();
logonFieldsPanel.setLayout(new GridLayout(2,2,5,5));
usernameLabel = new JLabel("Enter Username: ");
logonFieldsPanel.add(usernameLabel);
username = new JTextField(10);
logonFieldsPanel.add(username);
// GUI components for the password
passwordLabel = new JLabel("Enter Password: ");
logonFieldsPanel.add(passwordLabel);
password = new JPasswordField(10);
logonFieldsPanel.add(password);
c.add(logonFieldsPanel,BorderLayout.CENTER);
// panel for the logon button
logonButtonPanel = new JPanel();
logonButton = new JButton("logon");
logonButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
attemptLogin();
}
});
logonButtonPanel.add(logonButton);
c.add(logonButtonPanel, BorderLayout.SOUTH);
pack();
}
void sendMessage(String message){
try {
String output = "m" + message;
CompressedMessage mess = new CompressedMessage(output);
clientOutputStream.writeInt(participantNo);
clientOutputStream.writeObject(mess);
} catch (IOException e) {
// TODO Auto-generated catch block
System.out.println(e);
}
}
void setUpChat(Boolean loggedOn){
c.remove(logonButtonPanel);
c.remove(logonFieldsPanel);
if(loggedOn){
setResizable(true);
setSize(543,243);
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
gridBagLayout.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
gridBagLayout.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
c.setLayout(gridBagLayout);
chatLbl = new JLabel(new ImageIcon("chat.png"));
GridBagConstraints gbc_chatLbl = new GridBagConstraints();
gbc_chatLbl.gridheight = 2;
gbc_chatLbl.gridwidth = 3;
gbc_chatLbl.insets = new Insets(0, 0, 5, 5);
gbc_chatLbl.gridx = 1;
gbc_chatLbl.gridy = 1;
c.add(chatLbl, gbc_chatLbl);
broadcastPane = new JTextPane();
GridBagConstraints gbc_broadcastPane = new GridBagConstraints();
gbc_broadcastPane.insets = new Insets(0, 0, 5, 5);
gbc_broadcastPane.gridheight = 4;
gbc_broadcastPane.gridwidth = 6;
gbc_broadcastPane.fill = GridBagConstraints.BOTH;
gbc_broadcastPane.gridx = 5;
gbc_broadcastPane.gridy = 2;
c.add(broadcastPane, gbc_broadcastPane);
btnArken = new JButton("Arken");
GridBagConstraints gbc_btnArken = new GridBagConstraints();
gbc_btnArken.fill = GridBagConstraints.BOTH;
gbc_btnArken.insets = new Insets(0, 0, 5, 5);
gbc_btnArken.gridx = 2;
gbc_btnArken.gridy = 4;
c.add(btnArken, gbc_btnArken);
btnBen = new JButton("Ben");
GridBagConstraints gbc_btnBen = new GridBagConstraints();
gbc_btnBen.fill = GridBagConstraints.BOTH;
gbc_btnBen.insets = new Insets(0, 0, 5, 5);
gbc_btnBen.gridx = 2;
gbc_btnBen.gridy = 5;
c.add(btnBen, gbc_btnBen);
btnDarklark = new JButton("Darklark");
GridBagConstraints gbc_btnDarklark = new GridBagConstraints();
gbc_btnDarklark.fill = GridBagConstraints.BOTH;
gbc_btnDarklark.insets = new Insets(0, 0, 5, 5);
gbc_btnDarklark.gridx = 2;
gbc_btnDarklark.gridy = 6;
c.add(btnDarklark, gbc_btnDarklark);
btnFree = new JButton("Free");
GridBagConstraints gbc_btnFree = new GridBagConstraints();
gbc_btnFree.fill = GridBagConstraints.BOTH;
gbc_btnFree.insets = new Insets(0, 0, 5, 5);
gbc_btnFree.gridx = 2;
gbc_btnFree.gridy = 7;
c.add(btnFree, gbc_btnFree);
chatField = new JTextField();
GridBagConstraints gbc_chatField = new GridBagConstraints();
gbc_chatField.insets = new Insets(0, 0, 5, 5);
gbc_chatField.gridheight = 2;
gbc_chatField.gridwidth = 6;
gbc_chatField.fill = GridBagConstraints.BOTH;
gbc_chatField.gridx = 5;
gbc_chatField.gridy = 7;
c.add(chatField, gbc_chatField);
chatField.setColumns(10);
btnGroup = new JButton("Group");
GridBagConstraints gbc_btnGroup = new GridBagConstraints();
gbc_btnGroup.fill = GridBagConstraints.BOTH;
gbc_btnGroup.insets = new Insets(0, 0, 5, 5);
gbc_btnGroup.gridx = 2;
gbc_btnGroup.gridy = 8;
c.add(btnGroup, gbc_btnGroup);
btnQuit = new JButton("Quit");
GridBagConstraints gbc_btnQuit = new GridBagConstraints();
gbc_btnQuit.fill = GridBagConstraints.BOTH;
gbc_btnQuit.gridheight = 2;
gbc_btnQuit.insets = new Insets(0, 0, 5, 5);
gbc_btnQuit.gridx = 5;
gbc_btnQuit.gridy = 9;
c.add(btnQuit, gbc_btnQuit);
btnSend = new JButton("Send");
GridBagConstraints gbc_btnSend = new GridBagConstraints();
gbc_btnSend.fill = GridBagConstraints.BOTH;
gbc_btnSend.gridwidth = 3;
gbc_btnSend.gridheight = 2;
gbc_btnSend.insets = new Insets(0, 0, 5, 5);
gbc_btnSend.gridx = 8;
gbc_btnSend.gridy = 9;
c.add(btnSend, gbc_btnSend);
c.revalidate();
c.repaint();
} else{
//if login fails, display an error message, close the data flow streams, and dispose of the window
JOptionPane.showMessageDialog(null, "Logon unsuccessful. \nConnection Terminated.", "Login Unsuccessful", JOptionPane.WARNING_MESSAGE);
setEnabled(false);
closeStreams();
dispose();
}
}
void attemptLogin(){
try {
//get username from text area and encrypt
String loginName = username.getText();
EncryptedMessage uname = new EncryptedMessage(loginName);
//get password from text area and encrypt
String loginPword = new String(password.getPassword());
EncryptedMessage pword = new EncryptedMessage(loginPword);
uname.encrypt();
clientOutputStream.writeObject(uname);
pword.encrypt();
clientOutputStream.writeObject(pword);
/* create a new thread of YourChat_ClientThread, sending input
stream variable as a parameter */
thread = new YourChat_ClientThread(clientInputStream);
thread.run();
}catch(IOException e){
System.out.println(e);
System.exit(1);
}
}
void closeStreams()
{ try
{ // close input stream
clientOutputStream.close();
// close output stream
clientInputStream.close();
// close socket
socket.close();
}
catch(IOException e) // thrown by method close
{ System.out.println(e);
System.exit(1);
}
}
void addBroadcast(String s)
{ // add a message to the broadcast text output area
broadcastArea.append(s + "\n");
broadcastArea.setCaretPosition(broadcastArea.getText().length());
}
void getConnections() { try
{ // initialise a socket and get a connection to server
socket = new Socket(InetAddress.getLocalHost(), 6000);
// get input & output object streams
clientOutputStream = new ObjectOutputStream(socket.getOutputStream());
clientInputStream = new ObjectInputStream(socket.getInputStream());
}
catch(UnknownHostException e) // thrown by method getLocalHost
{ System.out.println(e);
System.exit(1);
}
catch(IOException e) // thrown by methods ObjectOutputStream, ObjectInputStream
{ System.out.println(e);
System.exit(1);
}
}
/*
* -------------------------------------------------------------------------
* ----------------------YourChat_ClientThread Class------------------------
* -------------------------------------------------------------------------
*/
public class YourChat_ClientThread{
ObjectInputStream threadInputStream;
public YourChat_ClientThread(ObjectInputStream in){
threadInputStream = in;
}
public void run(){
try{
Boolean loggedOn = (Boolean)clientInputStream.readObject();
participantNo = clientInputStream.readInt();
if(loggedOn){
CompressedMessage welcome = (CompressedMessage) clientInputStream.readObject();
welcome.decompress();
String message = welcome.getMessage();
setUpChat(loggedOn);
String inMessage;
CompressedMessage cMessage;
while(loggedOn){
cMessage = (CompressedMessage)clientInputStream.readObject();
cMessage.decompress();
inMessage = cMessage.getMessage();
//identfier is the first char of the message
char identifier = inMessage.charAt(0);
//once the char identifier has been taken, the char can be removed from the string
inMessage = inMessage.substring(1, inMessage.length());
if (identifier == 'q'){
addBroadcast(inMessage);
} else if(identifier == 'g'){
addBroadcast(inMessage);
closeStreams();
c.setEnabled(false);
} else if(identifier == 'j'){
addBroadcast(inMessage);
CompressedMessage usernameMessage = (CompressedMessage)clientInputStream.readObject();
usernameMessage.decompress();
String username = usernameMessage.getMessage();
switch (username){
case "Arken": btnArken.setEnabled(true); break;
case "Ben": btnBen.setEnabled(true); break;
case "Darklark":btnDarklark.setEnabled(true); break;
case "Free": btnFree.setEnabled(true); break;
}
}else if(identifier == 'o'){
}
}
} else{
CompressedMessage denied = (CompressedMessage) clientInputStream.readObject();
denied.decompress();
String message = denied.getMessage();
closeStreams();
JOptionPane.showMessageDialog(null, message, "ERROR", JOptionPane.ERROR_MESSAGE);
System.exit(1);
}
}catch(IOException e1){
System.out.println(e1);
System.exit(1);
}catch(ClassNotFoundException e1){
System.out.println(e1);
System.exit(1);
}
}
public void disableWindow(){
btnBen.setEnabled(false);
btnArken.setEnabled(false);
btnDarklark.setEnabled(false);
btnFree.setEnabled(false);
}
}
//main method
public static void main(String [] args){
YourChat_Client client = new YourChat_Client();
client.getConnections();
}
}
答案 0 :(得分:3)
请阅读Java教程课程:(Concurrency in Swing)。
您正在启动一个线程YourChat_ClientThread
,用于更新EDT之外的GUI。这可能会导致多个更新和GUI问题。在Swing中,所有GUI更新必须在事件调度线程(EDT)中执行。
我不确定这是否是您的根本问题,但您应该在检查其他问题之前清理有关EDT的代码。