Neu zeichnen verhindern

Status
Nicht offen für weitere Antworten.

flashdog

Bekanntes Mitglied
Hallo,
in der initialisierungs Phase moechte ich ein Bild zeichnen. Dann sollen neue Elemente nach einer bestimmten Zeit eingefuegt werden ohne, dass das initialisierungs Bild neu gemalt werden muss (CPU schonen).

Wie verhindert man ein neu zeichen, aber es soll noch moeglich sein neue Elemente ins urspruengliche Bild einzufuegen?

Viele Gruesse

Code:
import java.awt.*;
import javax.swing.*;

public class BallRoom extends JApplet implements Runnable {
  private final int WIDTH = 350;
  private final int HEIGHT = 300;
  private PaintSurface canvas;
  Thread th;

  public void init() {   	
    this.setSize(WIDTH, HEIGHT);
    canvas = new PaintSurface();
    this.add(canvas, BorderLayout.CENTER);
  }
  
  
  public void start() {
      th = new Thread(this);
      th.start();
  }

  public void run() { 
    while (true){
      repaint();
      try {
        Thread.sleep(100);
      }
      catch (InterruptedException ex){
      }
    }
  }

  public void update(Graphics g)
  {
    paint(g);
  }
}


Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import javax.swing.JComponent;

class PaintSurface extends JComponent {
  int ball1_x_pos = 0; // the starting X position
  int ball1_y_pos = 150; // the starting Y position
  int ball2_x_pos = 60; // the starting X position
  int ball2_y_pos = 150; // the starting Y position
  
  int d = 20; // the diameter of the ball

  public void paint(Graphics g) { 
    Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    ball1_x_pos++; // move ball1 right one pixel
    ball2_x_pos--; // move ball1 left one pixel
    Shape ball1 = new Ellipse2D.Float(ball1_x_pos, ball1_y_pos, d, d);
    Shape ball2 = new Ellipse2D.Float(ball2_x_pos, ball2_y_pos, d, d);
    g2.setColor(Color.RED);
    g2.fill(ball1);
    g2.fill(ball2);
  }
}
 
S

SlaterB

Gast
male das ursprüngliche Bild in ein Bild und male dann später nur das Bild ;)
also ein Bild zu malen dauert ja keine Zeit, das kann man nicht mehr optimieren (in den einfachen Strukturen, die ich hier nenne)

nur wenn du in einer paint aus tausend Schleifen irgendwas Punkt für Punkt zusammenbaust,
dann lohnt es sich, dieses Bild in einem Image abzuspeichern und später nur noch auf einen Schlag das fertige Bild zu malen
 

flashdog

Bekanntes Mitglied
Habe ein Bild zu erstellt, aber ich schaffe es nicht, dass sich das Bild aktualisiert (Ball-Bewegung). Was mache ich falsch?

Aktualiesierte PaintSurface Klasse befindet sich hier unten und die dazugehoerige BallRoom Klasse im ersten Posting.
Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;

class PaintSurface extends JComponent {
	int ball1_x_pos = 0; // the starting X position
	int ball1_y_pos = 150; // the starting Y position
	int ball2_x_pos = 60; // the starting X position
	int ball2_y_pos = 150; // the starting Y position

	int d = 20; // the diameter of the ball
	


	BufferedImage bi ;//= new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);

	boolean created = false;
	
	public Graphics2D CreatePicture(Graphics2D g2){
	  // Compute the grid only one time
    int w = this.getWidth();
    int h = this.getHeight();
    bi = (BufferedImage)(this.createImage(w,h));

    g2 = bi.createGraphics();
    g2.setColor(Color.BLUE);
    for (int x=0; x<w; x+=10) {g2.drawLine(x, 0, x, h);}
    for (int y=0; y<h; y+=10) {g2.drawLine(0, y, w, y);}
    return g2;
	}
		
	//public void paint(Graphics g) { 
	@Override public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
    
    if (bi == null) g2 = CreatePicture(g2);
    
    //g2.drawOval(10,10,40,100);
    
