flimmern

Status
Nicht offen für weitere Antworten.
J

javaner

Gast
hallo

wir sollten das flimmern des digitalen datums und der digitalen zeit weg haben. kann uns da jemand weiter helfen?

vielen dank

--------------------------------
Code:
import java.awt.*;
import java.applet.*;
import java.util.*;

public class AnalogUhr extends Applet {

    public void init() {
        setBackground(new Color(255,255,255));
    }

    Image time;
    Graphics2D gtime;

    Calendar date;

    int x=125, y=100; // Zentrum und Radius

    public void paint(Graphics g) {

        // Uhr Darstellen 
        if (time==null) {
            time=createImage(this.getSize().width, this.getSize().height);
            gtime=(Graphics2D)time.getGraphics();
        }
        //Uhr neu zeichnen wenn sich was ändert zeit korrekt darestellen//
       gtime.clearRect(0,0,this.getSize().width, this.getSize().height);


        gtime.setColor(new Color(0,0,0));
        gtime.drawOval(x-2,x-2,4,4);

        // Striche bei 3, 6, 9 und 12 Uhr erstellen
        for (int i=0;i<4;i++) {
            gtime.drawLine(
                x+(int)((y-7)*Math.cos(Math.toRadians(90*i))),
                x+(int)((y-7)*Math.sin(Math.toRadians(90*i))),
                x+(int)(y*Math.cos(Math.toRadians(90*i))),
                x+(int)(y*Math.sin(Math.toRadians(90*i))));
        }
        // Striche bei jeder Stunde erstellen
        for (int i=0;i<12;i++) {
            gtime.drawLine(
                x+(int)((y-5)*Math.cos(Math.toRadians(30*i))),
                x+(int)((y-5)*Math.sin(Math.toRadians(30*i))),
                x+(int)(y*Math.cos(Math.toRadians(30*i))),
                x+(int)(y*Math.sin(Math.toRadians(30*i))));
        }
        //akutelle zeit implementieren//
        date = new GregorianCalendar();

        int hours = date.get(Calendar.HOUR_OF_DAY);
        int minutes = date.get(Calendar.MINUTE);
        int seconds = date.get(Calendar.SECOND);
        int day = date.get(Calendar.DATE);
        int month = (date.get(Calendar.MONTH))+1;
        int year = date.get(Calendar.YEAR);


        // Stundenzeiger
        gtime.drawLine(
            x,x,x+(int)(60*Math.cos(Math.toRadians(hours%12*30+minutes/2.0-90))),
            x+(int)(60*Math.sin(Math.toRadians(hours%12*30+minutes/2.0-90))));

        // Minutenzeiger
        gtime.drawLine(
            x,x,x+(int)(85*Math.cos(Math.toRadians(minutes*6-90))),
            x+(int)(85*Math.sin(Math.toRadians(minutes*6-90))));

        // Sekundenzeiger
        gtime.setColor(new Color(170,170,170));
        gtime.drawLine(
            x,x,x+(int)(90*Math.cos(Math.toRadians(seconds*6-90))),
            x+(int)(90*Math.sin(Math.toRadians(seconds*6-90))));
       
        g.drawImage (time, 0, 0, this);

        repaint();
        
        //anzeige datum aktuelle uhrzeit
        
        g.drawString(""+day+". "+month+". "+year, 65,260);
        g.drawString(""+hours+". "+minutes+". "+seconds, 125,260);
    }
     // überschreiben / updaten//
           public void update(Graphics g) {paint(g);}


}

EDIT: Code-Tags eingefügt -AlArenal
 

The_S

Top Contributor
Versuchs mal mit DoubleBuffering.

Also zuerst in ein Image zeichnen und dieses Image dann anzeigen lassen
 

Leroy42

