Sauberes Faden mit awt Graphics

javampir

Bekanntes Mitglied
Guten Tag alle zusammen,
hab mir jetzt in den Kopf gesetzt, meine Programme ein bisschen dynamischer aussehen zu lassen. Ich arbeite hierbei viel mit awt Graphics und möchte Farbübergänge (z.B. wenn der user mit der maus über ein Element geht) machen. Mein Testcode schaut so aus:
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Gui extends JPanel implements MouseMotionListener {
    
    public static void main(String[] args) {
        new Gui();
    }
    
    JFrame f = new JFrame("Fade");
    int x = 20, y = 20, w = 100, h = 100;
    volatile Color col = Color.black;
    boolean in = false;
    
    public Gui() {
        super();
        setBackground(Color.white);
        addMouseMotionListener(this);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.setVisible(true);
    }
    
    private boolean over(int ix, int iy) {
        if(ix >= x && ix <= x + w && iy >= y && iy <= y + h) {
            return true;
        }
        return false;
    }
    
    private void fadeIn() {
        new Thread(new Runnable() {
            @Override
            public synchronized void run() {
                if(!in) {
                    int r = 0;
                    for(int i = 0; i < 127; i++) {
                        r += 2;
                        col = new Color(r, 0, 0);
                        repaint();
                        try {
                            Thread.sleep(30);
                        } catch (Exception ex) {}
                    }
                    in = true;
                }
            }
        }).start();
    }
    
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setColor(col);
        g.fillRect(x, y, w, h);
    }
    
    @Override
    public void mouseMoved(MouseEvent e) {
        if(over(e.getX(), e.getY())) {
            fadeIn();
        }
    }
    
    @Override
    public void mouseDragged(MouseEvent e) {
        mouseMoved(e);
    }
}

allerdings hat man ein sehr unruhiges Flackern wenn man mit der Maus über das Element geht. Es sieht immer so aus, wie wenn es kurz dunkler werden würde, bevor es wieder hell wird.
Liegt es einfach an meiner sleep-zeit und meiner step-größe, hab ich irgendeinen groben performance-schnitzer oder gehts einfach nicht besser?
Gruß,
javampir
 

Qler

Mitglied
Hallo javampir,

so wie es aussieht startest du immer einen neuen thread, solange deine variable in noch nicht auf true gesetzt ist.
in wird jedoch erst auf true gesetzt, wenn der farb-setz-thread die gesamte for-schleife durchlaufen hat.
D.h., dass du jedes mal einen neuen thread startest, solange der erste thread noch nicht fertig ist, und jeder dieser gestarteten threads startet wieder bei der ersten farbe des fade-in vorgangs.

quick fix:

in = true;

bevor die for-schleife durchlaufen wird.

hoffe ich konnte dir helfen!
 

Ruzmanz

Top Contributor
Die Erklärung von Qler ist richtig, die Lösung gefällt mir nicht. Synchronisation ist teuer. Java unterstützt out of the box nur eine Maus, deshalb (und aufgrund ein paar anderen Dingen) wird die Methode mouseMoved niemals parallel ausgeführt. Folgende Lösung ist deutlich besser:

Java:
@Override
public void mouseMoved(MouseEvent e) {
  if (over(e.getX(), e.getY()) && !in) {
    in = true;
    fadeIn();
  }
}

private void fadeIn() {
  new Thread(new Runnable() {
    @Override
    public void run() {
      int r = 0;
      for (int i = 0; i < 127; i++) {
        r += 2;
        col = new Color(r, 0, 0);
        repaint();
        try {
          Thread.sleep(30);
        } catch (Exception ex) {
          ex.printStackTrace();
        }
      }
    }
  }).start();
}
 
Zuletzt bearbeitet von einem Moderator:

javampir

Bekanntes Mitglied
hi,
danke für eure Antworten, aber so richtig schön sieht es erst aus, wenn ich r immer nur um 1 erhöhe und dann 30ms warte (das ist zu lang, die animation ist dann länger als 7650ms = über siebeneinhalb sekunden). Ansonsten ist das problem wie vorher.
javampir
 

Ruzmanz