    ball1_x_pos++; // move ball1 right one pixel
    ball2_x_pos--; // move ball1 left one pixel
    Shape ball1 = new Ellipse2D.Float(ball1_x_pos, ball1_y_pos, d, d);
    Shape ball2 = new Ellipse2D.Float(ball2_x_pos, ball2_y_pos, d, d);
    g2.setColor(Color.RED);
    g2.fill(ball1);
    g2.fill(ball2);
    //g2.drawImage(bi, null, 0, 0);
    g2.drawImage(bi, 0, 0, this);
	}
}
 
G

Guest

Gast
Ich habe die Bälle zuerst gezeichnet weil ich mir dachte, dass man die veränderte Position mit g2.drawImage(bi, 0, 0, this) im Bild abspeichern könnte, aber leider funktioniert das nicht.

Wenn man das Programm laufen lässt erzeugt es ein Bild mit einem Gitter und auf diesem zwei Baelle. Wenn man waehrend das Programm laeuft das Fenster vergrößert, dann sieht man nach einer kurzen wie ein Ball aus dem dem Schatten von dem erzeugten Bild zu vorschein kommt.

Was mache ich falsch?
 
S

SlaterB

Gast
wie gesagt, du zeigst immer nur das Bild,
die anderen Zeichen-Aufrufe davor werden übermalt,
erst wenn diese weiter rechts als das Bild liegen sind sie zu sehen

außerdem malst du anfangs die beiden Bälle auf das Hintergrundbild,
das willst du sicher nicht, die bekommst du nämlich nicht wieder weg

Code:
public class TestGUI
    extends JFrame
{

    public TestGUI()
        throws Exception
    {
        PaintSurface p = new PaintSurface();


        add(p);
        setSize(300, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);

        while (true)
        {
            Thread.sleep(10);
            repaint();
        }
    }

    public static void main(String[] args)
        throws Exception
    {
        new TestGUI();
    }
}



class PaintSurface
    extends JComponent
{
    int ball1_x_pos = 0; // the starting X position
    int ball1_y_pos = 150; // the starting Y position
    int ball2_x_pos = 60; // the starting X position
    int ball2_y_pos = 150; // the starting Y position

    int d = 20; // the diameter of the ball


    BufferedImage bi;// = new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);

    boolean created = false;

    public void createPicture()
    {
        // Compute the grid only one time
        int w = this.getWidth();
        int h = this.getHeight();
        bi = (BufferedImage)(this.createImage(w, h));

        Graphics2D g2 = bi.createGraphics();
        g2.setColor(Color.BLUE);
        for (int x = 0; x < w; x += 10)
        {
            g2.drawLine(x, 0, x, h);
        }
        for (int y = 0; y < h; y += 10)
        {
            g2.drawLine(0, y, w, y);
        }
    }
    
    @Override
    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        if (bi == null)
        {
            createPicture();
        }
        g2.drawImage(bi, 0, 0, this);

        ball1_x_pos++;
        ball2_y_pos++;
        Shape ball1 = new Ellipse2D.Float(ball1_x_pos, ball1_y_pos, d, d);
        Shape ball2 = new Ellipse2D.Float(ball2_x_pos, ball2_y_pos, d, d);
        g2.setColor(Color.RED);
        g2.fill(ball1);
        g2.fill(ball2);
    }
}
 

flashdog

Bekanntes Mitglied
Die Bälle die auf den Hintergrundbild gemalt wurden sind wollte ich wieder weg bekommen in dem ich an die alte Ball-Position ein neuen Ball mit der Hintergrundfarbe zeichne und dann die neue Ball-Position mit rot.

Oder ist es nicht moeglich ein mit BufferedImage erzeutgtes Bild wieder zu aendern/manipulieren?
 
S

SlaterB

Gast
doch, geht auch, mit Hintergrundfarbe wirst du aber kaum die Gitternetzlinien wiederherstellen

macht zwar in meinen Augen keinen Sinn, aber um das zu bewerkstelligen brauchst du das Graphics-Objekt von dem Bild,
bisher holst du dies nur am Anfang wenn createPicture() ausgeführt wird,
du musst dir auch danach in paint immer das Graphics-Objekt besorgen
 

flashdog

Bekanntes Mitglied
Hintergrundfarbe soll weiss sein, dass mit dem Gitternetzlinien war nur ein Test.

Wie besorgt man sich das Graphics-Objekt von dem Bild am besten?
 
S

SlaterB

