import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

/** SwingWorker: pekerjaan berat di thread latar, notifikasi di EDT. */
public class PekerjaLatar {
    static final int[] BEBAN = { 10, 15, 25, 25, 15 };

    public static void main(String[] args) throws Exception {
        List<Integer> progres = Collections.synchronizedList(new ArrayList<>());
        List<Boolean> prosesDiEdt = Collections.synchronizedList(new ArrayList<>());

        SwingWorker<String, Integer> pekerja = new SwingWorker<>() {
            @Override
            protected String doInBackground() {
                int total = 0;
                for (int b : BEBAN) {
                    try {
                        Thread.sleep(20); // simulasi unduhan satu potongan
                    } catch (InterruptedException e) {
                        return "terputus";
                    }
                    total += b;
                    publish(total); // kirim progres ke EDT
                }
                return "selesai, total beban " + total;
            }

            @Override
            protected void process(List<Integer> potongan) {
                // berjalan di EDT: satu-satunya tempat yang boleh menyentuh UI
                prosesDiEdt.add(SwingUtilities.isEventDispatchThread());
                progres.addAll(potongan);
            }
        };

        pekerja.execute();            // mulai pekerjaan di thread latar
        String hasil = pekerja.get(); // tunggu pekerjaan tuntas

        // Tunggu seluruh potongan progres tiba di EDT (paling lama 2 detik).
        for (int i = 0; i < 400 && progres.size() < BEBAN.length; i++) {
            Thread.sleep(5);
        }

        System.out.println("hasil                = " + hasil);
        System.out.println("urutan progres       = " + progres);
        System.out.println("process selalu di EDT = " + !prosesDiEdt.contains(false));
    }
}
