# Graphics2D + Bild anzeigen.



## raffnix (2. Mai 2005)

Hallo .
Ich möchte ein Bild mittels Graphics2D darstellen. 
Das Bild hole ich aus einer Jlist. 
die Methode aus einer anderen classe.
zunächst habe ich das bild mitteld Jlabel(Imageicon) angezeigt da ich aber auf dem Bild malen will. versuche ich nun zu 
Graphics2D zu wechseln.

Die Erste classe.


```
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;



public class Viewit extends JFrame {

 private DefaultListModel listdata = new DefaultListModel(); ;
 private JList liste = new JList(listdata);	
 private JLabel bildlabel = new JLabel();
 double theta;
 int a;
 int b;
 double x;
 double y;
 DrawStuff graf = new DrawStuff();
 Viewit(){
 	 
 	JMenuBar menubar = new JMenuBar();	
	setJMenuBar(menubar);
	JMenu m = new JMenu("File");
	menubar.add(m);
	JMenuItem datei = new JMenuItem("Open..");
	m.add(datei);
 	
	JScrollPane scroll = new JScrollPane(liste);
	scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
	
	JPanel bildpanel = new JPanel(new BorderLayout(4,4));
 	JPanel textpanel = new JPanel(new BorderLayout(1,1));
    JPanel listpanel = new JPanel(new BorderLayout(5,5));
	liste.setPreferredSize(new Dimension(80,500));
	
	
	liste.addListSelectionListener(new ListSelectionListener(){
		 public void valueChanged(ListSelectionEvent e){
		 	JList source = (JList)e.getSource();
		       if (source.getValueIsAdjusting())
		          return;
		       Object dat = source.getSelectedValue();
		       String path = dat.toString();		       
		       ImageIcon icon = new ImageIcon(path);
		       Image img = icon.getImage();
		      // bildlabel.setIcon(icon);                                                 
		       graf.zeigebild(img);  //at Viewit$1.valueChanged(Viewit.java:62)
		       
		 }
	});
	
    datei.addActionListener(new ActionListener() {
    
       public void actionPerformed(ActionEvent e)
       {
          JFileChooser chooser = new JFileChooser();
           chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
          chooser.showOpenDialog(null);
          String text = chooser.getSelectedFile().getAbsolutePath();
         File file =new File(text);
          listdata.removeAllElements();
          File[] files = file.listFiles();
  		for(int i =0;i<files.length;i++)
  			listdata.addElement(files[i]);
  		liste.setSelectedIndex(0);
       }
    
    });
	
	//bildpanel.add(bildlabel);
    listpanel.add(scroll);
	getContentPane().add(bildpanel, BorderLayout.CENTER);
	getContentPane().add(listpanel, BorderLayout.EAST);
	setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
	  setSize(800, 600);
	  setLocation(100, 100);
	  	
}
		
public static void main(String[] args){
	Viewit f = new Viewit();
    f.setVisible(true);
}
	
	
}
```

und die Classe mit der Methode.

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;


public class DrawStuff extends JPanel{
	Graphics graphics;
	Graphics2D g2d = (Graphics2D) graphics;
double theta;
double x;
double y;
int a;
int b;
public BufferedImage buffimg;	

public void zeigebild(Image img ){
	JFrame f = new JFrame();
	buffimg = (BufferedImage)f.createImage(img.getWidth(f),img.getHeight(f));
	g2d = buffimg.createGraphics();   //at DrawStuff.zeigebild(DrawStuff.java:33)
	g2d.drawImage(img, 0, 0, f);      
}


public void machRect2D(double x, double y){		   	   
  g2d.setColor(Color.BLACK);
  g2d.draw(new Rectangle2D.Double(x, y, 100, 80));
	}

public void drawPunkt(int a, int b){
	g2d.setColor(Color.RED);
	g2d.fillOval(a, b, 4, 4);
}

public void drehRect(double theta, double x, double y){
	AffineTransform aft = new AffineTransform();
	   aft.rotate(theta ,x ,y);
	   g2d.setTransform(aft);	
}

public Dimension getPreferredSize(){
return new Dimension(300, 200);	
}
}
```

Wenn ich nun das bild anzeigen will bekomme ich eine Nullpointer.
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
	at DrawStuff.zeigebild(DrawStuff.java:33)
	at Viewit$1.valueChanged(Viewit.java:62)

Ich weiss nicht wo hier der Fehler ist??? :cry: 
Kann mir bitte jemand helfen. (setz Hundeblick auf!) :cry:


----------



## Wildcard (2. Mai 2005)

Weil Graphics logischerweise null ist


----------



## raffnix (2. Mai 2005)

Das ging ja schnell.
muss ein tiemlich dummer fehler sein.(peinlich)  

Meinst du ich hab hier mist gebaut?

```
Graphics graphics;
   Graphics2D g2d = (Graphics2D) graphics;