Gast
Graphics2D g2 = bi.createGraphics();
wie du schon hast, vermute ich,
wenns damit Probleme gibt, dann speichere dir einfach das g2 vom Anfang auch in einer Exemplarvariablen, so wie bi
 

flashdog

Bekanntes Mitglied
Funktioniert zwar, aber ohne ANTIALIAS_ON bewegt sich der Ball nicht fluessig und mit ANTIALIAS_ON ist es eine fliessende Bewegung, aber mit einer Staubwolke.

Wie bekommt man eine fliessende Bewegung ohne eine Staubwolke hin?

Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;

class PaintSurface extends JComponent {
	int ball1_x_pos = 0; // the starting X position
	int ball1_y_pos = 150; // the starting Y position
	int ball2_x_pos = 60; // the starting X position
	int ball2_y_pos = 150; // the starting Y position

	int d = 20; // the diameter of the ball
	
	BufferedImage bi = null;//= new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);

	boolean created = false;
	
	public void CreatePicture(){
	  // Compute the grid only one time

    int w = this.getWidth();
    int h = this.getHeight();
    bi = (BufferedImage)(this.createImage(w,h));

    Graphics2D g2 = bi.createGraphics();
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
    g2.setBackground(Color.WHITE);
		g2.setColor(Color.RED);
		g2.fill(new Ellipse2D.Float(ball1_x_pos, ball1_y_pos, d, d));
	}
	
	public void DeleteOldPosition(Graphics2D g2, int oldXpos, int oldYpos) {
		g2.setColor(Color.WHITE);
		g2.fill(new Ellipse2D.Float(oldXpos, oldYpos, d, d));
	}
	
	public void SetNewPosition(Graphics2D g2, int newXpos, int newYpos) {
		g2.setColor(Color.RED);
		g2.fill(new Ellipse2D.Float(newXpos, newYpos, d, d));
	}
	
	public void MoveElement(){
		Graphics2D g2 = bi.createGraphics();
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
        RenderingHints.VALUE_ANTIALIAS_ON);
		DeleteOldPosition(g2, ball1_x_pos, ball1_y_pos);
		SetNewPosition(g2, ++ball1_x_pos, ball1_y_pos);
	}
		
	@Override public void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D)g;
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                       RenderingHints.VALUE_ANTIALIAS_ON);
    
    if (bi == null) {
    	CreatePicture();
    	g2.drawImage(bi, 0, 0, this);
    }
  
    if (bi != null) {
    	MoveElement();
    	g2.drawImage(bi, 0, 0, this);
    }

  }
}
 
S

SlaterB

Gast
interessant,

also bei mir macht das 'ohne ANTIALIAS_ON' nur den Rand weg, die Bewegung ist genauso flüssig,

wenn du viel Platz um den Ball hast, kannst du auch gut mit einem größeren Radius mit weiß übermalen

aber allgemein ist es eben bisher zumindest schlicht unnötig, den Ball auf das Bild zu malen und später auszuradieren,
wenn du ihn direkt auf den Bildschirm malen würdest, hättest du in diesem Punkt weniger Probleme,

tiefergehende Hinweise kann zumindest ich nicht geben
 

Quaxli

Top Contributor
Ich habe das gerad mal von Anfang bis Ende durchgelesen. Ohne zu Wissen, was Du letzten Endes vorhast, klingt das alles etwas umständlich.
Die Lösung die Dir SlaterB weiter oben aufgezeigt hat, ist da sehr viel effizienter und eignet sich durchaus auch für etwas aufwändigere Zeichenoperationen.

Was das Ruckeln Deiner Animation angeht, würde ich mal vermuten, daß es an dieser Zeile liegt:

Code:
Thread.sleep(100);

Das erscheint mir zu viel, falls es so noch im Code ist. Mehr als 10 ms würde ich den Thread nicht schlafen lassen. Du könntest den Befehl auch durch

Code:
Thread.yield()

ersetzen. Schneller geht's dann nicht mehr.

Aber auch das Errechnen der Bewegung mit

Code:
    ball1_x_pos++; // move ball1 right one pixel
    ball2_x_pos--; // move ball1 left one pixel

