Scrollen in Schleife - repaint() zündet nicht

Pius Hermit

Erfahrenes Mitglied
Hallo Leute,
muß nun bezüglich eines anderen Themas:http://www.tutorials.de/forum/java/296642-hilfe-performance-problem.html

noch Performance-Tests durchführen, und bekomme meine Leinwand (JComponent) nicht zum Scrollen (NICHT JScrollPane, SONDERN Animation). Ohne Schleife werden die Operationen sauber angezeigt, mit der Schleife - trotz repaint() - nur das Endergebnis:(
Hier ein Code-Auszug:

Actionlistener
Code:
package dateien;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import leinwand.Steuerung;

@SuppressWarnings("serial")
public final class horizontalScrollen implements ActionListener {
	
	private Steuerung s = null;

	public void actionPerformed(ActionEvent e) {
		if (!s.isKugelDarstellung()) {
			int i = 0;
			while (i<20 && !s.isEnde()) {
				s.scrollHorizontal();
				s.zeigeFlaeche();
				s.getLeinwand().repaint();
				i++;
				try {
					Thread.sleep(20);
				}
				catch(InterruptedException ex){}
			}
			s.resetEnde();
		}
	}
	public horizontalScrollen(Steuerung s){
		this.s = s;
	}
}

Klasse Steuerung

Code:
	public void scrollHorizontal() {
		int w = i.getWidth();
		int h = i.getHeight();
		int[] iData = new int[(w-1)*h];
		int[] iDat = new int[h];
		i.getRGB(0, 0 , w-1, h, iData, 0, w-1);
		i.getRGB(w-1, 0, 1, h, iDat, 0, 1);
		i.setRGB(0, 0, 1, h, iDat, 0, 1);
		i.setRGB(1, 0 , w-1, h, iData, 0, w-1);
	}

	public void zeigeFlaeche() {
		if (this.i!=null) {
			this.lw.setPreferredSize(
					new Dimension(this.i.getWidth(),
							this.i.getHeight()));
			this.lw.setSize(
					new Dimension(this.i.getWidth(),
							this.i.getHeight()));
			this.setBildVorhanden(true);
			setKugelDarstellung(false);
			lw.setLeinwand(i);
		}
	}

Klasse Leinwand

Code:
package leinwand;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;

@SuppressWarnings("serial")
public  class Leinwand extends JComponent {

	@SuppressWarnings("unused")
	private Steuerung s = null;
	private BufferedImage i = null;

	public void setLeinwand(BufferedImage i) {
		this.i = i;
	}
	
	public Leinwand(Steuerung s) {
		this.s = s;
		this.setVisible(true);
	}
	
	public void paintComponent(Graphics g) {
//		super.paintComponent(g);
		if (this.i != null) {
			int x = (int)((this.getWidth() - i.getWidth())/2);
			int y = (int)((this.getHeight() - i.getHeight())/2);
			g.drawImage(i, x, y, this);
		}
	}
}

Bin völlig ratlos, und dankbar für jeden Tipp.
Anmerkung des Autors: Meine Blütezeit hatte ich eigentlich auf dem 286´er und lehne - obwohl ich Java sehr mag, das Graphics-Konzept absolut ab.
Gruß,
Ulrich
 
Diese Problem mit dem repaint() hatte ich auch schon oft. Kommt daher dass er aus Performanc Gründen alle repaint Aufrufe zu einem zusammenfast.
Da gibts einmal die Möglichkeit dass du die repaint in einer Schleifen in einem THREAD aufrufst.
Andre Möglichkeit: du benutzt paintImmediately(). Hier kannst du gleich noch den Bereich angeben der neugezeichnet werden soll (was wiederrum die Performanc verbessern kann.
Viel Glück
 
paintImmediatly zeichnet erst, wenn die Berechnungen alle gelaufen sind:-(
Code:
package dateien;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import leinwand.Steuerung;

@SuppressWarnings("serial")
public final class horizontalScrollen implements ActionListener {
	
	private Steuerung s = null;

	public void actionPerformed(ActionEvent e) {
		int x1, y1, x2, y2;
		if (!s.isKugelDarstellung()) {
			int i = 0;
			while (i<20 && !s.isEnde()) {
				s.scrollHorizontal();
				s.zeigeFlaeche();
				x1 = s.getLeinwand().getX();
				y1 = s.getLeinwand().getY();
				x2 = s.getLeinwand().getWidth();
				y2 = s.getLeinwand().getHeight();
				s.getLeinwand().paintImmediately(x1, y1, x2, y1);
				x1 = s.getLeinwand().getX();
				i++;
				try {
					Thread.sleep(200);
				}
				catch(InterruptedException ex){}
			}
			s.resetEnde();
		}
	}

	public horizontalScrollen(Steuerung s){
		this.s = s;
	}
}
 
Ich kann mich wohl in Thread-Programmierung einlesen, mir ehrlich gesagt aber nicht vorstellen, wie das funktionieren soll. Ehrlich gesagt bin ich gerade ziemlich sauer auf die Entwickler des Java-Interpreters: Wenn eine serielle Befehlsfolge:
Berechnung,Zeichen,Berechnung,Zeichnen,... nicht funktioniert, ist das einfach sch...:mad:
Ich könnte mir höchstens vorstellen, das ein Thread A berechnet, ein Flag setzt, Thread B zeichnet, sobald das Flag gesetzt ist. Ich bin allerdings ernsthaft am überlegen, auf eine andere Programmiersprache umzusteigen, da das Laufzeitverhalten, so wie ich es vermute, völlig unlogisch ist. Oder habe ich eine Möglichkeit bei der Multithread-Programmierung (s.o.) übersehen? Bin verzweifelt!:-(

p.s.: Ich glaube ich hole mir bei ebay einen 286´er, MS-Dos 3.3 und Turbo-Pascal, das konnte man wenigstens noch so ausführen lassen, wie der Programmierer das wollte!
 
Programmierst du unter windows oder linux:

ich hatte mal ein ähnliches problem unter linux, unter windows lief das gleiche programm ohne probleme
 
Deine Bedenke und Gründe auf eine andere Sprache umzusteigen sind eigentlich völlig unbegründet!
Wenn du bei einer Kleinigkeit gleich die Sprache wechseln musst, dann empfehle ich dir gleich eine eigene zu schreiben.

Dieses Verhalten in Java ist vieleicht unumgänglich, weil Java eben Platformunabhängig ist und jede Platform anders funktionert (siehe Beitrag von "firmadankt"). Oder vielleicht ist es ja ein Perfomanc Grund. Wenn du zeichnen willst dann würde ich dir sowieso nicht paint() und repaint() empfelen, sondern eher, dass du dich mal mit Java2D auseinandersetzt!
 
Wenn du zeichnen willst dann würde ich dir sowieso nicht paint() und repaint() empfelen, sondern eher, dass du dich mal mit Java2D auseinandersetzt!

Hallo Matze,
zunächst einmal Danke für die Anregung.Ich habe gerade mal in "Learning Java" von O´Reilly geguckt:
Wie komme ich denn um paint() bei Benutzung der Klasse Graphics2D herum? Die Klasse meintest Du doch?
Code:
public void paint(Graphics g) {
  Graphic2D g2 = (Graphic2D) g;
  g2.methoden(...)
}
benutzt doch auch paint(), was ist da der Unterschied?
Neugierig,
Ulrich
 
Zurück