Top Contributor
Hobbit_Im_Blutrausch hat gesagt.:
Versuchs mal mit DoubleBuffering.
Das macht Javaner ja bereits.
javaner hat gesagt.:
Code:
public class AnalogUhr extends Applet {
    public void paint(Graphics g) {
        if (time==null) {
            time=createImage(this.getSize().width, this.getSize().height);
            gtime=(Graphics2D)time.getGraphics();
        }
       gtime.clearRect(0,0,this.getSize().width, this.getSize().height);
       ...
        g.drawImage (time, 0, 0, this);
        repaint();
        ...        
   }

Ich vermute, daß das Problem woanders liegt.
Innerhalb der paint-Methode wird repaint aufgerufen, was den EDT
veranlaßt, sofort nach Beendigung der paint-Methode diese
erneut aufzurufen. Abgesehen davon, daß das den Prozessor zu 100% auslastet(*),
könnte es auch das Flimmern erzeugen.

Die richtige Vorgehensweise ist auf jeden Fall, die Anwendung schlafen
zu legen, aber auf keinen Fall innerhalb der paint-Methode :noe:
sondern von außerhalb des EDT.

Code:
public void init() {
  ...
  new Thread(new Runnable() {
    public void run() {
      while (true) {
        try {Thread.sleep(500);} catch (InterruptedException e) {}
        repaint();
    }
  }}).start();
500 ms sollten ausreichend sein; es sei denn, du willst z.B. auch einen Zeiger
für Zehntelsekunden darstellen.

(*) Wenn du unter WinDoof arbeitest, mach doch mal, während der Laufzeit
des derzeitigen Applets, den Taskmanager auf, suche nach dem Browser/appletviewer
und gönne ihm mal ein wenig Echtzeit-Priorität.

Beschwer dich nachher aber nicht, wenn dein Mauszeiger etwas langsam reagiert :cool:
 
J

javaner

Gast
1mal besten dank für die tips. leider funktioniert es irgendwie immernoch nicht. bin villeicht etwas zu *blöde* ;-)

die uhr selber flimmert nicht. nur die anzeige des datums und der uhrzeit digital
 

Leroy42

Top Contributor
Hast du meinen Vorschlag überhaupt eingebaut?
Und den repaint())-Aufruf aus paint() herausgenommen? :meld:

Also bei mir läuft dein Applet tadellos :D
 

SebiB90

Top Contributor
Hobbit_Im_Blutrausch hat gesagt.:
Leroy42 hat gesagt.:
Hobbit_Im_Blutrausch hat gesagt.:
Versuchs mal mit DoubleBuffering.
Das macht Javaner ja bereits.

OK, nächstes mal lese ich aufmerksamer :oops:
habe ich auch, also du bist nicht allein^^
aber was überschreibt javaner auch die update methode wenn da eh nur paint() aufgerufen wird, wird ja sowieso und da normalerweise in update die doublebuffering eingebaut wird und da es dann nicht drin war dachte ich gibs kein, ich denke dir ging es genauso.

edit:
aber die digitale anzeige wird nicht doublebuffert, da wird auf g und nicht gtime drawString angewendet außerdem geschieht dies nach repaint() auruf, das sollte auch geändert werden.
 

The_S

Top Contributor
Nee, ich hab einfach nur Flimmern und paint gelesen. Dann habsch mir gedacht, der Kerle macht bestimmt kein DoubleBuffering und habs halt mal auf gut Glück hingeschrieben. Außerdem war ich in Eile ;)
 

Leroy42

Top Contributor
SebiB90 hat gesagt.:
aber was überschreibt javaner auch die update methode wenn da eh nur paint() aufgerufen wird, wird ja sowieso und da normalerweise in update die doublebuffering eingebaut wird...
Zumindest update mußte überschrieben werden da es default-mäßig ja erst mal den
Hintergrund zeichnet.

Da jetzt nur noch paint aufgerufen wird, hätte man sich natürlich
das Überschreiben der paint-Methode sparen, und den Code
gleich mit in update übernehmen können.

Ist halt 'ne Frage des Geschmacks, ich persönlich ziehe es auch vor
die Zeichnungen innerhalb der paint-Methode zu belassen.
 

L-ectron-X

Gesperrter Benutzer
So bitt'schön. DoubleBuffering und einen Zeit-Thread implementiert und damit das Flimmern und das repaint()-Problem behoben.
Code:
import java.awt.*;
import java.applet.*;
import java.util.*;
import java.text.*;

public class AnalogUhr extends Applet {
    private Calendar calendar;
    private DateFormat formatter;
    private int hours, minutes, seconds, day, month, year;
    private String timeString;
    
    private Image offscreenImage;
    private Graphics offscreenGraphics;
    
    private int x=125, y=100; // Zentrum und Radius
    
    private Time time; // ein Zeit-Thread
    
    public void init() {
        setBackground(Color.WHITE);
        calendar = Calendar.getInstance();
        time = new Time(this);
        offscreenImage = createImage(this.getSize().width, this.getSize().height);
        offscreenGraphics = offscreenImage.getGraphics();
        formatter = new SimpleDateFormat("MM.dd.yyyy   HH:mm:ss");
    }
    
    public void start() {
        if(time == null)
            time = new Time(this);

        time.start();
    }
    
    public void stop() {
        time.interrupt();
        time = null;
    }
    
