AWT mehrere Bilder in einen Frame zeichnen + Layout Manager

Furtano

Mitglied
Hallo,

ich möchte mehrere Bilder und Histogramme in einen Frame zeichnen und diese sollen alle dem LayoutManager (GridBagLayout) übergeordnet sein. Es soll dann proportional skaliert werden und gibt noch einige Besonderheiten.

Wie mach ich das am Besten? Jedes Bild nen eigenes Panel, die Panels den Layout zuweisen und dann das Panel zeichnen?
Ich möchte nur AWT und nicht SWING benutzen.
Java:
package htw;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class Fenster extends Frame {
	
	public Fenster(String pfad) {
		this.pfad = pfad;
	}
		
	private String pfad;
	
	// This method returns an Image object from a buffered image
	public static Image toImage(BufferedImage bufferedImage) {
	    return Toolkit.getDefaultToolkit().createImage(bufferedImage.getSource());
	}
	
	public void update(Graphics g) { //Example2409.java
		   paint(g);
		}
	@Override
	public void paint(Graphics g) {
		super.paint(g);
		
		
		Color linie = new Color (255,0,255);
		Image foto2 = null;
		g.setColor(linie);
		Dimension windowSize = this.getSize();
		int heigth = (int) windowSize.getHeight();
		int width = (int) windowSize.getWidth();
		BufferedImage foto = null;
		
		try {
			foto = BufferImage.drawthePicture(pfad);
			
			foto2 = toImage(foto);
			// Skaliert das Bild auf best. Maße, 2 = FAST_SCALING
			foto2 = foto2.getScaledInstance(width, heigth , 2);
			

			g.drawImage(foto2, 0, getheigthTitlebar(), this);
			
			// Groesse des aktuellen Fensters
			
			g.drawString(String.valueOf(windowSize.getHeight()), 100, 100);
			//g.drawLine(0, getheigthTitlebar(), 400, 200);
			
			
		} 
		
		catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		

	}
	
	// Gibt die Hoehe der Titlebar wieder, um korrekt zu zeichnen
	public int getheigthTitlebar (){
		return this.getInsets().top;
	}
	
}
 
Grundsätzlich würde ich die paint eines Frames nicht überschreiben. Besser ein Panel in den Frame packen und dessen paint überschreiben.
Wie mach ich das am Besten? Jedes Bild nen eigenes Panel, die Panels den Layout zuweisen und dann das Panel zeichnen?
Panel kann nichts mit Bildern anfangen, nimm eine Label und weise das Bild als Icon zu.
Ich möchte nur AWT und nicht SWING benutzen.
Warum?
 
Panel kann nichts mit Bildern anfangen, nimm eine Label und weise das Bild als Icon zu.
Eher nicht. Nehm lieber für jedes Bild nen Canvas und füge diese dann den Frame mit GBL hinzu, da das Vergrößern von Bildern in Labels nicht besonders gut ist ( Performance & Qualität).
 
Panel kann nichts mit Bildern anfangen...

Man kann doch aber ein Panel schreiben, was Bilder zeichnen kann.
Beispiel:
Java:
import java.awt.*;

public class ImagePanel extends Panel {
   private Image image;

   /**
    * Erzeugt ein neues, leeres ImagePanel, mit der Fähigkeit, nach Übergabe eines
    * Image-Objektes ein Bild zu zeichnen.
    */
   public ImagePanel() {
      super();
   }
   
   /**
    * Erzeugt ein neues ImagePanel, welches als Argument ein Image-Objekt
    * zur Darstellung erwartet.
    * @param image das Image-Objekt, welches vom ImagePanel dargestellt werden soll.
    */
   public ImagePanel(Image image) {
      this();
      this.image = image;
   }
   
   /**
    * Setzt per Übergabe eines Image-Objektes ein Bild in dieses Panel.
    * @image das Bild, welches vom Panel dargestellt werden soll.
    */
   public void setImage(Image image) {
      this.image = image;
      repaint();
   }
   
   public void paint(Graphics g) {
      super.paint(g);
      if(image != null) {
         g.drawImage(image, 0, 0, this);
      }
   }
}
 
