28. april 2003 - 20:35Der er
26 kommentarer og 1 løsning
ProgressMonitor
Jeg er igang med at lave et script der kan kryptere/dekryptere med AES kryptering. Dette virker også glimrende. Men når jeg skal koble dette sammen med en GUI vil jeg gerne have en progressmonitor der kan fortælle brugeren hvordan det står til med processsen.
Jeg har testet AES delen, og her er der ingen problemer med de værdier jeg benytter til GUIen.
Jeg har så i GUI'en defineret en ProgressMonitor som jeg vil benytte. Denne benytter en timerListener der kaldes hvert sekund og opdatere monitoren. Men monitoren vises aldrig. Jeg har så testet dette script og skriver ud hver gang Listeneren skal kaldes, men den kaldes først efter krypteringen er færdig.
Jeg er rimelig på herrens mark med dette så jeg håber på hjælp!
//Delen der kalder encrypt. og derved også progressmonitoren timer = new Timer(ONE_SECOND, new TimerListener()); aes = new Stream_AES(fileIn,fileOut,keyField.getText(),(new Integer(keyBitSize)).intValue()); progressMonitor = new ProgressMonitor(design.this, "Encrypting...","", 0, aes.getLength()); progressMonitor.setProgress(0); progressMonitor.setMillisToPopup(ONE_SECOND/2);
String fileOut = outFile.getText(); timer = new Timer(ONE_SECOND, new TimerListener()); Stream_AES aes = new Stream_AES(fileIn,fileOut,keyField.getText(),(new Integer(keyBitSize)).intValue()); progressMonitor = new ProgressMonitor(design.this, "Encrypting...","", 0, aes.getLength()); progressMonitor.setProgress(0); progressMonitor.setMillisToPopup(ONE_SECOND/2);
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Jeg har lidt svært ved helt at gennemskue din kode.
Men jeg har lavet et lille eksempel med en DummyEncrypter som ser ud til at virke fint:
package test;
import java.awt.event.*; import javax.swing.*;
public class ProgTest extends JFrame { private final static int N = 100; private ProgressMonitor progressMonitor; private Timer timer; private DummyEncrypter aes = new DummyEncrypter(); public ProgTest() { super(); progressMonitor = new ProgressMonitor(this, "Encryption", "Running", 0, N); progressMonitor.setProgress(0); timer = new Timer(1000, new TimerListener()); timer.start(); aes.encrypt(); } class TimerListener implements ActionListener { public void actionPerformed(ActionEvent evt) { progressMonitor.setProgress(aes.getCurrent()); if (aes.isDone()) { timer.stop(); } } } public static void main(String[] args) throws Exception { ProgTest f = new ProgTest(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.pack(); f.setVisible(true); } }
class DummyEncrypter { private final static int N = 100; private int n = 0; public int getCurrent() { if (n < N) n++; return n; } public boolean isDone() { return (n >= N); } public void encrypt() { while (!isDone()) { try { Thread.sleep(100); } catch (InterruptedException e) { } } } }
den kommer frem med progressmonitoren nu, men den når at afslutte krypteringen inden den kommer frem. Det er som om krypteringen tager alle resourcer og derefter kan den starte monitoren.
Men så står den naturligvis bare på det sted hvor den er nået, i dette tilfælde 6 af 100...
Satte dette ind, og har declareret exceptionen i klassen, men får følgende fejl.. Stream_AES.java:113: exception java.lang.InterruptedException is never thrown in body of corresponding try statement catch (InterruptedException e) { ^ Stream_AES.java:229: unreported exception java.lang.InterruptedException; must be caught or declared to be thrown stream1.encrypt();
Jeg har sat den ind nu, hver gang jeg sender en mb videre til kryptering.
Men som før kommer monitoren ikke frem...(hvis slut er længden af processen) Jeg har bedt den om at udskrive current, der er det tal der viser hvor langt den er nået, dette gør den også, men først når den er færdig med dette vises progressmonitoren.(hvis slut er 100)
Nej, det er den faktisk ikke. Den nedarver direkte fra Object. Derfor er det ikke umiddelbart klart hvilken tråd den udføres i. Dokumentationen siger blot at den udføres i en baggrundstråd, men ikke hvilken. Den kunne derfor dele resourcer med andre processer der bruger al tiden. Når jeg bruge ProgressMonitor benytter jeg en eksplicit ny tråd til at tegne med.
Although all Timers perform their waiting using a single, shared thread (created by the first Timer object that executes), the action event handlers for Timers execute on another thread -- the event-dispatching thread. This means that the action handlers for Timers can safely perform operations on Swing components. However, it also means that the handlers must execute quickly to keep the GUI responsive.
Men det sidste re måske en forklaring. Hvis den tunge krypterings process udføres direkte i en event-handler ("start button"), så er det nok det der er skyld i problemet.
Jeg har min startknap, når der trykkes på den kaldes listener. private final class listener implements ActionListener { public void actionPerformed(ActionEvent e) { HandleChoice(e.getActionCommand()); } }
Listener kalder så videre til HandleChoice og her begynder jeg krypteringen og timeren på den måde jeg har beskrevet i mit spg.
ok...! Det vil jeg prøve, men tænkte på om det kan lade sig gøre at skrive til progressmonitoren eller kalde den fra aes-klassen. Altså så hver gang jeg sender en mb, videre til kryptering opdateres monitoren, og vil det i såfald være hensigtsmæssigt?
public class ProgTest extends JFrame { private ProgressMonitor progressMonitor; private Timer timer; private DummyEncrypter aes = new DummyEncrypter(); public ProgTest() { super(); progressMonitor = new ProgressMonitor(this, "Encryption", "Running", 0, aes.getLength()); progressMonitor.setProgress(0); timer = new Timer(1000, new TimerListener()); timer.start(); (new EncrypterThread(aes)).start(); aes.encrypt(); } class TimerListener implements ActionListener { public void actionPerformed(ActionEvent evt) { progressMonitor.setProgress(aes.getCurrent()); if (aes.isDone()) { timer.stop(); } } } public static void main(String[] args) throws Exception { ProgTest f = new ProgTest(); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); f.pack(); f.setVisible(true); } }
class DummyEncrypter { private final static int N = 100; private int n = 0; public int getCurrent() { if (n < N) n++; return n; } public int getLength() { return N; } public boolean isDone() { return (n >= N); } public void encrypt() { while (!isDone()) { try { Thread.sleep(100); } catch (InterruptedException e) { } } } }
class EncrypterThread extends Thread { private DummyEncrypter aes; public EncrypterThread(DummyEncrypter aes) { this.aes = aes; } public void run() { aes.encrypt(); } }
Nu er vi meget tæt på... Det virkede for krypteringen før, men da jeg så ville udbygge det, tilføjede denne klasse class DecrypterThread extends Thread { private Stream_AES aes; public EncrypterThread(Stream_AES aes) throws IOException { this.aes = aes;
og testede med en if oppe i kaldet hvilken af de 2 der skulle kaldes fik jeg denne fejl, og jeg kan ikke se hvad det er jeg har gjort galt.. design.java:632: invalid method declaration; return type required public EncrypterThread(Stream_AES aes) throws IOException { ^ 1 error
Det virker. Mange tak for hjælpen. Afsatte lige lidt flere point, da du har brugt lang tid på dette...
Men tak for hjælpen. /Jens
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.