    public void setTime(Date date) {
        timeString = formatter.format(date);
        calendar.setTime(date);
        hours = calendar.get(Calendar.HOUR_OF_DAY);
        minutes = calendar.get(Calendar.MINUTE);
        seconds = calendar.get(Calendar.SECOND);
        day = calendar.get(Calendar.DATE);
        month = calendar.get(Calendar.MONTH)+1;
        year = calendar.get(Calendar.YEAR);
       
        repaint();
    }

    public void paint(Graphics g) {
      if (offscreenImage != null)
         g.drawImage(offscreenImage, 0, 0, this);
    }
    
    // überschreiben / updaten//
    public void update(Graphics g) { //Uhr neu zeichnen wenn sich was ändert zeit korrekt darstellen
        offscreenGraphics.clearRect(0,0,this.getSize().width, this.getSize().height);

        offscreenGraphics.setColor(Color.BLACK);
        offscreenGraphics.drawOval(x-2,x-2,4,4);

        // Striche bei 3, 6, 9 und 12 Uhr erstellen
        for (int i=0;i<4;i++) {
            offscreenGraphics.drawLine(
                x+(int)((y-7)*Math.cos(Math.toRadians(90*i))),
                x+(int)((y-7)*Math.sin(Math.toRadians(90*i))),
                x+(int)(y*Math.cos(Math.toRadians(90*i))),
                x+(int)(y*Math.sin(Math.toRadians(90*i))));
        }
        // Striche bei jeder Stunde erstellen
        for (int i=0;i<12;i++) {
            offscreenGraphics.drawLine(
                x+(int)((y-5)*Math.cos(Math.toRadians(30*i))),
                x+(int)((y-5)*Math.sin(Math.toRadians(30*i))),
                x+(int)(y*Math.cos(Math.toRadians(30*i))),
                x+(int)(y*Math.sin(Math.toRadians(30*i))));
        }

        // Stundenzeiger
        offscreenGraphics.drawLine(
            x,x,x+(int)(60*Math.cos(Math.toRadians(hours%12*30+minutes/2.0-90))),
            x+(int)(60*Math.sin(Math.toRadians(hours%12*30+minutes/2.0-90))));

        // Minutenzeiger
        offscreenGraphics.drawLine(
            x,x,x+(int)(85*Math.cos(Math.toRadians(minutes*6-90))),
            x+(int)(85*Math.sin(Math.toRadians(minutes*6-90))));

        // Sekundenzeiger
        offscreenGraphics.setColor(Color.GRAY);
        offscreenGraphics.drawLine(
            x,x,x+(int)(90*Math.cos(Math.toRadians(seconds*6-90))),
            x+(int)(90*Math.sin(Math.toRadians(seconds*6-90))));

        //anzeige datum aktuelle uhrzeit
        offscreenGraphics.drawString(timeString, 65,260);

        // Offscreen-Image auf die Appletfläche kopieren
        g.drawImage(offscreenImage, 0, 0, this);
    }
}

Code:
import java.util.*;

public class Time extends Thread {
   private AnalogUhr uhr;
   
   public Time(AnalogUhr uhr) {
      this.uhr = uhr;
   }
   
   public void run() {
      while(!isInterrupted()) {
         uhr.setTime(new Date());
         try {
            Thread.sleep(1000);
         }
         catch(InterruptedException e) {
            interrupt();
         }
      }
   }
}
 
J

javaner

Gast
ja und wo muss ich jetzt das einbauen?? :bahnhof:

kann mir nicht jemand den ganzen code wieder zusammen bauen, damit ich ihn nur noch übernehmen muss? :?

das wäre :toll:
 

Leroy42

Top Contributor
:shock: :shock: :shock:

Also ich hatte dir doch am Freitag genau beschrieben wo es einzubauen ist
und daß es funktioniert.

Jetzt habe ich mir die Mühe gemacht auch Lectron's so wie er ist
zu nehmen und auch der läuft auf Anhieb, ohne Änderungen, tadellos.
???:L

Brauchst du jetzt Unterstützung wie du den Code aus dieser HTML-Seite herauskopiert
und in deine Java-Datei eingefügt bekommst oder was?
:bae:
 

L-ectron-X

Gesperrter Benutzer
javaner hat gesagt.:
ja und wo muss ich jetzt das einbauen?? :bahnhof:

kann mir nicht jemand den ganzen code wieder zusammen bauen, damit ich ihn nur noch übernehmen muss? :?

das wäre :toll:
Das ist der fertige Quellcode, mehr musst du nicht machen.
Kompiliere das Ganze am besten mit dem JDK 1.1.8 oder dem SDK 1.4.x mit der Option -target 1.1 und baue eine passende HTML-Seite, in der du per Applet-Tag das Applet einbaust. Fertig.
 