ist nicht ideal. Da Du Deinen Ball nur um 1 Pixel bewegst fällt es vermutlich aber nicht sehr auf. Grundsätzlich braucht Deine Animationsschleife aber nie die gleiche Zeit für einen Loop, sondern es treten durchaus Unterschiede auf. Daher macht es gerade bei schnelleren Bewegungen Sinn, diese in Abhängigkeit von der Zeit, die der Loop benötigt hat auszuführen. Dazu mußt Du mit einem guten Timer, die Zeit für den Loop stoppen und die Bewegung dann in Abhängigkeit der Zeit berechnen.

Das Ganze könnte ungefähr so aussehen:

Code:
  public void run() {
    long last = System.nanoTime();
    int dx = 50;   //Geschwindigkeit 50 Pixel/sekunde

    while (true){

      long delta = System.nanoTime() - last;
      last = System.nanoTime();

      double movex = dx * delta / 1e9;
      ball1_x_pos += (int) movex;

      repaint();
      try {
        Thread.sleep(10); //100 ist zuviel
      }
      catch (InterruptedException ex){
      }
    }
  }


Wenn Du Dich zu dem Thema insgesamt etwas einlesen möchtest, gibt es ein gutes englisches Forum: www.javagaming.org.
 

flashdog

Bekanntes Mitglied
@SlaterB: Danke fuer deine Hilfe, ja es ist viel einfacher etwas auf den Bildschrim zu malen.

