大家好我正在构建一个java应用程序,我想从用户列表中选择用户并创建一个新的JFrame来与之聊天(例如新的用户到用户聊天框)。我已经将新的JFrame创建到一个名为ChatGUI的线程中。
我正在使用Smack,因此我的每个ChatGUI对象都应该有一个MessageListener。当我退出chatGUI线程时,它应该删除每个创建的线程(例如MessegeListener)并退出而不中断任何其他线程(使用它们自己的MessegeListeners)。
public class ChatGUI extends Thread {
volatile String remoteEndJID, remoteEndName, localEndJID, localEndName;
JFrame newFrame = new JFrame();
JButton sendMessage;
JTextField messageBox;
JTextPane chatBox;
Chat chat;
ChatMessageListener cMsgListener;
XMPPConnection connection;
StyleContext sContext;
volatile LinkedList<String> msgList;
DefaultStyledDocument sDoc;
public ChatGUI(String remoteEndJID, String remoteEndName, String localEndJID, String localEndName,
XMPPConnection connection, Chat chat, boolean createdLocaly, LinkedList<String> msgList) {
this.localEndName = localEndName;
this.remoteEndJID = remoteEndJID;
this.remoteEndName = remoteEndName;
this.localEndJID = localEndJID;
this.connection = connection;
this.chat = chat;
this.msgList = msgList;
if(createdLocaly==true)
cMsgListener = new ChatMessageListener();
start();
}
public void run() {
// Set title
newFrame.setTitle(remoteEndName);
newFrame.addWindowListener( new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
JFrame frame = (JFrame)e.getSource();
stop();
}
});
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel southPanel = new JPanel();
southPanel.setLayout(new GridBagLayout());
messageBox = new JTextField(30);
messageBox.requestFocusInWindow();
sendMessage = new JButton("Invia");
sendMessage.addActionListener(new sendMessageButtonListener());
sendMessage.setContentAreaFilled(false);
newFrame.getRootPane().setDefaultButton(sendMessage);
sContext = new StyleContext();
sDoc = new DefaultStyledDocument(sContext);
chatBox = new JTextPane(sDoc);
chatBox.setEditable(false);
mainPanel.add(new JScrollPane(chatBox), BorderLayout.CENTER);
GridBagConstraints left = new GridBagConstraints();
left.anchor = GridBagConstraints.LINE_START;
left.fill = GridBagConstraints.HORIZONTAL;
left.weightx = 512.0D;
left.weighty = 1.0D;
GridBagConstraints right = new GridBagConstraints();
right.insets = new Insets(0, 10, 0, 0);
right.anchor = GridBagConstraints.LINE_END;
right.fill = GridBagConstraints.NONE;
right.weightx = 1.0D;
right.weighty = 1.0D;
southPanel.add(messageBox, left);
southPanel.add(sendMessage, right);
mainPanel.add(BorderLayout.SOUTH, southPanel);
newFrame.add(mainPanel);
newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
newFrame.setSize(470, 300);
newFrame.setVisible(true);
if(msgList != null) {
startMessageManager();
}
// Start the actual XMPP conversation
if (cMsgListener != null)
chat = connection.getChatManager().createChat(remoteEndJID, cMsgListener);
System.out.println("New chat created : " + chat.getThreadID() + " " + chat.getParticipant());
}
class sendMessageButtonListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (messageBox.getText().length() < 1) {
// Do nothing
} else if (messageBox.getText().equals(".clear")) {
chatBox.setText("Cleared all messages\n");
messageBox.setText("");
} else {
addMessage(new ChatMessage(localEndName, remoteEndName, messageBox.getText(), true));
}
messageBox.requestFocusInWindow();
}
}
public void addMessage(ChatMessage message) {
Style style = sContext.getStyle(StyleContext.DEFAULT_STYLE);
if (message.isMine == true) {
// StyleConstants.setAlignment(style, StyleConstants.ALIGN_RIGHT);
StyleConstants.setFontSize(style, 14);
StyleConstants.setSpaceAbove(style, 4);
StyleConstants.setSpaceBelow(style, 4);
StyleConstants.setForeground(style, Color.BLUE);
try {
sDoc.insertString(sDoc.getLength(),
"(" + message.Time + ") " + message.senderName + ": " + message.body + "\n", style);
} catch (BadLocationException e1) {
e1.printStackTrace();
}
// Send the msg to the RemoteEnd
try {
chat.sendMessage(message.body);
} catch (XMPPException e) {
e.printStackTrace();
}
messageBox.setText("");
}
if (message.isMine == false) {
// StyleConstants.setAlignment(lStyle, StyleConstants.ALIGN_LEFT);
StyleConstants.setFontSize(style, 14);
StyleConstants.setSpaceAbove(style, 4);
StyleConstants.setSpaceBelow(style, 4);
StyleConstants.setForeground(style, Color.RED);
try {
sDoc.insertString(sDoc.getLength(),
"(" + message.Time + ") " + message.senderName + ": " + message.body + "\n", style);
} catch (BadLocationException e) {
e.printStackTrace();
}
}
}
class ChatMessageListener implements MessageListener {
@Override
public void processMessage(Chat chat, Message msg) {
if (msg.getType() == Message.Type.chat) {
addMessage(new ChatMessage(remoteEndName, localEndName, msg.getBody(), false));
System.out.println("The chat with threadID " + chat.getThreadID()
+ " recevied a message from the remoteEnd " + " " + chat.getParticipant());
}
}
}
public void startMessageManager() {
Thread t = new Thread() {
public void run() {
while(true){
if(msgList.size() > 0) {
for(int i=0; i<msgList.size();i++)
addMessage(new ChatMessage(remoteEndName, localEndName, msgList.removeFirst(), false));
}
}
}
};
t.setPriority(Thread.NORM_PRIORITY);
t.start();
} }
问题:现在我可以为每个用户创建一个新的ChatGUI但是当我在任何创建的chatGUI线程中单击exit时,它会关闭主进程和所有其他chatGUI。 为糟糕的英语道歉。
答案 0 :(得分:0)
我找到了解决方案: 由于我使用的是Smack 3.2.2,因此无法停止聊天。 使用newFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)后,我的JFrame退出了。而不是使用newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);