1

I am creating a program where the contents of a directory is being copied to another directory. Before the copy process commences I am trying to open a second Jframe to tell the user that the copying is in progress. The issue is that the second JFrame does not load completely until the copy progress is completed. Does anyone know of a way to load the second frame completely before starting the copying?

First Frame Code

public class First {

private JFrame frmFirstFrame;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                First window = new First();
                window.frmFirstFrame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the application.
 */
public First() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
    frmFirstFrame = new JFrame();
    frmFirstFrame.setTitle("First Frame");
    frmFirstFrame.setBounds(100, 100, 450, 300);
    frmFirstFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frmFirstFrame.getContentPane().setLayout(null);

    JButton btnCopy = new JButton("Copy");
    btnCopy.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {
            String source = "D:\\";
            String destination = "D:\\test\\";

            Second second = new Second();

            second.setVisible(true);

            File s = new File (source);
            File d = new File (destination);

            try {

                FileUtils.copyDirectory(s, d);
                //second.setVisible(false);
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    });
    btnCopy.setBounds(184, 111, 89, 23);
    frmFirstFrame.getContentPane().add(btnCopy);
}}

Second Frame Code

public class Second extends JFrame {

private JPanel contentPane;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Second frame = new Second();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Second() {
    setTitle("Second Frame");
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    JLabel lblCopyCompleted = new JLabel("Copy in Progress...");
    lblCopyCompleted.setBounds(76, 70, 217, 37);
    contentPane.add(lblCopyCompleted);
    }
}

This is what I am getting during the copy progress.

enter image description here

It should look like this during copying.

enter image description here

Jinro9
  • 67
  • 1
  • 1
  • 5

1 Answers1

3
  1. The second JFrame should be a JDialog, since your application should have only one JFrame (main window). For more on this, please see: The Use of Multiple JFrames, Good/Bad Practice?
  2. Your problem is that your code does not respect Swing threading rules, and by doing long-running tasks on the Swing event thread, you tie up the thread, preventing it from doing its necessary jobs, including drawing to windows and interacting with the user.
  3. A good solution is to use a background thread, specifically one obtained from a SwingWorker. Tutorial: Lesson: Concurrency in Swing

import java.awt.*;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.concurrent.ExecutionException;

import javax.swing.*;

@SuppressWarnings("serial")
public class First2 extends JPanel {
    private static final int COLS = 15;
    private JTextField sourceField = new JTextField(COLS);
    private JTextField destField = new JTextField(COLS);
    private JDialog dialog;
    private DialogPanel dialogPanel = new DialogPanel();

    public First2() {
        setLayout(new GridBagLayout());
        add(new JLabel("Source:"), createGbc(0, 0));
        add(sourceField, createGbc(1, 0));

        add(new JLabel("Destination:"), createGbc(0, 1));
        add(destField, createGbc(1, 1));

        add(new JButton(new CopyAction("Copy")), createGbc(1, 2));
    }

    private GridBagConstraints createGbc(int x, int y) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.insets = new Insets(4, 4, 4, 4);
        return gbc;
    }

    private class CopyAction extends AbstractAction {
        public CopyAction(String name) {
            super(name);
            int mnemonic = (int) name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String src = sourceField.getText();
            String dest = destField.getText();

            MyWorker myWorker = new MyWorker(src, dest);
            myWorker.addPropertyChangeListener(new WorkerListener());
            myWorker.execute();

            Window window = SwingUtilities.getWindowAncestor(First2.this);
            dialog = new JDialog(window, "File Copy", ModalityType.APPLICATION_MODAL);
            dialog.add(dialogPanel);
            dialog.pack();
            dialog.setLocationRelativeTo(null);
            dialog.setVisible(true);
        }
    }

    private class MyWorker extends SwingWorker<Void, Void> {
        private String src;
        private String dest;

        public MyWorker(String src, String dest) {
            this.src = src;
            this.dest = dest;
        }

        @Override
        protected Void doInBackground() throws Exception {
            FileUtils.copyDirectory(src, dest);
            return null;
        }
    }

    private class WorkerListener implements PropertyChangeListener {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (evt.getNewValue() == SwingWorker.StateValue.DONE) {
                if (dialog != null && dialog.isVisible()) {
                    dialog.dispose();
                }
                try {
                    ((MyWorker) evt.getSource()).get();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static void createAndShowGui() {
        First2 mainPanel = new First2();

        JFrame frame = new JFrame("First2");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}

class DialogPanel extends JPanel {
    private static final int PREF_W = 300;
    private static final int PREF_H = 250;

    public DialogPanel() {
        setLayout(new GridBagLayout());
        add(new JLabel("Copy in Progress..."));
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }
}
Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373