Oh danke habe ich beherzigt und es funktioniert soweit.
Einziges Problem: die gezeichnete rote Linie flackert wie verrückt, das jedoch Bild nicht 😵

Java:
package htw;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.IOException;

/*
 * Zeichnet ein Bild
 * @param pfad der Pfad des zu zeichnenden Bildes 
 * 
 */
public class PicturePanel extends Panel {
	
		private String pfad;
		
		public PicturePanel (String pfad){
			this.pfad = pfad;
		}

		public void update(Graphics g) { //Example2409.java
			   paint(g);
		}
		
        public void paint(Graphics g) {
        	super.paint(g);
        	// Groesse des Fensters
    		//Dimension windowSize = this.getSize();
    		//int heigth = (int) windowSize.getHeight();
    		//int width = (int) windowSize.getWidth();
    		BufferedImage foto = null;
    		Image foto2 = null;
    		
    		try {
    			
    			// Zeichentest - funktioniert das Panel ?
    			g.setColor(Color.RED);	
    			g.drawLine(0, 0, 320, 240);
    			
    			
    			/*
    			 * BILD ZEICHNEN 
    			 */
    			foto = BufferImage.drawthePicture(pfad);
    			foto2 = toImage(foto);
    			// Skaliert das Bild auf best. Maße, 2 = FAST_SCALING
    			//foto2 = foto2.getScaledInstance(width, heigth , 2);
    	
        		g.drawImage(foto2, 0, 0, this);
        		
        		// Groesse des aktuellen Fensters
        		
        		//g.drawString(String.valueOf(windowSize.getHeight()), 100, 100);
        		//g.drawLine(0, getheigthTitlebar(), 400, 200);
        		
               
              
    		} 
    		
    		catch (IOException e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    		
            this.setSize(320,240);
            
  
        }
        

		// This method returns an Image object from a buffered image
		public static Image toImage(BufferedImage bufferedImage) {
		    return Toolkit.getDefaultToolkit().createImage(bufferedImage.getSource());
		}

}


Java:
package htw;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Label;
import java.awt.Panel;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import javax.swing.ImageIcon;

public class Fenster extends Frame {
	
	   GridBagLayout gbl = new GridBagLayout();
	   GridBagConstraints gbc = new GridBagConstraints();
	   
   
	
	public Fenster(String pfad) {
		
	     setLayout(gbl);  // GridBagLayout setzen
	     gbc = makegbc(0, 0, 800, 600);
	     gbc.fill = GridBagConstraints.BOTH;
	     
	     PicturePanel bild1 = new PicturePanel(pfad);
	     gbl.setConstraints(bild1, gbc);
	     
	     this.add(bild1);
	     pack();
	}
		

	public void update(Graphics g) { //Example2409.java
		   paint(g);
		}
	@Override
	public void paint(Graphics g) {
		// verhindert das Fackern
		super.paint(g);
//		
//		GridBagLayout gbl=new GridBagLayout();
//		setLayout(gbl);
//		GridBagConstraints gbc=new GridBagConstraints();
		
		Color linie = new Color (255,0,255);
       

	}
	

	// Gibt die Hoehe der Titlebar wieder, um korrekt zu zeichnen
	public int getheigthTitlebar (){
		return this.getInsets().top;
	}
	
	private GridBagConstraints makegbc (int x, int y, int width, int heigth){
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = x;
		gbc.gridy = y;
		gbc.gridwidth = width;
		gbc.gridheight = heigth;
		gbc.insets = new Insets(1,1,1,1);
		return gbc;
		
		
	}
}
 
Zuletzt bearbeitet:
Versuch das ganze mal mit Swing umzusetzen, anstatt mit AWT. Swing unterstützt standardmäßig double buffering, evtl. löst das schon dein flackern.
 
Kenn mich jetzt in AWT nicht so gut aus wie in Swing, würde aber mal die beiden update Methoden, sowie die paint vom Frame entfernen. Ich denke das wird das Flackern schon beheben.
Zudem würde ich die Bilder ganz einfach per
Code:
ImageIO.read(bildURL);
laden.
 

Zurück
Oben