SwingWorker Doesn't Work in ActionListener

421 views Asked by At

In part of my email program, the user can select the message folder they want to open through a drop down JComboBox. This process can take up to twenty seconds depending on how many messages are in the folder, and before this would just freeze up the program. This wasn't desirable, so I utilized SwingWorker to run the opening of the folder in the background of the GUI and display a progress bar while the folder is being accessed.

The accessing of the folders is implemented with an ActionListener which listens for the folder name selected and sets the selected String as the name of the folder to be accessed. Here is the code for the ActionListener, where items is an array of folder names.

    box = new JComboBox<String>(items);
    box.setEditable(false);
    box.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            try
            {
                String selected = (String)box.getSelectedItem();
                if(selected.equals("Choose Folder"))
                    accessFolder(null);
                else if(selected.equals("Inbox"))
                    accessFolder("INBOX");
                else
                {
                    selected = TAG + selected;
                    accessFolder(selected);
                }
            }
            catch(Exception ex)
            {
                JOptionPane.showMessageDialog(null, "Error: " + 
                ex.getClass().getName(), "Error", JOptionPane.ERROR_MESSAGE);
            }
        }
    });

The end result of this code is as expected: a list of all messages is added to part of the main frame. But the progress bar never shows up. But if I add the code for the accessFolder method directly to the main method (where the ActionListener is added to the combo box), the progress bar shows up for the entirety of the process and I get the same end result. This is the accessFolder code.

private void accessFolder(String folderName) throws MessagingException, IOException
{
    MessagePanel mPanel = new MessagePanel(username, password, folderName);
    panel4 = mPanel.getJPanel();   
    panel4.setBorder(BorderFactory.createLoweredBevelBorder());
    BorderLayout layout = (BorderLayout)panel3.getLayout();
    panel3.remove(layout.getLayoutComponent(BorderLayout.EAST));
    panel3.add(panel4, BorderLayout.EAST);
    frame.pack();
    frame.revalidate();
}

So I can't seem to figure out why the SwingWorker (implemented in the MessagePanel class in accessFolder) works perfectly fine when implemented anywhere in the code except in an ActionListener. I can't seem to find anywhere a mention of a conflict between SwingWorker and listeners, and I don't see why there should be, leaving me completely baffled here. Thanks for any comments.

Edit: Here is the SwingWorker code.

public class FolderWorker extends CMailWorker
{
    private String username;
    private String password;
    private String foldername;
    private FolderContents accessor;
    private ArrayList<MailList> msgList;
    private DefaultListModel<String> model;
    private ProgressBar bar;
    private final static String PENDING = "Accessing...";
    public FolderWorker(String user, String pass, String fName)
    {
        super(PENDING, null);
        this.username = user;
        this.password = pass;
        this.foldername = fName;
    }
    protected Void doInBackground()
    {
        try
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    try
                    {
                        createProgressBar();
                    }
                    catch(Exception ex)
                    {
                        setException(ex);
                   }
                }
            });
            super.throwException();
            accessor = new FolderContents(username, password, foldername);
            model = new DefaultListModel<String>();
            msgList = accessor.getMessageList();
            for(int x = msgList.size()-1; x>=0; x--)
            {
                MailList mList = msgList.get(x);
                String sub = mList.getSubject();
                model.addElement(sub);
            }
            return null;
        }
        catch(final Exception ex)
        {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    JOptionPane.showMessageDialog(null, "Error: " + 
                    ex.getClass().getName(), "Error", JOptionPane.ERROR_MESSAGE);
                }
            });
            super.setError(true);
            return null;
        }
    }
    public ArrayList<MailList> getList()
    {
        return accessor.getMessageList();
    }
    public DefaultListModel<String> getModel()
    {
        return model;
    }
}

And that class extends this class.

public class CMailWorker extends SwingWorker<Void, Void>
{
    private ProgressBar bar;
    private String completed;
    private String message;
    private boolean error;
    private JFrame frame;
    private Exception exception;
    public CMailWorker(String msg, String done)
    {
        completed = done;
        message = msg;
        error = false;
    }
    protected Void doInBackground()
    {
        return null;
    }
    protected void done()
    {
        bar.dispose();
        if(frame != null)
            killJFrame();
        if(!error && completed != null)
            JOptionPane.showMessageDialog(null, completed);
    }
    protected void setJFrame(JFrame f)
    {
        frame = f;
    }
    private void killJFrame()
    {
        frame.dispose();
    }
    protected void createProgressBar() throws InterruptedException
    {
        bar = new ProgressBar(message);
    }
    protected void setError(boolean e)
    {
        error = e;
    }
    protected boolean getError()
    {
        return error;
    }
    protected void throwException() throws Exception
    {
        if(exception != null)
            throw exception;
    }
    protected void setException(Exception e)
    {
        exception = e;
    }
    protected Exception getException()
    {
        return exception;
    }
}
0

There are 0 answers