J

javaner

Gast
ja besten dank erstmals. das problem ist eben das ist eine schularbeit. der lehrer bringt das flimmern auch nicht raus. und der so wie der code von l-ectron-x geändert wurde hatten wir das noch gar nicht.. (das ist bis jetzt das "schwierigste" was wir programiierten... ;-) variablentechnisch usw und sofort. und wenn ich dan so die arbeit abgeben muss ist es schon ein wenig verwirrend. leroy42 köntest du mir bitte deine variante mal vervollständigen mit dem thread usw. wäre dir echt dankbar.

danke und gruss javaner
 

Leroy42

Top Contributor
Hast Glück, daß ich noch kein Frühjahrsputz gemacht habe :)

Code:
import java.awt.*;
import java.applet.*;
import java.util.*;

public class AnalogUhr extends Applet {
	Image time;
	Graphics2D gtime;
	Calendar date;
	int x=125, y=100; // Zentrum und Radius

    public void init() {
		setBackground(new Color(255,255,255));
		new Thread(new Runnable() {
			public void run() {
				while (true) {
					try {Thread.sleep(500);} catch (InterruptedException e) {}
					repaint();
				}
		}}).start();    }
		

	public void paint(Graphics g) {
		// Uhr Darstellen
		if (time==null) {
            time=createImage(this.getSize().width, this.getSize().height);
            gtime=(Graphics2D)time.getGraphics();
        }
        //Uhr neu zeichnen wenn sich was ändert zeit korrekt darestellen//
       gtime.clearRect(0,0,this.getSize().width, this.getSize().height);


        gtime.setColor(new Color(0,0,0));
        gtime.drawOval(x-2,x-2,4,4);

        // Striche bei 3, 6, 9 und 12 Uhr erstellen
        for (int i=0;i<4;i++) {
            gtime.drawLine(
                x+(int)((y-7)*Math.cos(Math.toRadians(90*i))),
                x+(int)((y-7)*Math.sin(Math.toRadians(90*i))),
                x+(int)(y*Math.cos(Math.toRadians(90*i))),
                x+(int)(y*Math.sin(Math.toRadians(90*i))));
        }
        // Striche bei jeder Stunde erstellen
        for (int i=0;i<12;i++) {
            gtime.drawLine(
                x+(int)((y-5)*Math.cos(Math.toRadians(30*i))),
                x+(int)((y-5)*Math.sin(Math.toRadians(30*i))),
                x+(int)(y*Math.cos(Math.toRadians(30*i))),
                x+(int)(y*Math.sin(Math.toRadians(30*i))));
        }
        //akutelle zeit implementieren//
        date = new GregorianCalendar();

        int hours = date.get(Calendar.HOUR_OF_DAY);
        int minutes = date.get(Calendar.MINUTE);
        int seconds = date.get(Calendar.SECOND);
        int day = date.get(Calendar.DATE);
        int month = (date.get(Calendar.MONTH))+1;
        int year = date.get(Calendar.YEAR);


        // Stundenzeiger
        gtime.drawLine(
            x,x,x+(int)(60*Math.cos(Math.toRadians(hours%12*30+minutes/2.0-90))),
            x+(int)(60*Math.sin(Math.toRadians(hours%12*30+minutes/2.0-90))));

        // Minutenzeiger
        gtime.drawLine(
            x,x,x+(int)(85*Math.cos(Math.toRadians(minutes*6-90))),
            x+(int)(85*Math.sin(Math.toRadians(minutes*6-90))));

        // Sekundenzeiger
        gtime.setColor(new Color(170,170,170));
        gtime.drawLine(
            x,x,x+(int)(90*Math.cos(Math.toRadians(seconds*6-90))),
            x+(int)(90*Math.sin(Math.toRadians(seconds*6-90))));

        g.drawImage (time, 0, 0, this);


        //anzeige datum aktuelle uhrzeit

        g.drawString(""+day+". "+month+". "+year, 65,260);
        g.drawString(""+hours+". "+minutes+". "+seconds, 125,260);
    }
     // überschreiben / updaten//
           public void update(Graphics g) {paint(g);}


}
 
J

javaner

Gast
danke vielmals. hat bestens geklappt. begreiffe jetzt dir ganze sache :-D schönes wochenende... gruss
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Gif Bilder flimmern Java Basics - Anfänger-Themen 10
B Flimmern Java Basics - Anfänger-Themen 8

Ähnliche Java Themen

Neue Themen


Oben