@Quaxli: Danke fuer den Code und den Link. Aber bei mir kennt er die Variable ball1_x_pos nicht in der run() Funktion. Wie kann man das aendern so dass es immer noch moeglich ist spaeter JButton usw. einzufuegen (z. B. http://www.geom.uiuc.edu/~daeron/apps/function/graph.html ).

Code:
import java.awt.*;
import javax.swing.*;

public class BallRoom extends JApplet implements Runnable {
  private final int WIDTH = 350;
  private final int HEIGHT = 300;
  private PaintSurface canvas;
  Thread th;

  public void init() {   	
    this.setSize(WIDTH, HEIGHT);
    canvas = new PaintSurface();
    this.add(canvas, BorderLayout.CENTER);
  }
  public void start() {
      th = new Thread(this);
      th.start();
  }
  public void run() { 
    while (true){
      repaint();
      try {
        Thread.sleep(20);
      }
      catch (InterruptedException ex){
      }
    }
  }

  public void update(Graphics g) {
    paint(g);
  }
}

Code:
class PaintSurface extends JComponent {
	int ball1_x_pos = 0; // the starting X position
	int ball1_y_pos = 150; // the starting Y position
	int ball2_x_pos = 60; // the starting X position
	int ball2_y_pos = 150; // the starting Y position

	int d = 2; // the diameter of the ball
	
	BufferedImage bi = null;//= new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);

	boolean created = false;
	
	public void CreatePicture(){
	}
	
	public void DeleteOldPosition(Graphics2D g2, int oldXpos, int oldYpos) {
	}
	
	public void SetNewPosition(Graphics2D g2, int newXpos, int newYpos) {
	}
	
	public void MoveElement(){
	}
		
	@Override public void paintComponent(Graphics g) {
	}
}
 
S

SlaterB

Gast
in der run-Methode kennst du
canvas

und kannst dort
canvas getAny/ setAny aufrufen oder besser
canvas.recalculateWhatYouNeedWithTimeInformation(time oder delta);
 

flashdog

Bekanntes Mitglied
Leider bekomme ich den Inhalt vom BufferedImage nicht auf dem Bildschirm, wenn man den init Button betaettigt.
Code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.*;

public class BallRoom2Test extends JApplet implements ActionListener, Runnable {
	private final int WIDTH = 350;
	private final int HEIGHT = 300;
	private PaintSurface2Test canvas;
	private JButton init;
	private JPanel control;

	public void init() {     
		this.setSize(WIDTH, HEIGHT);
		
		canvas = new PaintSurface2Test();
		this.add(canvas, BorderLayout.CENTER);

		control = new JPanel();
		init = new JButton("init");
		init.addActionListener(this);
		control.add(init);
		this.add(control, BorderLayout.SOUTH);
	}

	public void run() {
	}

	public void update(Graphics g) {
		paint(g);
	}

	public void actionPerformed(ActionEvent e){
		if (e.getSource() == init){
			canvas.initialization = true;
			canvas.repaint();
		}
	}
}

Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.Scanner;

import javax.swing.JComponent;

class PaintSurface2Test extends JComponent {
	int d = 20; // the diameter of the ball
	boolean created = false;
	boolean initialization = false;

	final float ScalingFactor = 2;
	final float ElipseSize = 2;

	BufferedImage buffer = null;//= new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
	Graphics2D osg;

	public PaintSurface2Test(){
		buffer = new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
		osg = buffer.createGraphics();
		osg.setBackground(Color.WHITE);
	}

	public void Initialization(){
		System.out.println("Initialization");

		osg.setColor(Color.BLACK);
		Shape molecule = new Ellipse2D.Float(20 * ScalingFactor, 40 * ScalingFactor, ElipseSize, ElipseSize);
		osg.fill(molecule);
	}

	@Override public void paintComponent(Graphics g) {
		if (initialization == true){
			Initialization();
			initialization = false;
			osg.drawImage(buffer, 0, 0, this);
		}
	}
}

Was mache ich falsch das der Bildschirm leer bleibt?
 
S

SlaterB

Gast
wer soll denn wo was zeichen? ich sehe keinen Zeichnen-Befehl,
z.B. in
public void paintComponent(Graphics g) {
von PaintSurface2Test
wird nie etwas mit g gemacht?
 
S

SlaterB

Gast
weil heut Gründienstag ist
(oder du ausführbaren Code posten musst, kannst dir aussuchen)
 

flashdog

Bekanntes Mitglied
Es ist eigentlich der gleiche code wie oben nur statt osg.drawImage ist jetzt g.drawImage. Aber ich poste gerne nochmal

Code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;

import javax.swing.*;

public class BallRoom2Test extends JApplet implements ActionListener, Runnable {
   private final int WIDTH = 350;
   private final int HEIGHT = 300;
   private PaintSurface2Test canvas;
   private JButton init;
   private JPanel control;

   public void init() {     
      this.setSize(WIDTH, HEIGHT);
      
      canvas = new PaintSurface2Test();
      this.add(canvas, BorderLayout.CENTER);

      control = new JPanel();
      init = new JButton("init");
      init.addActionListener(this);
      control.add(init);
      this.add(control, BorderLayout.SOUTH);
   }

   public void run() {
   }

   public void update(Graphics g) {
      paint(g);
   }

   public void actionPerformed(ActionEvent e){
      if (e.getSource() == init){
         canvas.initialization = true;
         canvas.repaint();
      }
   }
}

Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.Scanner;

import javax.swing.JComponent;

class PaintSurface2Test extends JComponent {
   int d = 20; // the diameter of the ball
   boolean created = false;
   boolean initialization = false;

   final float ScalingFactor = 2;
   final float ElipseSize = 2;

   BufferedImage buffer = null;//= new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
   Graphics2D osg;

   public PaintSurface2Test(){
      buffer = new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
      osg = buffer.createGraphics();
      osg.setBackground(Color.WHITE);
   }

   public void Initialization(){
      System.out.println("Initialization");

      osg.setColor(Color.BLACK);
      Shape molecule = new Ellipse2D.Float(20 * ScalingFactor, 40 * ScalingFactor, ElipseSize, ElipseSize);
      osg.fill(molecule);
   }

   @Override public void paintComponent(Graphics g) {
      if (initialization == true){
         Initialization();
         initialization = false;
         g.drawImage(buffer, 0, 0, this);
      }
   }
}

Warum zeichnet er ein Rechteck und nicht eine Ellipse?
 
S

SlaterB

Gast
ich nix kennen JApplet, du weißt was zu tun ist ;),
oder andere bemühen sich mal
 

flashdog

Bekanntes Mitglied
ok, ich habe es in JFrame umgeschrieben.
Code:
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BallRoom2TestMain extends JFrame implements ActionListener {
	private final int WIDTH = 350;
	private final int HEIGHT = 300;
	private PaintSurface2Test canvas;
	private JButton init;
	private JPanel control;

	public BallRoom2TestMain(){
		this.setSize(WIDTH, HEIGHT);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);

		canvas = new PaintSurface2Test();
		this.add(canvas, BorderLayout.CENTER);
		control = new JPanel();
		init = new JButton("init");
		init.addActionListener(this);
		control.add(init);
		this.add(control, BorderLayout.SOUTH);
	}

	public void update(Graphics g) {
		paint(g);
	}

	public void actionPerformed(ActionEvent e){
		if (e.getSource() == init){
			canvas.initialization = true;
			canvas.repaint();
		}
	}

	public static void main(String[] args) {
		new BallRoom2TestMain();
	}
}
Code:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Date;
import java.util.Scanner;

