# Bild zeichnen



## Souljumper (18. Mrz 2006)

Ich versteh diese ganze Logik von der dieser beknackten paint-Methode nicht. In allen Biespielen wird die Methode nicht aufgerufen, aber angeblich soll das Bild als hintergrund ausgegeben werden. 

Bei meinem code klappt das nicht:

```
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.ImageObserver;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.SpringLayout;

import sun.awt.RepaintArea;

public class Login {
		
	public static void main(String[] args) {
		JFrame frame;
		JLabel acctxt;
		JLabel passtxt;
		JTextField acc;
		JPasswordField pass;
		JButton ok;
		JButton abort;
		JPanel panel;
		SpringLayout layout;
		
		acctxt = new JLabel("Account:");
		acc = new JTextField(20);
		passtxt = new JLabel("Passwort:");
		pass = new JPasswordField(20);
		ok = new JButton("Login");
		abort = new JButton("Abbruch");
		
		panel = new JPanel();
		layout = new SpringLayout();
		//Zeile 1 - Account
		layout.putConstraint(SpringLayout.WEST,acctxt,5,SpringLayout.WEST,panel);
		layout.putConstraint(SpringLayout.NORTH,acctxt,5,SpringLayout.NORTH,panel);
		layout.putConstraint(SpringLayout.WEST, acc,13,SpringLayout.EAST, acctxt);
		layout.putConstraint(SpringLayout.NORTH,acc,5,SpringLayout.NORTH,panel);
		
		//Zeile 2 - Passwortfeld
		layout.putConstraint(SpringLayout.WEST,passtxt,5,SpringLayout.WEST,panel);
		layout.putConstraint(SpringLayout.NORTH,passtxt,30,SpringLayout.NORTH,panel);
		layout.putConstraint(SpringLayout.WEST, pass,5,SpringLayout.EAST, passtxt);
		layout.putConstraint(SpringLayout.NORTH,pass,30,SpringLayout.NORTH,panel);
		
		frame = new JFrame("Login");
	
		
		
		//Zeile 3 - Buttons
		layout.putConstraint(SpringLayout.WEST,ok,75,SpringLayout.WEST,panel);
		layout.putConstraint(SpringLayout.NORTH,ok,55,SpringLayout.NORTH,panel);
		layout.putConstraint(SpringLayout.WEST, abort,50,SpringLayout.EAST, ok);
		layout.putConstraint(SpringLayout.NORTH,abort,55,SpringLayout.NORTH,panel);
	
		panel.setLayout(layout);
			
		panel.add(acctxt);
		panel.add(acc);
		panel.add(passtxt);
		panel.add(pass);
		panel.add(ok);
		panel.add(abort);
	
		
		frame.setContentPane(panel);

		frame.pack();
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setSize(310,120);
		frame.setVisible(true);

	}
	
	public void paint(Graphics g)
	{
		Image pic;
		pic = Toolkit.getDefaultToolkit().getImage("hintergrund.jpg");
		g.drawImage(pic,0,0,(ImageObserver) this);
	}


}
```

Wie geht das? bzw. was mach ich falsch?


----------



## André Uhres (18. Mrz 2006)

Das Bild darf nicht in der Methode _paint(..)_ gezeichnet werden. _paint(..)_ ist im Wesentlichen
eine Kombination von _paintComponent_, _paintBorder _und _paintChildren_. Davon ist aber nur _paintComponent_ 
für den Hintergrund zuständig.

Die Methode _paintComponent(..)_ wird automatisch aufgerufen wenn die Komponente neu gezeichnet wird,
z.B. wenn sie das erstemal erscheint (durch _frame.setVisible(true);_), oder wenn sie durch einen anderen Frame versteckt 
und dann wieder aufgedeckt wird, oder auch wenn du _panel.repaint()_ aufrufst.
Sie überschreibt die Methode _paintComponent(..)_ der Klasse _JComponent_: die Klasse in der sie steht
muss also von einem _JComponent_ abgeleitet sein, meistens mit _extends JPanel_ (siehe unten: Klasse _Background_).

```
/*
 * Login.java
 */
import java.awt.*;
import java.awt.image.*;
import javax.swing.*;
public class Login {
    public Login(){
        pic = Toolkit.getDefaultToolkit().getImage("hintergrund.jpg");
        acctxt = new JLabel("Account:");
        acc = new JTextField(20);
        passtxt = new JLabel("Passwort:");
        pass = new JPasswordField(20);
        ok = new JButton("Login");
        abort = new JButton("Abbruch");
        abort.addActionListener(new ActionListener()
           {public void actionPerformed(ActionEvent e){exit();}});
        
        panel = new Background();    // <------------------------------------
        layout = new SpringLayout();
        //Zeile 1 - Account
...
... was hier noch dazwischen gehört hab ich ausgelassen: es bleibt unverändert
...
        frame.setVisible(true);
    }
    private void exit(){frame.dispose();}
    private JFrame frame;
    private JLabel acctxt, passtxt;
    private JTextField acc;
    private JPasswordField pass;
    private JButton ok, abort;
    private SpringLayout layout;
    private Background panel;    // <------------------------------------
    private Image pic;
    public static void main(String[] args){new Login();}
    class Background extends JPanel{    // <------------------------------------
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(pic,0,0,(ImageObserver) this);
        }
    }
}
```


----------



## Souljumper (18. Mrz 2006)

Danke, funktioniert.


----------



## Souljumper (18. Mrz 2006)

Kleinigkeit hab ich dann doch noch.

Der Aufbau meines Fensters ist etwas unschön. Es wird erst das Fensteraufgebaut mit Buttons und Eingabefelder und knappe ne halbe Sekunde später wird das Hintergrundbild erst gesetzt. 

Wie kann ich erreichen das mein Fenster erst angezeigt wird wenn es komplett fertig aufgebaut ist?


----------



## Leroy42 (18. Mrz 2006)

Das Problem ist das Bild selbst. Durch

```
pic = Toolkit.getDefaultToolkit().getImage("hintergrund.jpg");
```

wird das Laden des Bildes nur _initiiert_, d.h. wenn die Methode beendet
ist, ist das Bild noch lange nicht fertig geladen.

Hierfür gibt es den *MediaTracker*. Du packst daß mit getImage() erzeugte,
aber noch nicht vollständig geladene, Bild in einen MediaTracker und rufst hierauf
dann die Methode _waitFor_ auf.

Mit den Stichwörtern *MediaTracker* und *waitFor* solltest du in der
Forensuche schnell zu lauffähigem Beispielcode gelangen.


----------



## André Uhres (18. Mrz 2006)

```
import java.io.*;
import javax.imageio.*;
...
        try {
            pic = ImageIO.read(new File("hintergrund.jpg"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
```


----------



## Guest (20. Mrz 2006)

André Uhres hat gesagt.:
			
		

> ```
> import java.io.*;
> import javax.imageio.*;
> ...
> ...



Cool, vielen Dank  :toll:


----------

