Bild als Hintergrund für die GUI


#1
Moin an alle,

ich hoffe ich find hier ein Paar, die einem Anfänger der objektorientierten Programmierung weiterhelfen können.

Bevor ich aber zu meiner Frage komme, erst einmal, was ich überhaupt vor habe zu programmieren:

Ich will ein Prog mit grafischer Benutzeroberfläche erstellen, mit der ich in ganz Deutschland, Österreich und der Schweiz die Skigebiete mit den dazugehörigen Infomationen, wie z.B. Bild, Öffnungszeiten, etc. auslesen kann.

Mit dem Schulwissen komm ich nur bis zu einem gewissen Punkt, doch mein erstes Problem ist:
Ich habe mit Hilfe von Photoshop ein Bild erstellt. Dieses Bild (.jpg) würde ich gern als Hintergrundbild für meine GUI verwenden. Bevor ich mit der Programmierung beginne, würd ich gerne wissen, ob ich eine zusätzliche Class erstellen muss, oder ob ich das Bild mit angabe des Pfades und einer bestimmten Methode in meiner Klasse für die GUI (die sich dann "Hauptfenster" nennt) aufrufen kann?

Ich hoffe, Ihr habt mein Problem verstanden und könnt mir im vorraus helfen, ansonsten beginne ich heute mit meinem Projekt und fragen dann noch einmal...

Mit freundlichen greez

merTii
 
#5
Oh klar, tut mir leid bin heute um 2:00 Uhr in der Nacht drauf gekommen:D

Im Prinzip ist das ja gar nicht schwer...

Die GUI erstellen, ein JLabel aufziehen und dann folgendes:

Code:
Image image = Toolkit.getDefaultToolkit().createImage("Pfad");
btBild = new JLabel(new ImageIcon(image));
btBild.setBounds(new Rectangle(2, 2, 699, 434));
btBild.setText("JLabel");
Die relevanten Zeilen sind die erste und zweite:D
 
