Rainer Wahnsinn Geschrieben 26. Dezember 2010 Teilen Geschrieben 26. Dezember 2010 Hallo, sitz gerade an einem Timer und komm nicht wirklich weiter. Und zwar habe ich einen Thread, der nach und nach eine EKG-Linie zeichnet. Immer, wenn eine R-Zacke kommt, also ein bestimmter Schwellenwert überschritten wird, soll ein Punkt an der jeweiligen Stelle gezeichnet werden. Danach soll dies 0.5 Sekunden lang nicht mehr geschehen. Der Code dazu : /** * Diese Methode ist fuer das Zeichnen der EKG-Linien zustaendig. */ @Override public void paintComponent(Graphics g) throws IndexOutOfBoundsException { super.paintComponent(g); if(controller.getAktuellesEkg() != null) { floatWerte = controller.getAktuellesEkg().getEkgWerte(); for(int i = 1; i < floatWerte.size(); i++) { if(aufzeichnung) { if(floatWerte.get(i) > grenze) { g.drawLine(i-1, floatWerte.get(i-1).intValue(), i, floatWerte.get(i).intValue()); g.setColor(Color.red); g.fillOval(i-1, floatWerte.get(i-1).intValue(), 8,8); g.setColor(Color.black); } else g.drawLine(i-1, floatWerte.get(i-1).intValue(), i, floatWerte.get(i).intValue()); } else{ g.drawLine(i-1, floatWerte.get(i-1).intValue(), i, floatWerte.get(i).intValue()); } } } } Die zweite if-Bedingung soll, auch wenn sie erfüllt ist, nur alle 0.5 sekunden durchgeführt werden, wenn die Zeit aber noch nicht abgelaufen ist soll die Ausführung des Programms weiterlaufen. Bin nicht so der große Experte was Threads anbetrifft, deshalb vermute ich dass es da eine Möglichkeit gibt, ich aber alleine nicht drauf komme. Habe es schon mit einem Timer / TimerTask versucht, allerdings müsste dafür i als final deklariert werden, was in meinem Fall nicht möglich ist. Hat von euch jemand ne Idee wie ich das lösen könnte ??? Viele Grüße, Rainer Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Wurmi Geschrieben 27. Dezember 2010 Teilen Geschrieben 27. Dezember 2010 (bearbeitet) Hallo, Und zwar habe ich einen Thread, der nach und nach eine EKG-Linie zeichnet. Immer, wenn eine R-Zacke kommt, also ein bestimmter Schwellenwert überschritten wird, soll ein Punkt an der jeweiligen Stelle gezeichnet werden. Danach soll dies 0.5 Sekunden lang nicht mehr geschehen. Ich bin da auch kein Experte, aber in der paintComponent-Methode würde ich diese Bedingung nicht einbauen. Ich würde einen Thread laufen lassen, der die repaint()-Methode aufruft (diese erzeugt dann den Aufruf von paintComponent) nach bestimmten Ereignissen/Bedingungen und der nach dem R-Zacke-Ereignis für 500ms schlafen gelegt wird. Bearbeitet 27. Dezember 2010 von Wurmi Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Rainer Wahnsinn Geschrieben 27. Dezember 2010 Autor Teilen Geschrieben 27. Dezember 2010 hmm...das Ganze sollte wenn möglich schon in der Methode passieren. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Rainer Wahnsinn Geschrieben 27. Dezember 2010 Autor Teilen Geschrieben 27. Dezember 2010 Vielleicht könnte man das Ganze ja auch einfach mit nem boolean Datenfeld machen, dessen Wert alle 500ms zwischen true / false geswiched wird. Aber wie gesacht...kenn mich nicht wirklich mit Threads aus...wo ich im Code genau so nen Thread starte, wie das mit dem wechseln realisiert werden könnte, usw. Wär toll wenn mir da jemand weiter helfen könnte mfg Rainer Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Wurmi Geschrieben 27. Dezember 2010 Teilen Geschrieben 27. Dezember 2010 hmm...das Ganze sollte wenn möglich schon in der Methode passieren. Wie rufst Du denn die paintComponent-Methode auf? Wenn Du selbige nicht explizit mit repaint() aufrufst, wird sie nur bei Änderungen aufgerufen, bei Größenänderungen oder Verschieben des Containers etwa. Der "Takt" zum Neuzeichnen sollte von außen erfolgen, wenn Du so etwas wie Wartezeiten einbauen willst. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Rainer Wahnsinn Geschrieben 27. Dezember 2010 Autor Teilen Geschrieben 27. Dezember 2010 Doch, ich rufe die paintComponent() Methode schon über repaint auf... das Problem bei der Sache ist aber dass die EKG-Kurve beim Starten einer Aufzeichnung langsam durchläuft...also nicht die ganze Kurve auf einmal gezeichnet wird...dafür benutze ich einen Thread. Die Punkte sollen aber zusätzlich gezeichnet werden, wenn ein EKG-Wert über einer bestimmten Schwelle liegt. /** * Malt die EKG-Kurve */ public void paintEkg() { ekgKurve.repaint(); ekgKurve.add(ekgLinie,BorderLayout.CENTER); } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Wurmi Geschrieben 27. Dezember 2010 Teilen Geschrieben 27. Dezember 2010 Wär toll wenn mir da jemand weiter helfen könnte Das versuche ich ja... Oder wartest Du auf einen, der Dir alles auf dem Präsentierteller reicht? Also: 1. Die paintComponent-Methode soll nicht direkt aufgerufen werden, sondern entweder explizit mit repaint() oder durch durch den Swing-Thread (EventQueue) Schau Dir auch das an: Malen in Swing Teil 1: der grundlegende Mechanismus - Byte-Welt Wiki Ich hab mal folgendes probiert, vielleicht hilft das import java.awt.*; import javax.swing.*; class ZZTestPaint extends JFrame { PaintPanel myPanel; int rot = 0; int gruen = 0; int blau = 0; public ZZTestPaint() { super("Test repaint"); myPanel = new PaintPanel(); getContentPane().add( myPanel ); Fred fred = new Fred(); fred.start(); } public static void main(String[] args) { ZZTestPaint form = new ZZTestPaint(); form.setLocation(300, 100); form.setSize(500, 300); form.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); form.setVisible(true); } class Fred extends Thread { boolean increase = true; public void run() { while ( true ) { myPanel.setColor( new Color( rot, gruen, blau ) ); myPanel.repaint(); // System.out.println("Rot = "+rot+" Gruen = "+gruen); try { sleep(2); } catch( InterruptedException e) { } if ( increase ) rot += 5; else rot -= 5; if ( rot > 255 ) { rot = 255; increase = false; } else if ( rot < 0 ) { rot = 0; increase = true; } } } } } class PaintPanel extends JPanel { private Color myColor; public void setColor( Color newColor) { myColor = newColor; } @Override public void paintComponent(Graphics g) { g.setColor( myColor ); g.fillOval(50, 50, 200,200); } } Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Rainer Wahnsinn Geschrieben 27. Dezember 2010 Autor Teilen Geschrieben 27. Dezember 2010 Ich rufe die paintComponent() Methode wie gesagt nicht direkt auf...das passiert alles über paintEkg(). Und ja, ich fände es schön wenn mir jemand, der das Ganze besser beherrscht als ich es tue, einen Beispielcode zur Verfügung stellen könnte...ich sitze jetzt seit über 3 Stunden an dem *******, und hab schon alles mögliche ausprobiert...sonst würde ich nicht in ein Forum schreiben. Dein Beispiel ist zwar nett, hilft mir aber leider nicht wirklich weiter... Mein Problem ist wo im Code ich diesen Thread am besten einbaue...ich möchte es erst einmal gerne in der paintComponent Methode machen, später wenn es einmal funktioniert kann ich es immer noch auslagern. Es müsste doch eigentlich mit einem einfachen switch von einem boolean datenfeld gehen... if(true) male Kreis an EKG-Linie setze 500ms auf false Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Wurmi Geschrieben 27. Dezember 2010 Teilen Geschrieben 27. Dezember 2010 (bearbeitet) Doch, ich rufe die paintComponent() Methode schon über repaint auf... das Problem bei der Sache ist aber dass die EKG-Kurve beim Starten einer Aufzeichnung langsam durchläuft...also nicht die ganze Kurve auf einmal gezeichnet wird...dafür benutze ich einen Thread. Zuerst hast Du gesagt, daß Du kein großer Experte beim Thema Threads bist (das bin ich auch nicht) und dann sagst Du, das Du Dich eigentlich kaum auskennst damit? Was stimmt jetzt? Zeig mal die Methode run() des Threads, was die macht. Sonst kann ich Dir noch viele "nette" Beispiele quoten, ohne das Du weiterkommst. Das Umsetzen und Mitdenken mußt Du selber machen. Ich kenne Deinen Code nicht, soll ich Dir sagen "setz den Code in Zeile 345 ein"? Bearbeitet 27. Dezember 2010 von Wurmi Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Rainer Wahnsinn Geschrieben 27. Dezember 2010 Autor Teilen Geschrieben 27. Dezember 2010 public void starteAufzeichnung() { if(aktuellerPatient != null) { aufzeichnungAktiv = true; ekgDatenPanel.reset(); LogdateiAnzeige.erzeugeLogEintrag(AUFZEICHNUNG_GESTARTET,sprache); logger.log(Level.INFO,AUFZEICHNUNG_GESTARTET); new Thread(new Runnable() { @Override public void run() { try { aufzeichnungStarten(); } catch (IOException e) { LogdateiAnzeige.erzeugeLogEintrag(FEHLERMELDUNG,sprache); logger.log(Level.INFO,FEHLERMELDUNG); } }}).start(); } else{ LogdateiAnzeige.erzeugeLogEintrag(PATIENT_LADEN_BEVOR_AUFZEICHNUNG,sprache); logger.log(Level.INFO,PATIENT_LADEN_BEVOR_AUFZEICHNUNG); } } Und : private void aufzeichnungStarten() throws IOException { VirtuellerEKGRekorder ekgRecorder = new VirtuellerEKGRekorder(); EKG randomEkg = new EKG(); setAktuellesEkg(randomEkg); ekgRecorder.aufzeichnungStarten(); werte = new ArrayList<Float>(); werteGefiltert = new ArrayList<Float>(); while(aufzeichnungAktiv == true) { naechsterWert = ekgRecorder.getNaechsterWert(); naechsterWertGefiltert = ekgRecorder.getNaechsterWertGefiltert(); werte.add(naechsterWert); // werte.add(naechsterWertGefiltert); //R-ZACKEN SICHTBAR !!! werteGefiltert.add(naechsterWertGefiltert); aktuellesEkg.setEkgWerte(werte); ekgBildPanel.paintEkg(); ekgBildPanel.setPreferredSizeOfPanel(werte.size()); } ekgRecorder.aufzeichnungBeenden(); aktuellesEkg.setAbtastIntervall(ekgRecorder.getAbtastIntervall()); aktuellesEkg.setAnzahlWerte(werte.size()); aktuellesEkg.setFilterung(false); aktuellesEkg.setPatientenID(aktuellerPatient.getId()); aktuellesEkg.setPhysikalischesMaximum(ekgRecorder.getPhysikalischesMaximum()); aktuellesEkg.setPhysikalischesMinimum(ekgRecorder.getPhysikalischesMinimum()); } Im Aufruf "ekgBildPanel.paintEkg();" steckt dann die repaint Methode, die paintComponent aufruft Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Rainer Wahnsinn Geschrieben 27. Dezember 2010 Autor Teilen Geschrieben 27. Dezember 2010 Das will ich doch auch gar nicht... Ich habe ja am Ende nur noch nach einer Möglichkeit gefragt, wie ich zeitabhängig ein boolean Datenfeld auf true bzw false switchen kann...ich gehe nämlich davon aus, dass damit mein Problem gelöst wäre. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Wurmi Geschrieben 27. Dezember 2010 Teilen Geschrieben 27. Dezember 2010 Das will ich doch auch gar nicht... Ich habe ja am Ende nur noch nach einer Möglichkeit gefragt, wie ich zeitabhängig ein boolean Datenfeld auf true bzw false switchen kann...ich gehe nämlich davon aus, dass damit mein Problem gelöst wäre. Ich habe mir den Code kurz angesehen. Wenn Du den Thread AUSSCHLIESSLICH dazu verwendest, eine Methode zu starten, brauchst Du ihn nicht. Lösung: Lege alles, was in der Methode aufzeichnungStarten() steht, in die Methode run() des Threads. Dann kannst Du darin die Methode sleep (beim Zutreffen irgendeiner Bedingung) aufrufen und mußt dabei nicht aktiv warten. Den Rest mußt Du dir selber erarbeiten. Deine Hausaufgaben gemacht bekommst Du hier nicht. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.