具有多个jframe-threads的Java应用程序

时间:2016-09-11 12:16:48

标签: java multithreading swing

大家好我正在构建一个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。 为糟糕的英语道歉。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案: 由于我使用的是Smack 3.2.2,因此无法停止聊天。 使用newFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE)后,我的JFrame退出了。而不是使用newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);