简体   繁体   中英

Java Swing Worker causes GUI freeze

Hello there I am trying to implement a chat using RMI. The algorithm is the following: both the shared RMI object and the clients have a String variable for the last typed message. Whenever a client types a message, the message from the shared RMI object updates(messageRMI=messageClient). If a client doensn't have its last message equal with the message from the RMI Object, the last message will be automatically typed in the jTextPane.

This is the swing worker:

    SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
        @Override
        protected Void doInBackground()
            throws Exception {
            byte[] the_image;
            while (true) {
                Thread.sleep(1000);
                if (connected) {
                    try {
                        remote = (I) Naming.lookup("rmi://" + jTextFieldAddress.getText() + "/Niemand23");
                        switch (remote.refresh_chat(last_message)) {
                            case 0:
                                last_message = remote.last_message();
                                jTextPane1.getStyledDocument().insertString(jTextPane1.getDocument().getLength(), "\n ", null);
                                if (remote.hasImage()) {
                                    the_image = remote.client_image();
                                    formatC = new ImageIcon(the_image);
                                    jTextPane1.insertIcon(formatC);
                                } else {
                                    jTextPane1.insertIcon(noImageIcon);
                                }
                                jTextPane1.getStyledDocument()
                                    .insertString(jTextPane1.getDocument().getLength(), "\n " + remote.last_message(), style);
                                jTextPane1.getStyledDocument().insertString(jTextPane1.getDocument().getLength(), "\n", null);
                        }
                    } catch (NotBoundException | MalformedURLException | RemoteException | BadLocationException ex) {
                        Logger.getLogger(Client.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        }
    };

The worker should check the condition every second. The big problem is that whenever a client types a message, the GUI from the second one freezes. I've tried everything but no result. Any ideas?

If you read the SwingWorker javadocs you'll see you should not be making direct changes to the Swing components in your doInBackground() method.

Rather, you should implement the process() method and use the publish() method in doInBackground() . For specifics, look at the publish method .

In your case this would entail switching your SwingWorker<Void, Void> to SwingWorker<Void,String> and publish() each message as you receive it. Your process(String...s) method would then populate the jTextPane1 with the incoming messages.

Give this a try and see how it works.

ETA : Also, do you need to be performing the naming lookup in every runthrough of your loop? The address isn't changing, is it?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM