linienzeichner

Status
Nicht offen für weitere Antworten.
R

RockyBalboa

Gast
Hi,
Ich habe ca. 54500 koordinaten aus einer datei, die eingelesen werden müssen. Danach sollen sie auf einer art player (GUI) mit Linien nachgezeichnet werden. Man soll den verlauf der linien erkennen. Ich habe die Koordinaten mit dem BufferedReader eingelesen, und anhand des StringTokenizer (for-Schleife) in die einzelnen Koordinaten unterteilt. Wenn ich das Programm ausführe, erhalte ich zwar das gesamte Bild auf einmal, aber da es ja ein player werden soll, wüsste ich gerne, was ich machen muss, damit die linien nach und nach aufgebaut werden... Ist das in JAVA möglich?
Hier mein Programm:

Code:
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;
import javax.swing.*;


public class Player extends JComponent {
	static JFrame myFrame;
	static Panel myPanel;
	static Polygon p = new Polygon();
	static String pathname = "...ListeVonKoordinaten.txt";         //Beispiel
	static File input;


	public void paintComponent(Graphics g){
		input = new File(pathname);
		String line;
	    String buffer = " ";
	    int x;
	    int y;
	    int xprev = 0;
	    int yprev = 0;
	    int i;
	
		
		try{
			BufferedReader reader = new BufferedReader(new FileReader(input));
			for(i = 0 ; i<54367; i++){
				line = reader.readLine();
				StringTokenizer st = new StringTokenizer(line);
				buffer = st.nextToken();
				x  = Integer.valueOf(buffer).intValue();
				buffer = st.nextToken();
				y = Integer.valueOf(buffer).intValue();
				if(x <= 0){
					i++;
					continue;
				}
				if(x >= 1280){
					i++;
					continue;
				}
				if(y <= 0){
					i++;
					continue;
				}
				if(y >= 800){
					i++;
					continue;
				}
				
				g.setColor(Color.BLUE);
				g.drawLine(x, y, xprev, yprev);
				xprev = x;
				yprev = y;
				
				
			}
		}
			
		catch(IOException e){
			e.printStackTrace();
		}
	}
	
    
  public Player() {

	  myFrame = new JFrame("KoordEyePlayer");
	  myFrame.setSize(1280, 800);
	  myFrame.add(this);
	  myFrame.setVisible(true);
  	  myFrame.setDefaultCloseOperation(myFrame.EXIT_ON_CLOSE);
	  }

  
  

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











Wäre euch sehr verbunden, wenn ihr mir helfen könntet.
MFG
 
M

Michael...

Gast
Hallo,

mit Thread.sleep(int i), kann man z.B in der for-Schleife, den aktuellen Thread schlafen legen.
 
R

RockyBalboa

Gast
Hi,
Danke, aber des hab ich schon probiert. Dann dauerts aber nur länger, bis das gesamte Bild kommt. Die linien werden troztdem nicht nacheinander gezeichnet... Hab auch schon einen solchen Code, mit selbst geschriebener Wait() Methode, die im Prinzip des implementiert, was du mir grad geschrieben hast:

Code:
p.addPoint(x, y);
  if((i % 30)==0){					        
  g.setColor(Color.BLUE);
  g.drawPolygon(p);
  Wait.milliSec(100);
}

aber wie gesagt, es dauert nur länger, bis dann endlich wieder das ganze Bild auf einmal eingeladen wird...
}
 

Wildcard

Top Contributor
In der paintComponent wird nur gezeichnet. Dort eine Datei einlesen ist komplett falsch.
Derzeit liest du die Datei einmal pro repaint ein, was auch durchaus mal 80 repaints (oder mehr) pro Sekunde sein können!
Um die Linien nach und nach zu zeichnen brauchst du einen seperaten Thread, der die Linien nach und nach in ein Datenmodell füllt und dann repaint aufruft.
In deinem speziellen Fall wäre es aber auch möglich in ein Image zu zeichnen und in paintComponent nur das Image abzubilden.
 
R

RockyBalboa

Gast
Vielen Dank!
Aber hättest du vielleicht ein beispiel, wie man sowas implementiert?
 
G

Guest

Gast
Code:
import javax.swing.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;

import java.awt.image.*;


public class Player extends JComponent{
	
		static Polygon p = new Polygon();
		static String pathname = "...data.txt";  //Koordianaten
		static File input = new File(pathname);
		static File file;
		static int i;
		static BufferedImage bffImg;
		
		
		
		

		
		
		public void setImage(File input, Graphics g){
			
			
			
			String line;
		    String buffer = " ";
		    int x;
		    int y;
		
		  
			try{
				 for(i = 0 ; i<54367; i++){
				BufferedReader reader = new BufferedReader(new FileReader(input));
					line = reader.readLine();
					StringTokenizer st = new StringTokenizer(line);
					buffer = st.nextToken();
					x = Integer.valueOf(buffer).intValue();
					buffer = st.nextToken();
					y = Integer.valueOf(buffer).intValue();
					if(x <= 0){
						return;
					}
					if(x >= 1280){
						return;
					}
					if(y <= 0){
						return;
					}
					if(y >= 800){
						return;
					}
					
					p.addPoint(x, y);
					
					if((i % 30)==0){
						Wait.milliSec(100);
						g.drawPolygon(p);
						bffImg.getGraphics();
					}
				 }
			}
			catch(IOException e){
				e.printStackTrace();
				}
			}
		
		public void paintComponent(Graphics g){
			if(bffImg != null){
			g.drawImage(bffImg, 0, 0, this);
			}
		}
}