#6
Ich hab noch eine weitere Frage, hoff ich kann sie auch hier stellen...und zwar habe ich nun ein Bild als Hintergrund, worauf zwei Buttons erscheinen sollten, aber wenn ich mein Prog ausführe, so erscheinen meine Buttons nur, wenn ich mit der Maus drüber fahre...könnt ihr mir da helfen`?
 

Akeshihiro

Erfahrenes Mitglied
#7
Dafür wirst du schon den Code posten müssen ^^

EDIT:
Hab mal spaßeshalber was zusammengekloppt, das ein Hintergrundbild zeichnet und zwei Buttons hinzufügt, also eigentlich das, was du gemacht hast (hatte grad eh nix zu tun). Funktioniert so wie es soll. Hier mal der Code, Kommentare sind drin.

Java:
package de.tutorials.forum.hilfe.mertii.bgimage;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

/**
 * Diese Klasse zeichnet ein Hintergrundbild und fügt zwei Buttons hinzu.
 * 
 * @author Akeshihiro
 */
public class BgImageSample extends JFrame {
	/**
	 * Versionkennung für die Serialisierung.
	 */
	private static final long	serialVersionUID	= 3633606108685196952L;

	/**
	 * Main-Methode.
	 * 
	 * @param args
	 *            Programmparameter.
	 */
	public static void main(String[] args) {
		new BgImageSample();
	}

	/**
	 * Default-Konstruktor.
	 */
	public BgImageSample() {
		initSettings();
		initComponents();
		initGui();
	}

	/**
	 * Initialisiert die Komponenten, die im Fenster zu sehn sein sollen.
	 */
	private void initComponents() {
		/*
		 * Neue ContentPane setzen, die das Hintergrundbild zeichnet. Hier zu
		 * Vorzeigezwecken alles in einem Schritt reingeklatscht, sollte im
		 * Normalfall sauberer implementiert werden.
		 */
		setContentPane(new JPanel() {
			/**
			 * Versionskennung für die Serialisierung.
			 */
			private static final long	serialVersionUID	= 366410619231078381L;

			/**
			 * Das Hintergrundbild.
			 */
			private Image				img;

			/*
			 * Da es sich hierbei um eine anonyme Klasse handelt, kann ich
			 * keinen expliziten Konstruktor deklarieren, daher wird das Bild in
			 * einem Initialisierer geladen.
			 */
			{
				img = getToolkit().createImage("C:/bild.jpg");

				MediaTracker mt = new MediaTracker(this);
				mt.addImage(img, 1);
				try {
					mt.waitForAll();
				} catch(InterruptedException e) {
					e.printStackTrace();
				}
			}

			/*
			 * (non-Javadoc)
			 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
			 */
			@Override
			protected void paintComponent(Graphics g) {
				g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
			}
		});

		// Zwei Buttons hinzufügen
		getContentPane().add(new JButton("bt1"));
		getContentPane().add(new JButton("bt2"));
	}

	/**
	 * Größe und Position festlegen und sichtbar machen.
	 */
	private void initGui() {
		setSize(500, 500);
		setLocationRelativeTo(null);
		setVisible(true);
	}

	/**
	 * Setzt ein paar grobe Einstellungen.
	 */
	private void initSettings() {
		setTitle(getClass().getName());
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		// Das Metal-LAF sieht beknackt aus, lieber das Systemeigene LAF nehmen
		try {
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		} catch(ClassNotFoundException e) {
			e.printStackTrace();
		} catch(InstantiationException e) {
			e.printStackTrace();
		} catch(IllegalAccessException e) {
			e.printStackTrace();
		} catch(UnsupportedLookAndFeelException e) {
			e.printStackTrace();
		}
	}
}
 
Zuletzt bearbeitet:
#8
Aus Gründen der Übersicht poste ich nur mal den Teil für meinen Button:

Code:
private JButton getBtRegistrieren() {
		if (btRegistrieren == null) {
			btRegistrieren = new JButton();
			btRegistrieren.setBounds(new Rectangle(267,352, 158,37));
			btRegistrieren.setText("Registrieren");
			btRegistrieren.addActionListener(new java.awt.event.ActionListener() {
				
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()");
					;
					
				}
Falls es mehr nötig ist, kann ich auch mehr posten...
Ich denke wichtig ist " setVisible(true)"...die Frage ist nur wo ich dies Einfügen muss?
 

Akeshihiro

Erfahrenes Mitglied
#9
das setVisible() kannste bei Komponenten weglassen, die sind üblicherweise sichtbar, sobald man sie hinzufügt. Die Frage ist eher wie und wann du deine Buttons hinzufügst.
 
#10
Okay, dann poste ich mal meine gesamte Klasse:

Code:
package paket1;

import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Image;
import java.awt.Toolkit;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JLabel;
import java.awt.Rectangle;
import javax.swing.JButton;
import java.awt.Point;

public class Hauptfenster extends JFrame {

	private static final long serialVersionUID = 1L;
	private JPanel jContentPane = null;
	private JLabel btBild = null;
	private JButton btAnmelden = null;	
	private JButton btRegistrieren = null;

	/**
	 * This method initializes btAnmelden	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBtAnmelden() {
		if (btAnmelden == null) {
			btAnmelden = new JButton();
			btAnmelden.setBounds(new Rectangle(267, 296, 158, 37));
			btAnmelden.setText("Anmelden");
			btAnmelden.addActionListener(new java.awt.event.ActionListener() {
				
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()"); 
					// TODO Auto-generated Event stub actionPerformed()
				}
			});
		}
		return btAnmelden;
	}

	/**
	 * This method initializes btRegistrieren	
	 * 	
	 * @return javax.swing.JButton	
	 */
	private JButton getBtRegistrieren() {
		if (btRegistrieren == null) {
			btRegistrieren = new JButton();
			btRegistrieren.setBounds(new Rectangle(267,352, 158,37));
			btRegistrieren.setText("Registrieren");
			btRegistrieren.addActionListener(new java.awt.event.ActionListener() {
				
				public void actionPerformed(java.awt.event.ActionEvent e) {
					System.out.println("actionPerformed()");
					;
					// TODO Auto-generated Event stub actionPerformed()
				}
			});
		}
		return btRegistrieren;
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				Hauptfenster thisClass = new Hauptfenster();
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				thisClass.setVisible(true);
			}
		});
	}

	/**
	 * This is the default constructor
	 */
	public Hauptfenster() {
		super();
		initialize();
	}

	/**
	 * This method initializes this
	 * 
	 * @return void
	 */
	private void initialize() {
		this.setSize(699, 479);
		this.setContentPane(getJContentPane());
		this.setTitle("iSnow - Alle Skigebiete auf einen Blick");
	}

	/**
	 * This method initializes jContentPane
	 * 
	 * @return javax.swing.JPanel
	 */
	private JPanel getJContentPane() {
		if (jContentPane == null) {
			
			Image image = Toolkit.getDefaultToolkit().createImage("C:/Users/Efe/Documents/Mert/GFS/Background.jpg");
			btBild = new JLabel(new ImageIcon(image));
			btBild.setBounds(new Rectangle(2, 2, 699, 434));
			btBild.setText("JLabel");
			jContentPane = new JPanel();
			jContentPane.setLayout(null);
			jContentPane.add(btBild, null);
			jContentPane.add(getBtAnmelden(), null);
			jContentPane.add(getBtRegistrieren(), null);
		}
		return jContentPane;
	}

}  //  @jve:decl-index=0:visual-constraint="10,10"
 

Akeshihiro

Erfahrenes Mitglied
#11
Tatsache, das sieht wirklich komisch aus. Aber du fügst deinen "Hintergrund" auch als Label ein, wahrscheinlich wird versucht diese auch ganz normal darzustellen. Ich würde den Hintergrund lieber wirklich im Hintergrund zeichnen (so wie ich das gemacht hab) anstatt es als Komponente einzufügen.
 
#12
Okay ich versuchs so zu machen, wie du es auch gemacht hast...

Kannst du mir sagen, mit welchem Tool du deine GUI erstellst...ich denk, du tippst ja wohl nicht alles einzelne.
 

Akeshihiro

Erfahrenes Mitglied
#14
Ich hab ne Möglichkeit gefunden, dein Problem zu lösen, aber meiner Meinung nach is das auch nich so der Hit ... Man kann nämlich den Z-Index bestimmen. Oder anders gesagt, man kann die Reihenfolge der Komponenten bestimmen, quasi als ob sie auf verschiedenen Ebenen liegen würden (so wie in Photoshop, falls das fürs Verständnis besser ist).
Dazu änderst du in der Methode getJContentPane() einfach etwas ab. Und zwar
Java:
jContentPane.add(btBild, null);
jContentPane.add(getBtAnmelden(), null);
jContentPane.add(getBtRegistrieren(), null);
gegen
Java:
jContentPane.add(btBild, 0);
jContentPane.add(getBtAnmelden(), 0);
jContentPane.add(getBtRegistrieren(), 0);
Also einfach nur null gegen 0 ersetzen. Hier würde es schon reichen das nur beim getBtRegistrieren() zu machen, aber sicherheitshalber hab ich das bei den anderen Komponenten hinzugefügt.

Also wenn ich mir den Code anschaue, dann nutzt die wohl Eclipse. Das nutze ich auch, aber ohne irgendwelche visuellen Editoren, wie z.B. VE. Am Anfang hab ich das noch gemacht, bis mir das Teil auf die Nerven ging, weil der Code immer aussah wie sonst was und seit dem tippe ich das alles von Hand. Son VE ist zwar ganz nett, vor allem wenn man was ändern will, aber man braucht ihn nicht. Abgesehn davon ordnest du damit ja nur paar Komponenten an, die Logik musst du ja dennoch selbst machen und dazu gehört auch das Zeichnen.
 
#15
Okay super es funktioniert...danke! Ich find das als JLabel einen tick besser, weil die Qualität einfach besser ist.

Jap benutze auch Eclipse, aber hab mir auch vorgenommen, viele Teile per Hand abzutippen, weil es ja mal vorkommen kann, dass kein Tool vorhanden ist, was mir alles vorsagt^^
 

Akeshihiro

Erfahrenes Mitglied
#16
Das mit der Qualität hat nichts mit dem Label zu tun, sondern liegt an der Darstellung des Bildes. Ich hab das so gemacht, dass es immer vollständig zu sehen ist, egal wie groß das Fenster gerade ist. Das heißt, es wird auch verzerrt, wenn sich eine Achse verändert. Man kann es auch in der richtigen Größe zeichnen lassen, kommt immer drauf an. Ich hatte beim Test ein Bild, bei dem es eh egal war, weil es ein Verlauf war, zwar mit angebrachter Größe, aber da merkt man eh nix, wenn sich die Größe ändert. Bei einem konkreten Bild sieht es anders aus. Dann würde ich aber ohnehin verhindern, dass man die Fenstergröße ändern kann, da sonst freie Flächen auftauchen. Andererseits muss das Bild aber auch die bestimmte Größe haben, ist es zu klein, hat man freie Flächen, ist es zu groß sieht man nur einen Ausschnitt.
 
#17
Hey :)

Ist schon etwas länger her, aber ich hoffe ihr könnt mir trotzdem weiterhelfen :D

Und zwar möchte ich meinem JFrame ein Hintergrundbild verpassen, auf diesem dann ein Button platzfinden soll.

Mit dem Code von Akeshihiro habe ich das soweit schon geschafft, nur habe ich das Problem, dass ich zwar die Größe des Buttons ändern kann, aber nicht dessen Position...

Außerdem lässt dich die Größe des Buttons nur mit dem Befehl setPreferredSize(new Dimension(x,y))) ändern, nicht aber mit setSize().

Habt ihr eine Idee wieso? :/