0

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). I have created the new JFrame into a thread i called it ChatGUI.

I am working with Smack so each of my ChatGUI object should have a 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).

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. Apologize for bad English.

Drunk Cat
  • 483
  • 1
  • 4
  • 9
  • 1
    1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) See [Detection/fix for the hanging close bracket of a code block](http://meta.stackexchange.com/q/251795/155831) for a problem I could no longer be bothered fixing. 3) See [The Use of Multiple JFrames, Good/Bad Practice?](http://stackoverflow.com/q/9554636/418556) – Andrew Thompson Sep 11 '16 at 12:32
  • 2
    `newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);` Think about (and ***research***) the effect of this code statement.. – Andrew Thompson Sep 11 '16 at 12:33
  • @Andrew Thompson I have already tried to use newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); inside windowClosing event and still have the problems that it kills all the others ChatGUI-threads and the main application... – Drunk Cat Sep 11 '16 at 12:41
  • @AndrewThompson So you are suggesting me to use Dialogs for each new chatbox instead of using a jframe-thread? – Drunk Cat Sep 11 '16 at 12:47
  • *"use Dialogs for each new chatbox instead of using a jframe-thread?"* Yes, use dialogs instead of the frame, but it would still need threads, Glad to see you got the tip about `DISPOSE_ON_CLOSE`.. – Andrew Thompson Sep 11 '16 at 19:45

1 Answers1

0

I found the solution: Since I am using Smack 3.2.2 it does not have the capability to stop a Chat. My JFrame exited well after using newFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); instead of using newFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

Drunk Cat
  • 483
  • 1
  • 4
  • 9