Top Contributor
Dass der Fehler weiterhin auftritt ist ausgeschlossen. Nochmal der Code ...

Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Gui extends JPanel implements MouseMotionListener {

	public static void main(String[] args) {
		new Gui();
	}

	JFrame f = new JFrame("Fade");
	int x = 20, y = 20, w = 100, h = 100;
	volatile Color col = Color.black;
	boolean in = false;

	public Gui() {
		super();
		setBackground(Color.white);
		addMouseMotionListener(this);
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.add(this);
		f.setExtendedState(JFrame.MAXIMIZED_BOTH);
		f.setVisible(true);
	}

	private boolean over(int ix, int iy) {
		if (ix >= x && ix <= x + w && iy >= y && iy <= y + h) {
			return true;
		}
		return false;
	}

	@Override
	public void mouseMoved(MouseEvent e) {
		if (over(e.getX(), e.getY()) && !in) {
			in = true;
			fadeIn();
		}
	}

	private void fadeIn() {
		new Thread(new Runnable() {
			@Override
			public void run() {
				int r = 0;
				for (int i = 0; i < 127; i++) {
					r += 2;
					col = new Color(r, 0, 0);
					repaint();
					try {
						Thread.sleep(30);
					} catch (Exception ex) {
						ex.printStackTrace();
					}
				}
			}
		}).start();
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.setColor(col);
		g.fillRect(x, y, w, h);
	}

	@Override
	public void mouseDragged(MouseEvent e) {
		mouseMoved(e);
	}
}

Meine Intention war es nicht die Animation zu ändern ... wenn sie dir zu lange dauert, musst du sie ändern :bahnhof:
 

javampir