```

Steige gerade erst ein in Graphics2D was ist nun genau Falsch und vorallem warum??


----------



## Wildcard (2. Mai 2005)

Graphics g;
bedeutet das du g auf null initialisierst. Danach castest du auf Graphics2D. Immer noch null.
Klar?


----------



## raffnix (2. Mai 2005)

Jaa. so langsam kommt es.... ???:L  ???:L  ???:L  ???:L  ???:L 

brauche ich Graphics graphics überhaupt??

ich nutze ja nur g2d also kann ich mir das casten doch sparen oder?
muss ich dann auch g2d einen Wert zuweisen? (Soo : Graphics g2d     < -- ist es ja auch null ..)
 wenn ja welchen denn???


----------



## Wildcard (2. Mai 2005)

L-ectron-X hat gesagt.:
			
		

> ```
> Graphics g = getGraphics();
> ```
> besorgt dir eine Referenz auf ein Graphics-Objekt, deinem "Zeichenblatt".


Man sollte nach Möglichkeit keine Graphics-Objekte speichern, sondern das g aus paintComponent verwenden.


----------



## L-ectron-X (3. Mai 2005)

Habs inzwischen wieder entfernt, noch bevor du gepostet hast. Sorry, ich war wieder mal in Gedanken bei Applets.

Edit: @Wildcard, mir ist aufgefallen, dass Du häufig Aussagen machst, die du selten begründest, was u.U. nicht hilfreich für den Fragenden ist.


----------



## raffnix (3. Mai 2005)

> besorgt dir eine Referenz auf ein Graphics-Objekt, deinem "Zeichenblatt".



sowas wie ein JPanel? ja?



> Man sollte nach Möglichkeit keine Graphics-Objekte speichern, sondern das g aus paintComponent verwenden.



was?????  :?  :?:  :?: 
nun bin ich total verwirrt. Was soll das heissen? 
sorry . hab im moment absolut keinen Plan


----------



## Wildcard (3. Mai 2005)

Überschreib paintComponent und zeichne dort.


----------



## raffnix (3. Mai 2005)

Ok.

```
public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
         JFrame f = new JFrame();
	buffimg = (BufferedImage)f.createImage(img.getWidth(f),img.getHeight(f));
	g2d = buffimg.createGraphics();   
	g2d.drawImage(img, 0, 0, f);
```

meinst du soo??

ich hab ja nun extra mehrere Methoden geschrieben. um sie auch einzeln aufrufen zu können.
ich kann doch nicht jede Methode so schreiben. dann kann ich sie doch nicht einzelln aufrufen.

AXO nebenbei.
da ich die Methode ja in einer anderen classe starte, die JFrame extends , kann ich dann nicht JFrame f  weglassen und 
das  f in drawImage durch this ersetzen??


----------



## Wildcard (3. Mai 2005)

L-ectron-X hat gesagt.:
			
		

> Edit: @Wildcard, mir ist aufgefallen, dass Du häufig Aussagen machst, die du selten begründest, was u.U. nicht hilfreich für den Fragenden ist


Das Problem ist das ich keine saubere Erklärung liefern kann warum man Graphics nicht speicher soll.
Sie verlieren nach einiger Zeit ihre Wirkung, ich hab aber noch nichts gefunden das näher auf die Probleme mit 
gespeicherten Graphics eingeht. 
Die von SUN empfohlene Methode zum zeichnen in Swing ist der Weg über die paintComponent und das versuche ich so weiterzugeben.
Wenn du eine gute Erklärung oder Link hast währe ich dir allerdings sehr verbunden  :wink: 

Warum erstellst du denn ein JFrame in paintComponent?????

```
g2d = buffimg.createGraphics();    
   g2d.drawImage(img, 0, 0, f);
```
Das ist unnötig weil du ja damit

```
Graphics2D g2d = (Graphics2D) g;
```
schon dein Graphics2D Objekt hast.


----------



## raffnix (3. Mai 2005)

> Warum erstellst du denn ein JFrame in paintComponent?????



eigentlich wolltle ich nur sehen ob ich auf ein Frame zeichnen kann weill ich ja in einer anderen classe aufrufe.

so langsam komme ich näher.
ich brauche also nur die PaintComponent  um g2d einen wert zu zuweisen.
das heisst dann ja ich kann die anderen Methoden so lassen.
geht es soo?



```
public class DrawStuff extends JPanel{

Graphics2D g2d;

public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g2d = (Graphics2D) g;
         }   


	