import javax.swing.JComponent;

class PaintSurface2Test extends JComponent {
	int d = 20; // the diameter of the ball
	boolean created = false;
	boolean initialization = false;

	final float ScalingFactor = 20;
	final float ElipseSize = 20;

	BufferedImage buffer = null;//= new BufferedImage(300, 300, BufferedImage.TYPE_INT_ARGB);
	Graphics2D osg;

	public PaintSurface2Test(){
		System.out.println("I'm in PaintSurface2 constructor");
		buffer = new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
		osg = buffer.createGraphics();
		osg.setBackground(Color.WHITE);
		System.out.println("I'll leave PaintSurface2 constructor");
	}

	public void Initialization(){
		System.out.println("Initialization");

		osg.setColor(Color.BLACK);
		Shape molecule = new Ellipse2D.Float(20 * ScalingFactor, 40 * ScalingFactor, ElipseSize, ElipseSize);
		osg.fill(molecule);
		//osg.draw(molecule);
		//    		System.out.println("count " + ++count);
	}

	@Override public void paintComponent(Graphics g) {
		if (initialization == true){
			Initialization();
			initialization = false;
			
			g.drawImage(buffer, 0, 0, this);
		}
	}
}

Warum zeichnet er ein Rechteck und nicht eine Ellipse?
 
S

SlaterB

Gast
wo ist jetzt eigentlich ein funktionierendes Beispiel mit Rechteck?
der obige Code enthält jedenfalls unendlich viele Fehler, würde bei mir auch mit Rechteck lange Zeit nicht gehen

fängt mit
> new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
an, was bei mir gar nicht bemalbar ist,
besser wieder
> buffer = (BufferedImage) (this.createImage(300, 300));
das geht,
welches davon theorerisch besser/ benutzbar ist, kann ich nicht sagen,
ich kann nur debuggen dass ersteres nicht (auf gleiche Weise) bemalbar ist, sondern sich als dicker schwarzer Klotz darstellt ;)
vielleicht ist es ja im JApplet nicht so, mag sein

edit: ok hier habe ich übertrieben, das funktioniert doch, wenn die folgenden Befehle korrekt sind,
new BufferedImage(300,300,BufferedImage.TYPE_INT_RGB);
ist also denkbar,
> osg.setBackground(Color.WHITE);
alleine hilft allerdings nicht allzu weit, da musst du schon einen 300x300 Kasten in weiß malen um das Anfangs-Schwarz zu übermalen

----------


dann ist boolean initialisation immer false, Initialization() wird also nie ausgeführt,
das ist doch babyleicht nachzuvollziehen?
du hast ja sogar schon
> System.out.println("Initialization");
drin, es müsste dir nur noch auffallen, dass diese Meldung nie kommt


selbst wenn das einmal ausgeführt werden würde, steht dein
g.drawImage()-Aufruf auch in diesem if, wird also maximal einmal ausgeführt, danach nie wieder,

und schließlich zur eigentlichen Elipse:
> new Ellipse2D.Float(20 * ScalingFactor, 40 * ScalingFactor, ElipseSize, ElipseSize);
überlegst du eigentlich und prüfst du nach, was das bedeutet?

die ersten beiden Parameter sind die Position x und y, das sind hier 400 und 800,
das ist doch völlig außerhalb jedem sichtbaren Bereichs wenn das Bild nur 300x300 groß ist..

Code:
public class BallRoom2TestMain extends JFrame implements ActionListener {
	private final int WIDTH = 350;
	private final int HEIGHT = 300;
	private PaintSurface2Test canvas;
	private JButton init;
	private JPanel control;

	public BallRoom2TestMain() {
		this.setSize(WIDTH, HEIGHT);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);

