# Punktesetzen auf weißem Hintergrund



## napwatcher (17. Jun 2008)

*Liebe Javafreunde,*

habe hier mein altes Standardproblem in Java wiederentdeckt: "BufferedImage"

Also ich möchte gerne ( so schnell wie möglich ) einen *Funktionsgraphen auf weißem Hintergrund zeichnen* und dabei entweder:
*a) drawline verwenden* ( wenn es das Schnellste ist ?) und auf den Grafikkontext des JPanels direkt zeichnen
oder
*b) image.setrgb vom BufferedImage*, welches ich auf das JPanel setze.

Folgenden Code habe ich fabriziert, weil ich Möglichkeit b) bevorzuge (vielleicht schneller - ich finde das jedenfalls schöner).
Leider bekomme ich immer diesen schwarzen Hintergrund. Habe im Netz geforscht und es ergab sich, dass ich wohl nur TYPE_INT_RGB in TYPE_INT_ARGB ändern müsste, aber das hat auch nicht geholfen, denn dann zeichnet er gleichmal gar nichts.

Wenn jemand das schonmal umgesetzt hat, freu ich mich über Lösungsvorschläge!





```
public class PlotPanel extends JPanel 
{ 
    private double ymin;
    private double ymax;
    private double[] tabelle;
    BufferedImage image;
    Dimension d;
    
    public PlotPanel(EingabeDaten Eingabe) {
        d = Toolkit.getDefaultToolkit().getScreenSize();
        ymin = Eingabe.ymin;
        ymax = Eingabe.ymax;
        tabelle = Eingabe.tabelle;
        image = new BufferedImage(d.width,d.height, BufferedImage.TYPE_INT_RGB);
        updateImage();
    }
    
  @Override 
  protected void paintComponent( Graphics g ) 
  { 
      super.paintComponent(g);
      Graphics2D g2 = (Graphics2D) g; 

      g2.drawImage(image,0,0,this);
  } 
  
  public void updateImage() {
      int dummy;
      for (int i=0; i < image.getHeight(); i++) {
          image.setRGB(image.getWidth()/2, i, 444);
      }
      for (int i=0; i < image.getWidth(); i++) {
          image.setRGB(i, image.getHeight()/2, 444);
      }
      for (int i=1; i < image.getWidth(); i++) { // bei 1 beginnen!!!!!!      
        dummy = (int) (( (tabelle[i]-ymax)/(ymin-ymax) )*image.getHeight());
        image.setRGB(i, dummy, 555577);
      }

  }
```


----------



## Quaxli (18. Jun 2008)

Leider hast Du kein lauffähiges Programm gepostet, so daß man nicht erkennen kann, woran letzten Endes der Fehler liegt, z. B. ob Zeil 10 Sinn mach, wo Du die Größe des Bildschirms abfragst oder ob es an den Daten der Klasse Eingabedaten liegt. 
Ich hab' mal an Deinem Programm rumgefrickelt und einen Frame außen rum gebastelt. So hast Du zumindest ein lauffähiges Beispiel, von dem Du übernehmen kannst, was Dir sinnvoll erscheint. 


```
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

public class PlotPanel extends JPanel {

	private static final long	serialVersionUID	= 1L;

	BufferedImage			image;
	Dimension					d;
	
  public static void main(String[] args) {
    new PlotPanel();
	}

	public PlotPanel() {
    JFrame frame = new JFrame("Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400,400);
    frame.setLocation(100,100);
    frame.setResizable(false);
    frame.add(this);
    frame.setVisible(true);

    //Image erst hier, damit die Breite aus dem JPanel genommen werden kann.
    image = new BufferedImage(getWidth(),getHeight(), BufferedImage.TYPE_INT_RGB);
		updateImage();
		//dann natürlich noch einen repaint.
		frame.repaint();

	}

	@Override
	protected void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(image, 0, 0, this);
	}

	public void updateImage() {

		Graphics gb = image.createGraphics();
		gb.setColor(Color.BLUE);
		
		//so ist's kürzer
		gb.drawLine(getWidth()/2, 0, getWidth()/2, getHeight());
		gb.drawLine(0,getHeight()/2,getWidth(),getHeight()/2);
		
		//Jetzt die Punkte mit einer beliebigen Funktion
		for (int x = 0; x < image.getWidth(); x++) { 
			int y = x/2;
		  image.setRGB(x,y,Color.GREEN.getRGB());
		}

	}
}
```


----------



## Wildcard (18. Jun 2008)

> Graphics gb = image.createGraphics();


Danach aber dispose aufrufen!


----------



## Quaxli (18. Jun 2008)

Hatte ich vergessen. Danke.


----------



## napwatcher (18. Jun 2008)

@Quaxli
Danke für Deinen Vorschlag - leider zeichne ich damit weiterhin Linien und Punkte auf SCHWARZEM Hintergrund.
Wie geht dasselbe denn auf weißem Hintergrund?[/img]


----------



## Quaxli (18. Jun 2008)

Ein Blick in die API zum Graphics-Object hätt's auch getan 


```
public void updateImage() {

		Graphics gb = image.createGraphics();
		gb.setColor(Color.WHITE);
		gb.fillRect(0,0,getWidth(),getHeight());
		gb.setColor(Color.BLUE);
		
		//so ist's kürzer
		gb.drawLine(getWidth()/2, 0, getWidth()/2, getHeight());
		gb.drawLine(0,getHeight()/2,getWidth(),getHeight()/2);
		
		//Jetzt die Punkte mit einer beliebigen Funktion
		for (int x = 0; x < image.getWidth(); x++) { 
			int y = x/2;
		  image.setRGB(x,y,Color.GREEN.getRGB());
		}
		
		gb.dispose();

	}
```


----------



## napwatcher (18. Jun 2008)

```
gb.setColor(Color.WHITE);
      gb.fillRect(0,0,getWidth(),getHeight());
```

ja eigentlich wollte ich genau diese zwei Zeilen umgehen!

Es wäre doch viel praktischer einen weißen Hintergrund zu nehmen und nicht extra einen schwarzen weiß zu machen!
(aus Performance-Perspektive)

Dann setze ich doch lieber gleich meine Grafik direkt aufs JPanel, welches ich vorher mit this.setBackgroundColor(); weiss färbe und bin genauso weit. (oder bewirkt setBackgroundColor intern einen Aufruf von fillRect , keine Ahnung)

Also wer noch eine andere Möglichkeit kennt, bitte melden![/code]


----------



## Illuvatar (18. Jun 2008)

Natürlich bewirkt setBackgroundColor intern einen aufruf von fillRect. Wie soll da sonst weiß hinkommen? Wenn du ein Bild erstellst, ist erstmal überall der Default-Wert, d.h. (0/0/0/0), d.h. schwarz. Wenn da was anderes hinsoll, musst du die Werte ändern. Ob du das mit fillRect oder sonstwas machst ist wurscht, nur wird alles andere sicher irgendwie auf fillRect zurückgeleitet.


----------



## Quaxli (18. Jun 2008)

Mal davon abgesehen, daß es auf fillRect zurück fällt:
Je nachdem, wie Deine Formel zum Erstellen der Kurve aussieht, wäre ein Zeichnen direkt im Panel noch viel unperformanter, da Du die paintComponent-Methode überschreiben müßtest und bei jedem repaint (gewollt oder nicht) würde die ganze Rechnerrei wieder loslaufen oder zumindest die komplette Zeichenoperation durchlaufen werden, falls Du die Punkte anderweitig speichern würdest.


----------



## napwatcher (18. Jun 2008)

Danke, werd also dann das BufferedImage vorziehen und mit fillrect arbeiten.


----------

