[英]Java application with multiple jframe-threads
Hello all I am building a java application where i want to select a users from a list of users and create a new JFrame to chat with(for example a new user-to-user chatbox). 大家好,我正在构建一个Java应用程序,我想从用户列表中选择一个用户并创建一个新的JFrame与之聊天(例如,一个新的用户对用户聊天框)。 I have created the new JFrame into a thread i called it ChatGUI.
我已经将新的JFrame创建到一个名为ChatGUI的线程中。
I am working with Smack so each of my ChatGUI object should have a MessageListener. 我正在使用Smack,因此我的每个ChatGUI对象都应该具有一个MessageListener。 When i exit a chatGUI thread it should delete everyting the thread created(for example the MessegeListener) and exit without interrupting any of the other threads(with their own MessegeListeners).
当我退出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();
} } }}
Problem: For now i can create a new ChatGUI for each user but when i click exit in any of the created chatGUI-threads it closes the main process and all other chatGUIs. 问题:现在,我可以为每个用户创建一个新的ChatGUI,但是当我在任何已创建的chatGUI线程中单击“退出”时,它将关闭主进程和所有其他chatGUI。 Apologize for bad English.
对英语不好表示歉意。
I found the solution: Since I am using Smack 3.2.2 it does not have the capability to stop a Chat. 我找到了解决方案:由于我正在使用Smack 3.2.2,因此它没有停止聊天的功能。 My JFrame exited well after using newFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
使用newFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)后,我的JFrame退出良好; instead of using newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
而不是使用newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.