double theta;
double x;
double y;
int a;
int b;
public BufferedImage buffimg;	

public void zeigebild(Image img ){
	buffimg = (BufferedImage)this.createImage(img.getWidth(this),img.getHeight(this));
	g2d = buffimg.createGraphics();   
	g2d.drawImage(img, 0, 0, this);      
}
```


Wenn ja muss ich dann doch vor jedem aufrufen von zeigebild(img) auch paintComponent(Graphics g) aufrufen.?

pssollte man nach jedem draw(wasauch immer) repaint() aufrufen?)


----------



## Wildcard (3. Mai 2005)

Alles was jetzt gezeichnet werden soll rufst du von der paintComponent Methode auf, und reichts das graphics objekt weiter.
Die paintComponent selbst rufst du nicht direkt auf, sondern mit repaint()


----------



## raffnix (3. Mai 2005)

me <-- versteht gar nix...

kannst du mir mal so einen Aufruf aufschreiben?
ist das so jetzt richtig in der Classe DrawSuff???


----------



## raffnix (3. Mai 2005)

also ich hab es jetzt so versucht . Aber ein bild wird immer noch nicht angezeigt.

```
liste.addListSelectionListener(new ListSelectionListener(){
		 public void valueChanged(ListSelectionEvent e){
		 	JList source = (JList)e.getSource();
		       if (source.getValueIsAdjusting())
		          return;
		       Object dat = source.getSelectedValue();
		       String path = dat.toString();		       
		       ImageIcon icon = new ImageIcon(path);
		     final  Image img = icon.getImage();
		       JPanel bildpanel = new JPanel(new BorderLayout(4,4)){
		       protected void paintComponent(Graphics g) {
		         super.paintComponent(g);
		        g2d = (Graphics2D) g;
		        BufferedImage buffimg;
		        buffimg = (BufferedImage)this.createImage(img.getWidth(this),img.getHeight(this));
		    	g2d = buffimg.createGraphics();   
		    	g2d.drawImage(img, 0, 0, this); 
		         }   
		       };
		       getContentPane().add(bildpanel, BorderLayout.CENTER);
		       
		       
		 }
	});
```

was ist denn un hier falsch??


----------



## Wildcard (3. Mai 2005)

Welches Bild sollte denn damit angezeigt werden?  :bahnhof:


----------



## raffnix (3. Mai 2005)

```
final  Image img = icon.getImage();
```

dieses..
möchte die Methode paint component eigenlich auch gar nicht so aufrufen. aber so wie ich es vorher probiert habe hat es einfachnicht geklappt.



> Alles was jetzt gezeichnet werden soll rufst du von der paintComponent Methode auf, und reichts das graphics objekt weiter.
> Die paintComponent selbst rufst du nicht direkt auf, sondern mit repaint()


kannst du mir das ochmal erklären dann versuch ich es nochmal über die andere Classe.


----------



## Wildcard (3. Mai 2005)

Einfach so:

```
protected void paintComponent(Graphics g) { 
               super.paintComponent(g);    
               g2d.drawImage(img, 0, 0, this); 
               }    
             };
```
Du musst dem bildpanel aber noch eine Größe setzen da es sonst die Größe 0,0 hat und du nichts sehen kannst.


----------



## raffnix (3. Mai 2005)

Ja super so klappt es.

Ich möchte aber auf dem bild auch malen können deswegen erstelle ich ja ein BufferedImage
allerdings scheint da irgendwas falsch zu sein bei dem buffimg.

```
liste.addListSelectionListener(new ListSelectionListener(){
		 public void valueChanged(ListSelectionEvent e){
		 	JList source = (JList)e.getSource();
		       if (source.getValueIsAdjusting())
		          return;
		       Object dat = source.getSelectedValue();
		       String path = dat.toString();		       
		       ImageIcon icon = new ImageIcon(path);
		     final  Image img = icon.getImage();
		       JPanel bildpanel = new JPanel(new BorderLayout(4,4)){
		       protected void paintComponent(Graphics g) {
		         super.paintComponent(g);
		        g2d = (Graphics2D) g;
		        BufferedImage buffimg= null;
		        buffimg = (BufferedImage)this.createImage(img.getWidth(this),img.getHeight(this));
		    	g2d = buffimg.createGraphics();   
		    	g2d.drawImage(buffimg, 0, 0, this);
		         }   
		       };
		       bildpanel.setSize(500,500);
		       getContentPane().add(bildpanel, BorderLayout.CENTER);
		       
		       
		 }
	});
