Hirdetés

Keresés

Új hozzászólás Aktív témák

  • Karma
    félisten

    Ismét kellene egy kis segítség:

    Adott kettő class közös package-ben:

    programGUI és fileMasolas

    programGUI.java ködrészlete:

    //Progress bar:
    JDialog copyModalDialog = new JDialog();
    copyModalDialog.setTitle("Mentés másolása folyamatban");

    pb = new JProgressBar(0, 100);
    pb.setValue(0);
    pb.setStringPainted(true);

    JPanel panel = new JPanel();
    panel.add(pb);

    panel.setBorder(BorderFactory.createEmptyBorder(40, 75, 40, 75));
    copyModalDialog.setContentPane(panel);
    copyModalDialog.setResizable(false);
    copyModalDialog.setModal(true);
    copyModalDialog.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    copyModalDialog.pack();
    copyModalDialog.setLocationRelativeTo(null);

    //fájlmásolás szál indítása:
    fileMasolas tMasolas = new fileMasolas();
    tMasolas.start();

    //progress ablak megjelenítése:
    copyModalDialog.setVisible(true);

    fileMasolas.java kód:

    /*
    * To change this template, choose Tools | Templates
    * and open the template in the editor.
    */
    package proba;

    import java.io.*;

    class fileMasolas extends Thread {

    public fileMasolas() {
    }

    public void run() {
    File filein = new File("D:/adat.db");
    File fileout = new File("D:/adat_new.db");

    FileInputStream fin = null;
    FileOutputStream fout = null;
    long length = filein.length();
    long counter = 0;
    int r = 0;
    byte[] b = new byte[100];
    try {
    fin = new FileInputStream(filein);
    fout = new FileOutputStream(fileout);
    while ((r = fin.read(b)) != -1) {
    counter += r;
    int bar = (int) (100.0 * counter / length);
    MentesKeszitoGUI.pb.setValue(bar);
    fout.write(b, 0, r);
    }
    } catch (Exception e) {
    System.out.println("Hiba");
    }
    }
    }

    A kérdés, ha végzett a run() metódus, hogyan tudom ezt a szálat leállítani és visszaadni a másiknak a vezérlést. Vagyis eltüntetni a copyModalDialog-ot?

    Huh, erős kód. Meg egy kicsit erjedt is. Ha már egyszer a progressbar értékét is másik szálból közvetlenül babrálod a setValue-val, miért nem hívod meg a dialógus setVisible-jét amikor vége?

    Félreértéseket elkerülendő, ez így nagyon-nagyon nem jó megoldás, de legalább begipszelnéd a lyukat :P

    A probléma ugyanis az, hogy a Swing (meg úgy egyébként a legtöbb UI framework) nem szereti azt, ha a UI szálon kívül (itt event dispatcher threadnek hívják) bármit módosítasz. Jobb helyeken egy hatalmas exceptiont kapsz a nyakadba, itt úgy tűnik nem.

    A dialógus elindítása még rendben van, a másik szálból nem szabadna közvetlenül hívogatni a setValue-t.

    Fontos megjegyezni, mert ahogy látom itt félreértés van: az új szál indításával a vezérlés két, párhuzamosan futó részre szakadt. Ez a mondatod: A kérdés, ha végzett a run() metódus, hogyan tudom ezt a szálat leállítani és visszaadni a másiknak a vezérlést." értelmetlen, az indító dialógusos kód nem vesztette el a szálát, egyszerűen visszatért az eseményekre várakozó állapotba. Ezt végzi is, csak a modális dialógus miatt nem törődik máshova irányuló kattintásokkal és billentyűleütésekkel.

    Magára a problémára visszatérve, egy kicsit szerteágazik a megoldás, mert olyan alap dolgokkal kellene tisztában lenned, mint a UI (dialógus, progressbar helyzete) elválasztása az üzleti logikától (fájlmásolás száz bájtonként). Kéne egy rendes Listener interfész, amit a másoló hívogat (ezen keresztül jelentve a százalékos állást, számként), és a programGUI-d implementálja.

    Ehhez az implementációhoz meg a SwingUtilities.InvokeLater-t kéne használnod, hogy a dispatcher szálon fusson le a tényleges progress bar frissítés, meg a dialógus elrejtése.

    Így nem függene a másolód attól, hogy a UI-on milyen komponensek vannak és hogy hívják őket, csak a dolgát végezné :U

Új hozzászólás Aktív témák