		canvas = new PaintSurface2Test();
		this.add(canvas, BorderLayout.CENTER);
		control = new JPanel();
		init = new JButton("init");
		init.addActionListener(this);
		control.add(init);
		this.add(control, BorderLayout.SOUTH);
	}

	public void update(Graphics g) {
		paint(g);
	}

	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == init) {
			canvas.initialization = true;
			canvas.repaint();
		}
	}

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

class PaintSurface2Test extends JComponent {
	int d = 20; // the diameter of the ball
	boolean created = false;
	boolean initialization = true;

	final float ScalingFactor = 20;
	final float ElipseSize = 20;

	BufferedImage buffer = null;// = new BufferedImage(300, 300,
	// BufferedImage.TYPE_INT_ARGB);
	Graphics2D osg;

	public PaintSurface2Test() {
		System.out.println("I'm in PaintSurface2 constructor");
		setBorder(BorderFactory.createLineBorder(Color.RED));
		System.out.println("I'll leave PaintSurface2 constructor");
	}

	public void Initialization() {
		System.out.println("Initialization");
		buffer = (BufferedImage) (this.createImage(300, 300));
		osg = buffer.createGraphics();
		// osg.setBackground(Color.WHITE);
		osg.drawLine(10, 10, 40, 40);
		osg.setColor(Color.GREEN);
		Shape molecule = new Ellipse2D.Float(2 * ScalingFactor, 2 * ScalingFactor, ElipseSize,
				ElipseSize);
		osg.fill(molecule);
		// osg.draw(molecule);
		// System.out.println("count " + ++count);
	}

	@Override
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		if (initialization == true) {
			Initialization();
			initialization = false;

		}
		g.drawImage(buffer, 0, 0, this);
	}
}