```

es wird einfach kein bild Angezeigt.
wie gesagt wenn ich es so mache wie du gerad geschrieben hast funktioniert es.
kann ich auch auf dem bild zeichnen wenn es kein BufferedImage ist??


----------



## Wildcard (3. Mai 2005)

Einfach nur so:

```
protected void paintComponent(Graphics g) { 
     super.paintComponent(g);    
     g.drawImage(img, 0, 0, this); 
     g.fillOval(50,50,10,10);
     }    
};
```


Ich versteh überhaupt nicht was du damit machen willst  :bahnhof: 

```
BufferedImage buffimg= null; 
              buffimg = (BufferedImage)this.createImage(img.getWidth(this),img.getHeight(this)); 
             g2d = buffimg.createGraphics();    
             g2d.drawImage(buffimg, 0, 0, this);
```


----------



## raffnix (3. Mai 2005)

Ok das heisst ich brauche kein Buffered Image um darauf zu malen.

ich wollte aus einem Image ein BufferedImage erstellen und dieses dann anzeigen.

wenn es aber mit dem malen auf dem bild auch so geht, brauche ich das ja nicht mehr.


----------



## Wildcard (3. Mai 2005)

Nein, du brauchts zum zeichnen nur ein Graphic Objekt.


----------



## raffnix (3. Mai 2005)

Danke. 
nur noch ein Problem.
wenn ich nun ein neues Bild anzeigen will.(ist ja ein Listener) passiert nix.
ich habe nun vor durch eine if abfrage zu überprüfen ob das panel leer ist und wenn nicht soll es leer gemacht werden.
ist das so in etwa der richtige weg??


----------



## Wildcard (3. Mai 2005)

Nein, du musst img ein neues Bild zuweisen und repaint aufrufen.


----------



## raffnix (3. Mai 2005)

Super ! hat alles gefunzt.
kann ich jetzt  auch in einem Mouslistener für das Bildpanel das ich erstellt habe g2d aufrufen und was zeichnen??

```
private DefaultListModel listdata = new DefaultListModel(); ;
 private JList liste = new JList(listdata);	
 private JLabel bildlabel = new JLabel();
 private Image img;
 private JPanel bildpanel;
 double theta;
 int a;
 int b;
 double x;
 double y;
 Graphics2D g2d;
 Viewit(){
 	 
 	JMenuBar menubar = new JMenuBar();	
	setJMenuBar(menubar);
	JMenu m = new JMenu("File");
	menubar.add(m);
	JMenuItem datei = new JMenuItem("Open..");
	m.add(datei);
 	
	JScrollPane scroll = new JScrollPane(liste);
	scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
	
 	JPanel textpanel = new JPanel(new BorderLayout(1,1));
    JPanel listpanel = new JPanel(new BorderLayout(5,5));
	liste.setPreferredSize(new Dimension(80,500));
	
	
	liste.addListSelectionListener(new ListSelectionListener(){
		 public void valueChanged(ListSelectionEvent e){
		 	JList source = (JList)e.getSource();
		       if (source.getValueIsAdjusting())
		          return;
		       Object dat = source.getSelectedValue();
		       String path = dat.toString();		       
		      ImageIcon icon = new ImageIcon(path);
		      img = icon.getImage();
		       bildpanel = new JPanel(new BorderLayout(4,4)){
		       protected void paintComponent(Graphics g) {
		         super.paintComponent(g);
		        g2d = (Graphics2D) g;   
		    	g2d.drawImage(img, 0, 0, this);
		    	repaint();
		         } 
		       
		       };
		       bildpanel.setSize(500,500);
		       getContentPane().add(bildpanel, BorderLayout.CENTER);
		       
		       
		 }
	});
	
    datei.addActionListener(new ActionListener() {
    
       public void actionPerformed(ActionEvent e)
       {
          JFileChooser chooser = new JFileChooser();
           chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
          chooser.showOpenDialog(null);
          String text = chooser.getSelectedFile().getAbsolutePath();
         File file =new File(text);
          listdata.removeAllElements();
          File[] files = file.listFiles();
  		for(int i =0;i<files.length;i++)
  			listdata.addElement(files[i]);
  		liste.setSelectedIndex(0);
       }
    
    });
	
    listpanel.add(scroll);
    
	getContentPane().add(listpanel, BorderLayout.EAST);
	setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); 
	  setSize(800, 600);
	  setLocation(100, 100);
	  	
}

 
public static void main(String[] args){
	Viewit f = new Viewit();
    f.setVisible(true);
}
	
	
}
```


----------



## Wildcard (3. Mai 2005)

Schau dir das mal an:
http://www.java-forum.org/de/viewtopic.php?t=17471&postdays=0&postorder=asc&start=0


----------