Meinst du so? Des funktioniert aber irgendwie nicht. Was muss ich ändern? Ich bräuchte wirklich hilfe...
 

Marco13

Top Contributor
Ich gehe davon aus, dass dieses 'Graphics'-Objekt, das du an setImage übergibst, das ist, das du irgendwie mit bffImg.getGraphics() bekommen hast.

Dass während des Einlesens deine "Wait"-Methode aufgerufen wird, finde ich persönlich nicht so schön. Besser wäre es IMHO(!) erstmal ALLES zu lesen, und die gelesenen Daten dann ins Bild zu zeichnen. Aber ... die einfachste Möglichkeit, das gewünschte zu erreichen, wäre, die setImage-Methode von einem eigenen Thread ausführen zu lassen.
Code:
Thread t = new Thread(new Runnable()
{
    public void run()
    {
        setImage(....);
    }
});
t.start();
Allerdings ist auch die setImage-Funktion nicht optimal. Dort bräuchtest du jetzt (wenn du die Linien in ein BufferedImage malst) wirklich NURnoch die letzte Linie zu zeichnen, und nicht das ganze Polygon. Und nach dem zeichnen der Linie dann repaint() aufrufen.
 

RockyBalboa

Mitglied
Danke für eure Antworten!
Sorry, aber ich komme mir grad als kompletter Vollidiot vor! Des Funktioniert einfach nicht. Ich bin glaub ich einfach zu blöd dafür!
kann mir bitte jemand sagen, was speziell an meinem Code nicht stimmt, und was ich reinschreiben muss, damit es Funktioniert? Hilfe bitte!!!

Code:
import javax.swing.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.StringTokenizer;

import java.awt.image.*;


public class Player extends JComponent{
	
		static Polygon p = new Polygon();
		static String pathname = "... Koordinaten.txt";
		static File input;
		static File file;
		static int i;
		static BufferedImage bffImg;
	
		
		
		

		
		
		public void setImage(Graphics g){
			
			
			input = new File(pathname);
			String line;
		    String buffer = " ";
		    int x;
		    int y;
		    int xprev = 0;
		    int yprev = 0;
		
		  
			try{
				 for(i = 0 ; i<54367; i++){
				BufferedReader reader = new BufferedReader(new FileReader(input));
					line = reader.readLine();
					StringTokenizer st = new StringTokenizer(line);
					buffer = st.nextToken();
					x = Integer.valueOf(buffer).intValue();
					buffer = st.nextToken();
					y = Integer.valueOf(buffer).intValue();
					if(x <= 0){
						return;
					}
					if(x >= 1280){
						return;
					}
					if(y <= 0){
						return;
					}
					if(y >= 800){
						return;
					}
					
					p.addPoint(x, y);
					
					g.setColor(Color.BLUE);
					g.drawLine(x, y, xprev, yprev);
					xprev = x;
					yprev = y;
					bffImg.getGraphics();
					
				 }
				 Thread t = new Thread(new Runnable(){
			public void run(){
				setImage(g);
				}
			});
			t.start();
			}
			catch(IOException e){
				e.printStackTrace();
				}
			}
 
M

Michael...

Gast
Hallo,

generell würde ich Dir empfehlen sich mal mit folgenden Themen aus einander zu setzen:

wie zeichne ich auf Komponenten
wie funktionieren Threads

Da mir Dein Code ein bisschen zu chaotisch ist, Du aber doch recht verzweifelt klingst, habe ich hier mal ein kurzes, kompilierbares Bsp. wie man mittels BufferdImage und Thread eine Zeichnung sukzessive aufbauen könnte.

Code:
import java.awt.*;
import java.awt.image.BufferedImage;

import javax.swing.*;

public class PaintingFrame extends JFrame{

	public PaintingFrame() {
		this.setBounds(50, 50, 500, 500);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		this.getContentPane().setLayout(new BorderLayout());
		this.getContentPane().add(new Player(), BorderLayout.CENTER);
	}
	
	public static void main(String[] args) {
		new PaintingFrame().show();
	}
	
	public class Player extends JPanel { // beinhaltet das zu zeichnende Bild
		private BufferedImage image;
		public Player(){
			image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
			Graphics g = image.getGraphics();
			g.setColor(Color.RED);
			Thread t = new Thread(new Timer(this, g));
			t.start();
		}
		public void paintComponent(Graphics g) {
			super.paintComponent(g);
			Graphics2D g2 = (Graphics2D) g;
			g2.drawImage(image, null, 10, 10);	//hier wird das Bild auf den Player gemalt
		}
	}
	
	public class Timer implements Runnable{ //steuert den zeitlichen Verlauf des Bildaufbaus 
		Graphics g;
		Player p;
		public Timer(Player p, Graphics g){
			this.g = g;
			this.p = p;
		}
		public void run() {
			for (int i=1 ; i<30; i++) {
				g.drawRect(i*10, i*10, 100, 100); 	//hier werden die ein neues Rechteck ins Bild gemalt
				p.repaint();						//hier wird der Player "aufgefrischt"
				try {
					Thread.sleep(1000);				//hier wird eine Pause von ca. 1000ms eingelegt
				}
				catch (Exception exc) {
					exc.printStackTrace();
				}
			}
		}
	}
}
 

RockyBalboa

Mitglied
Vielen, vielen dank!!!
Wenn ich des mit dem Beispiel jetzt nicht hinbekomme, dann hör ich auf zu studieren ;-)!!!
Danke nochmal!
 
Status
Nicht offen für weitere Antworten.

Oben