statt
if (initialization == true) {

übrigens besser
if (buffer == null) {
testen
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Überlagern von Strings beim zeichnen verhindern Spiele- und Multimedia-Programmierung 3
E relevanter bereich einer isometrischen karte zeichnen (AffineTransform) Spiele- und Multimedia-Programmierung 0
SaftigMelo Kreissegment zeichnen Spiele- und Multimedia-Programmierung 2
E Buttons neu zeichnen im GridLayout Spiele- und Multimedia-Programmierung 2
A Zeichnen außerhalb der paint-Methode Spiele- und Multimedia-Programmierung 6
E Isometrische Tiles mit unterschiedlicher Größe an korrekter Position zeichnen Spiele- und Multimedia-Programmierung 1
Androbin Mein Spiel will sich nicht zeichnen lassen !!! Spiele- und Multimedia-Programmierung 7
J Int Wert auf JFrame zeichnen Spiele- und Multimedia-Programmierung 3
H [ANIMATION] Hintergrundbild nur einmal zeichnen Spiele- und Multimedia-Programmierung 3
R [lwjgl] Cursor -> versetzt Zeichnen / Bild ist umgedreht Spiele- und Multimedia-Programmierung 2
M Methoden eine Map zu zeichnen Spiele- und Multimedia-Programmierung 5
aze Nicht rechteckiges Bild zeichnen Spiele- und Multimedia-Programmierung 5
F nur Ausschnitt eines Image zeichnen Spiele- und Multimedia-Programmierung 9
T 3D Graphen Zeichnen Spiele- und Multimedia-Programmierung 19
F Kurven zeichnen Spiele- und Multimedia-Programmierung 2
E Keine Werte zum Zeichnen werden Übergeben Spiele- und Multimedia-Programmierung 3
A Halbkreise zeichnen lassen? Spiele- und Multimedia-Programmierung 2
F Lineal mit Zahlen zeichnen Spiele- und Multimedia-Programmierung 7
N Linie mit Rand zeichnen Spiele- und Multimedia-Programmierung 10
A Mehrere geometrische Objekte in JPanel zeichnen Spiele- und Multimedia-Programmierung 4
A Optimiertes Zeichnen - wie? Spiele- und Multimedia-Programmierung 8
data89 Koordinaten in Koordinatensystem zeichnen Spiele- und Multimedia-Programmierung 11
M Binärbaum ohne Überlappung zeichnen Spiele- und Multimedia-Programmierung 3
H Decke zeichnen mit Hilfe eines Polygons Spiele- und Multimedia-Programmierung 2
B 1)JButtons zeichnen 2)Kolisionsabfrage von zwei Objekten Spiele- und Multimedia-Programmierung 9
G Linie im Applet zeichnen Spiele- und Multimedia-Programmierung 5
G Schüsse zeichnen, Fehler? Spiele- und Multimedia-Programmierung 3
S Dreieck zeichnen Spiele- und Multimedia-Programmierung 9
C Objekt bei Buttonklick zeichnen Spiele- und Multimedia-Programmierung 16
G Geschwungene Klammer zeichnen Spiele- und Multimedia-Programmierung 5
J Zeichnen in BufferedImage und dieses in Datei speichern Spiele- und Multimedia-Programmierung 2
O Funktion zeichnen Spiele- und Multimedia-Programmierung 11
A Lissajous Figuren zeichnen Spiele- und Multimedia-Programmierung 1
G Maus springt --> Free-Hand-Zeichnen Spiele- und Multimedia-Programmierung 2
L Schüsse zeichnen Spiele- und Multimedia-Programmierung 13
M Eigene Strings zeichnen Spiele- und Multimedia-Programmierung 4
T Blitz berechnen und zeichnen Spiele- und Multimedia-Programmierung 13
M auswahlkreis zeichnen (schräg) Spiele- und Multimedia-Programmierung 4
N Logik: Grenz-/Frontlinie zeichnen Spiele- und Multimedia-Programmierung 4
M Grafikprogramm, zeichnen mit Maus Spiele- und Multimedia-Programmierung 7
G Problem beim Zeichnen von LineArrays Spiele- und Multimedia-Programmierung 9
P linie in bild zeichnen Spiele- und Multimedia-Programmierung 2
G Auf 3D Box zeichnen Spiele- und Multimedia-Programmierung 4
K mit Canvas übereinander zeichnen Spiele- und Multimedia-Programmierung 4
G 3D Raum zeichnen Spiele- und Multimedia-Programmierung 7
H Kreis zeichnen mittels Schleife & drawLine Spiele- und Multimedia-Programmierung 4
B Probleme beim zeichnen Spiele- und Multimedia-Programmierung 15
N Bild zu zeichnen (drawImage) klappt nur manchmal?? Spiele- und Multimedia-Programmierung 8
T Effizient zeichnen Spiele- und Multimedia-Programmierung 12
H mit Java2D Markierung über JTable zeichnen und diese bewegen Spiele- und Multimedia-Programmierung 2
C Graphische Benutzerschnittstelle, Problem beim Zeichnen Spiele- und Multimedia-Programmierung 4
J schnellste alternative um in java zu "zeichnen" Spiele- und Multimedia-Programmierung 17
conan2 Objekte in richtiger Z-Reihenfolge zeichnen Spiele- und Multimedia-Programmierung 2
G Punkte in Java3D zeichnen Spiele- und Multimedia-Programmierung 2
S Pixel zeichnen Spiele- und Multimedia-Programmierung 3
S Bild in Speicherbild zeichnen = Nichts? Spiele- und Multimedia-Programmierung 3
G Farbig zeichnen ohne java.awt.Color? Spiele- und Multimedia-Programmierung 5
S Wie kann ich das Zeichnen der Grafik feiner machen? Spiele- und Multimedia-Programmierung 9
M Wie kann man Kreisringe zeichnen ? Spiele- und Multimedia-Programmierung 12
C Graphics 2D Zeichnen Spiele- und Multimedia-Programmierung 4
R Kreuz lässt sich nicht zeichnen Spiele- und Multimedia-Programmierung 11
F einzelne Polygone(Graphics) schneller als and. Fig. zeichnen Spiele- und Multimedia-Programmierung 3
K Kugeln und Zylinder zeichnen Spiele- und Multimedia-Programmierung 4
L ein Rechteck zeichnen Spiele- und Multimedia-Programmierung 6
Z Zugriff von externe Programme verhindern Spiele- und Multimedia-Programmierung 9
D Kollision verhindern Spiele- und Multimedia-Programmierung 2
P Browsergame - Cheaten verhindern Spiele- und Multimedia-Programmierung 12

Ähnliche Java Themen

Neue Themen


Oben