Zamieszanie z wątkami (program z GUI)

Odpowiedz Nowy wątek
2019-06-23 11:54
0

Cześć.
Piszę prosty budzik komputerowy. Ma interfejs graficzny, który tworzę w metodzie main. W tej samej metodzie mam dwa wątki :

  • Pierwszy od sprawdzania czy został dodany nowy alarm
  • Drugi sprawdzający czy ma wywołać jakiś alarm

Zauważyłem, że konstruktor dla klasy okna głównego aplikacji jest wywoływany trzy razy. Co więcej wątek sprawdzający czy został dodany nowy alarm działa ale dodaje do listy tylko w swoim obrębie czyli lista w oknie głównym się nie powiększa, a powinna. Znalazłem informację, że może pomóc 'volatile' przy deklaracji jednak to na nic.
Pracę z wątkami dopiero zaczynam i muszę przyznać, że mocno się gubię.

Metoda main:

 public static void main(String[] args) throws InterruptedException {
        JFrame frame = new JFrame("oknoGlowne");
        frame.setContentPane(new oknoGlowne().jpanel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

        Runnable w1 = new watekSprListeAlarmow();
        Thread t1 = new Thread(w1);
        t1.start();

        Runnable w2 = new watekSprCzyWlaczycAlarm();
        Thread t2 = new Thread(w2);
        t2.start();
    }

Wątek : watekSprListeAlarmow

public class watekSprListeAlarmow extends oknoGlowne.oknoGlowne implements Runnable{

    @Override
    public void run() {
        while(true)
        {
            if (pobierzListePlikowDlaAlarmow().size() > listaWszystkchAlarmow.size()) {
                stworzWykazAlarmow();
            }
        }
    }
}

Wątek : watekSprCzyWlaczycAlarm

public class watekSprCzyWlaczycAlarm extends oknoGlowne.oknoGlowne implements Runnable{

    @Override
    public void run() {
        try {
            while (true)
            {
                //Pobranie dnia tygodnia
                GregorianCalendar kalendarz = new GregorianCalendar();
                int dzienTygodniaWInt = kalendarz.get(Calendar.DAY_OF_WEEK);
                DateFormatSymbols dfs = new DateFormatSymbols();
                String dzienTygodnia = dfs.getWeekdays()[dzienTygodniaWInt];
                //=====
                Date data = new Date();

                for(int i=0; i<listaAktywanychAlarmow.size(); i++)
                {
                    if(dzienTygodnia.equals(listaAktywanychAlarmow.get(i).getDzienTygodnia()))
                    {
                        String godzina = data.getHours() + ":" + data.getMinutes();

                        if(godzina.equals(listaAktywanychAlarmow.get(i).getGodzina()))
                        {
                            JFrame frame = new JFrame("");
                            JOptionPane.showMessageDialog(frame, "Alarm");
                        }
                    }
                }

                sleep(1000);
            }
        }catch (InterruptedException ie)
        {
            JFrame frame = new JFrame("");
            JOptionPane.showMessageDialog(frame, ie.toString());
        }
    }
}

Metoda stworzWykazAlarmow() - wywolana w watku : watekSprListeAlarmow

public void stworzWykazAlarmow()
    {

        stworzListeAlarmow();
        JPanel panel= new JPanel();
        panel.setLayout(new GridLayout(listaWszystkchAlarmow.size(),5));

        for(int i=0; i<listaWszystkchAlarmow.size(); i++)
        {
            panel.add(new Label(listaWszystkchAlarmow.get(i).getDzienTygodnia()+""));
            panel.add(new Label(listaWszystkchAlarmow.get(i).getGodzina()+""));
            panel.add(new Label(listaWszystkchAlarmow.get(i).isCzyAktywny()+""));
            panel.add(new Button("Edytuj"),"btnEdytuj"+i);
            panel.add(new Button("Usun"),"btnUsun"+i);

        }
        jScrollPanel.setViewportView(panel);
    }

Metoda stworzListeAlarmow wywolana w metodzie stworzWykazAlarmow

 public void stworzListeAlarmow()
    {
        listaWszystkchAlarmow.clear();
        listaAktywanychAlarmow.clear();

        List<File>listaPlikowAlarmow = pobierzListePlikowDlaAlarmow();

        alarm alTymczasowy;

        for(int i=0; i<listaPlikowAlarmow.size(); i++)
        {
                alTymczasowy = wczytajDaneZPlikuAlarmu(listaPlikowAlarmow.get(i));

                if(alTymczasowy!=null)
                {
                    if(alTymczasowy.isCzyAktywny())
                    {
                        listaAktywanychAlarmow.add(alTymczasowy);
                        listaWszystkchAlarmow.add(alTymczasowy);
                    }else
                    {
                        listaWszystkchAlarmow.add(alTymczasowy);
                    }
                }
        }
    }

W konstruktorze okna głównego wywołuję tylko metodę stworzWykazAlarmow(), którą wkleiłem wcześniej.
Listy są typu 'alarm'.
Klasa ta wygląda następująco:

public class alarm {
    private String dzienTygodnia;
    private String godzina;
    private String sciezkaDoDzwieku;
    private boolean czyAktywny;

    public alarm(String dzienTygodnia, String godzina, String sciezkaDoDzwieku, boolean czyAktywny) {
        this.dzienTygodnia = dzienTygodnia;
        this.godzina = godzina;
        this.sciezkaDoDzwieku = sciezkaDoDzwieku;
        this.czyAktywny = czyAktywny;
    }

    public String getDzienTygodnia() {
        return dzienTygodnia;
    }

    public void setDzienTygodnia(String dzienTygodnia) {
        this.dzienTygodnia = dzienTygodnia;
    }

    public String getGodzina() {
        return godzina;
    }

    public void setGodzina(String godzina) {
        this.godzina = godzina;
    }

    public String getSciezkaDoDzwieku() {
        return sciezkaDoDzwieku;
    }

    public void setSciezkaDoDzwieku(String sciezkaDoDzwieku) {
        this.sciezkaDoDzwieku = sciezkaDoDzwieku;
    }

    public boolean isCzyAktywny() {
        return czyAktywny;
    }

    public void setCzyAktywny(boolean czyAktywny) {
        this.czyAktywny = czyAktywny;
    }
}

Z góry dzięki za pomoc.

edytowany 1x, ostatnio: kisiel1996, 2019-06-23 11:55
Inny wątek nie może bezpośrednio zmieniać elementów gui z maina. - au7h 2019-06-23 12:14
możesz zrobić w klasie z wątkiem delegatę (do niej setter) i kiedy ten skończy działanie z delegaty wywoływać metodę np processFinish i tam updateować gui - au7h 2019-06-23 12:22

Pozostało 580 znaków

2019-06-23 12:31
0

Zauważyłem, że konstruktor dla klasy okna głównego aplikacji jest wywoływany trzy razy.

Bo Twoje klasy wątków dziedziczą z klasy okna głównego więc tworząc je wywołujesz też konstruktor klasy bazowej. Tyle że to są inne obiekty i operują na innych danych.

Zamiast wątków użyj timer'ów: https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html

edytowany 1x, ostatnio: Delor, 2019-06-23 12:40

Pozostało 580 znaków

2019-06-23 13:12
0

Wykorzystałem pomysł au7h i wszystko działa.
Dzięki wielkie za rady.

nieIdźTąDrogą :) przerzuć się na pisanie kodu po angielsku i to jak najszybciej! - kixe52 2019-06-23 20:40

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0