Bekanntes Mitglied
hi,
ja, danke soweit hatte ich es verstanden und auch schon abgeändert. aber wie gesagt, es sieht immer noch unruhig aus, also etwas abgehackt und stufenweise. wenn ich die sleep-zeit heruntersetze, schmeißt er wahrscheinlich ein paar repaints raus, und wenn ich r nicht um 1 oder 2, sondern um, sagen wir mal 4, erhöhe hat man ein unangenehmes Rucken drin. Vielleicht wirkt es auch nur so, weil es eine relativ große zusammenhängende fläche ist und es würde bei linien nicht auffallen, aber schön sieht es trotzdem nicht aus.
Wenn noch jemand eine idee hat...
javampir
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Sauberes Rendern ? AWT, Swing, JavaFX & SWT 12
P Swing Roter Faden beim Applet GUI Programmieren AWT, Swing, JavaFX & SWT 2
F (Split)Panel faden bei automatischer Größenanderung AWT, Swing, JavaFX & SWT 2
N Graphics Objekte scalen mit Veränderung des Bildschirms AWT, Swing, JavaFX & SWT 19
T Bild in ein graphics füllen AWT, Swing, JavaFX & SWT 2
volcanos Scrollen: JScrollPane mit Graphics g und Java-Fonts extends Frame ? AWT, Swing, JavaFX & SWT 5
DonBronson Java Graphics bewegbar machen (Drag&Drop) AWT, Swing, JavaFX & SWT 3
ExceptionOfExpectation MouseListener-Objekte zu den Graphics-Objekten einfügen AWT, Swing, JavaFX & SWT 3
R AWT Graphics initialisieren AWT, Swing, JavaFX & SWT 15
P JPanle, JFrame und Graphics AWT, Swing, JavaFX & SWT 2
R 2D-Grafik PNG Bild per Graphics auf JPanel AWT, Swing, JavaFX & SWT 9
B Graphics to Image AWT, Swing, JavaFX & SWT 3
T Swing Graphics auf Panel AWT, Swing, JavaFX & SWT 2
B Graphics -> Graphics2D etwas zu beachten? AWT, Swing, JavaFX & SWT 8
P ActionListener Graphics Einbauen AWT, Swing, JavaFX & SWT 0
J Swing Problem mit Graphics Methode AWT, Swing, JavaFX & SWT 4
R Swing Bewegung eines Graphics Objektes innerhalb eines JPanels funktioniert nicht richtig AWT, Swing, JavaFX & SWT 2
V Netbeans: TabbedPane, ScrollPane und Graphics AWT, Swing, JavaFX & SWT 4
V Graphics g - drawOval problem mit background AWT, Swing, JavaFX & SWT 1
M Graphics.fillOval AWT, Swing, JavaFX & SWT 1
D 2D-Grafik Inhalt eines Graphics in anderes Graphics zeichnen.... AWT, Swing, JavaFX & SWT 3
X AWT Text der mit Graphics "drawString(...)" geschreiben wurde wieder löschen. AWT, Swing, JavaFX & SWT 6
C Zwei Ebenen in Graphics ? AWT, Swing, JavaFX & SWT 0
C Graphics Objekt in Zeitschleife zeichnen AWT, Swing, JavaFX & SWT 4
D Frage zu JFrame und Graphics AWT, Swing, JavaFX & SWT 4
I JavaFX Graphics Performance AWT, Swing, JavaFX & SWT 2
vodkaz Graphics aufrufen AWT, Swing, JavaFX & SWT 4
V 2D-Grafik Frage zum Graphics Objekt AWT, Swing, JavaFX & SWT 2
P 2D-Grafik NPE beim Zeichnen auf Graphics g AWT, Swing, JavaFX & SWT 8
M Graphics.drawImage von unten nach oben abbilden lassen AWT, Swing, JavaFX & SWT 6
F Probleme mit (Graphics g) II AWT, Swing, JavaFX & SWT 4
F Probleme mit (Graphics g) AWT, Swing, JavaFX & SWT 3
M JFrame Graphics.drawString Problem AWT, Swing, JavaFX & SWT 11
I Rechteck eines Graphics eines JPanels in einem anderen JPanel anzeigen AWT, Swing, JavaFX & SWT 7
antonbracke Multiplayer Shooter- Wie geht das mit Canvas & Graphics AWT, Swing, JavaFX & SWT 6
R Ankerpunkt bei Graphics AWT, Swing, JavaFX & SWT 3
R Fließende Bewegung von Graphics AWT, Swing, JavaFX & SWT 6
T AWT Graphics G Kein Text erscheint warum? AWT, Swing, JavaFX & SWT 12
L Graphics.drawImage() - Output-Größe entspricht nicht Parametern AWT, Swing, JavaFX & SWT 10
L Border verschwindet durch Graphics.drawImage() AWT, Swing, JavaFX & SWT 4
Furtano AWT paint braucht ein Graphics Objekt ? AWT, Swing, JavaFX & SWT 2
P "Graphics" wird nicht angezeigt AWT, Swing, JavaFX & SWT 11
L Graphics Objekt - aus anderer Klasse aufrufen / übergeben AWT, Swing, JavaFX & SWT 5
B Swing Zeilenumbruch in Graphics AWT, Swing, JavaFX & SWT 20
T Graphics zeichnet nicht AWT, Swing, JavaFX & SWT 2
T Applet graphics - zeichnen funktioniert nicht AWT, Swing, JavaFX & SWT 14
R Graphics-Object speichern AWT, Swing, JavaFX & SWT 4
S Zeichnen mit java.awt.Graphics AWT, Swing, JavaFX & SWT 6
D Graphics zeichnen AWT, Swing, JavaFX & SWT 6
M Graphics auf JFrame Koordinatensystem AWT, Swing, JavaFX & SWT 3
T Graphics Ersetzend Zeichnen AWT, Swing, JavaFX & SWT 6
S Unterscheiden ob ein Graphics-Objekt von einer JComponent oder einem BufferedImage kommt..? AWT, Swing, JavaFX & SWT 4
Developer_X Swing Auf ein BufferedImage mit Graphics/Graphics2D zeichnen AWT, Swing, JavaFX & SWT 6
D Erzeugen eines leeren Graphics-Objektes AWT, Swing, JavaFX & SWT 7
B Anzeigefehler in GridBagLayout durch paintComponent(Graphics g) AWT, Swing, JavaFX & SWT 3
A AWT AWT Panelfenster mit Graphics kombinieren AWT, Swing, JavaFX & SWT 7
T Graphics Parameterübergabe AWT, Swing, JavaFX & SWT 3
K Graphics.drawImage() sehr schnell AWT, Swing, JavaFX & SWT 5
M Graphics-Objekt aktualisiert sich nicht AWT, Swing, JavaFX & SWT 2
N paintComponent für Graphics ansprechen AWT, Swing, JavaFX & SWT 2
M Graphics.drawImage verlangsamt sich plötzlich AWT, Swing, JavaFX & SWT 15
S Swing AWT (graphics (g)) AWT, Swing, JavaFX & SWT 27
E einfache Frage zu paintComponent und Graphics AWT, Swing, JavaFX & SWT 7
B Swing Tooltips auf Graphics AWT, Swing, JavaFX & SWT 8
Ä Graphics-Komponente auf JPanel wird nicht angezeigt AWT, Swing, JavaFX & SWT 4
S Applet mit Graphics dynamisch vergrößern AWT, Swing, JavaFX & SWT 3
T Dialog ohne Frame, direktes paint in graphics AWT, Swing, JavaFX & SWT 5
T Swing Component in Graphics zeichnen AWT, Swing, JavaFX & SWT 4
J getFontMetrics außerhalb von paint(Graphics g) AWT, Swing, JavaFX & SWT 8
E Problem bzw. Sinn von Graphics / Graphics Context AWT, Swing, JavaFX & SWT 21
S Weder ActionListener noch Graphics wollen so recht AWT, Swing, JavaFX & SWT 3
F Methode drawOval(int,int,int,int) von graphics AWT, Swing, JavaFX & SWT 4
G Graphics Objekte in AWT Container einfügen AWT, Swing, JavaFX & SWT 2
S Mit Graphics g ins Fenster zeichnen AWT, Swing, JavaFX & SWT 4
G Graphics - Raute AWT, Swing, JavaFX & SWT 3
G "pinseldicke" bei Graphics? AWT, Swing, JavaFX & SWT 2
G Graphics.drawImage() AWT, Swing, JavaFX & SWT 6
D Methode Graphics g klassenübergreifend nutzen. AWT, Swing, JavaFX & SWT 3
W java.lang.NoClassDefFoundError: org/eclipse/swt/graphics/Dev AWT, Swing, JavaFX & SWT 1
B Graphics und Canvas - Problem AWT, Swing, JavaFX & SWT 2
H eigene paintComponent(Graphics) kommt mit rezise nicht klar AWT, Swing, JavaFX & SWT 6
T Transparenz bei Graphics AWT, Swing, JavaFX & SWT 9
L Graphics AWT, Swing, JavaFX & SWT 37
B JPanel#paintComponent(Graphics g) << flackert oO AWT, Swing, JavaFX & SWT 3
Y Problem mit der Referenz eines Graphics-Objekts AWT, Swing, JavaFX & SWT 5
O Graphics erstellt Componente scheinbar nicht richtig AWT, Swing, JavaFX & SWT 23
G 2x Graphics in einer paint() miteinander verbinden AWT, Swing, JavaFX & SWT 11
K Gutes Buch gesucht (Graphics Only) Kennt jemand eins? AWT, Swing, JavaFX & SWT 5
K Graphics-Objekt zeichnet nicht alle Bilder AWT, Swing, JavaFX & SWT 3
J Einmal gleichzeitig auf zwei Graphics malen? AWT, Swing, JavaFX & SWT 5
E Image, Graphics, verzögert zeichnen AWT, Swing, JavaFX & SWT 2
N Graphics Objekt "puffern" AWT, Swing, JavaFX & SWT 7
H neuzeichnen von graphics nach minimierung oder ähnlichem AWT, Swing, JavaFX & SWT 10
G SWT Graphics Zeichnung neu laden AWT, Swing, JavaFX & SWT 13
G SWT Graphics GC Problem AWT, Swing, JavaFX & SWT 6
M Abstrakte Graphics Klasse erzeugen AWT, Swing, JavaFX & SWT 2
H awt Graphics und Image selbermachen ? AWT, Swing, JavaFX & SWT 12
D Image aus Graphics erstellen? AWT, Swing, JavaFX & SWT 2
R Graphics Objekt ändern AWT, Swing, JavaFX & SWT 11
raptorrs J2D graphics, sind 500px immer 500 px AWT, Swing, JavaFX & SWT 2

Ähnliche Java Themen

Neue Themen


Oben