JPanel mit spezifischer Breite

lgorse

Mitglied
Hallo,

ich habe ganz neu mit Java angefangen und mich gleich mal an Swing herangewagt ;). Ich hätte gerne ein JPanel, auf welches ich mit awt zeichnen kann. Das Problem ist jedoch, dass ich dem JPanel keine Breite bzw. Höhe zuweisen kann. Beim recherchieren im Internet habe ich herausgefunden, dass das Layout auf null gesetzt werden soll, damit gehts aber leider auch nicht. Hat jemand ne Idee wie das geht?

Mein Code:
PHP:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;

/**
 * Das primäre Fenster der Anwendung
 * 
 * @author lgorse
 */
public class Main extends JFrame implements ActionListener {
	private static final long serialVersionUID = 1L;
	
	/*
	 * GUI Elemente
	 */
	private JPanel panel;
	
	public Main()
	{
		super("Mein erstes Swing-Programm");
		
		/*
		 * Panel erstellen
		 */
		panel = new JPanel();
		panel.setLayout(null);
		panel.setBounds(10, 10, 300, 300);
		
		/*
		 * Panel zum Frame hinzufügen
		 */
		getContentPane().add(panel, BorderLayout.NORTH);
		
		/*
		 * Aktion zum Schließen
		 */
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
	
	public void actionPerformed(ActionEvent event) {
	
	}
	
	/**
	 * Wird aufgerufen, wenn dass UI ganz oder teilweise neu gezeichnet werden
	 * muss
	 * 
	 * @param g repräsentiert die Zeichenfläche
	 */
	public void paint(Graphics g) {
		System.out.println("Breite: " + panel.getWidth() + " Höhe: " + panel.getHeight());
		paintPanel(panel.getGraphics());
	}
	
	/**
	 * Zeichnet die Grafikausgabe für das Panel neu
	 * 
	 * @param g repräsentiert die Zeichenfläche
	 */
	private void paintPanel(Graphics g) {
		g.drawLine(10, 10, 400, 400);
	}
	
	/**
	 * Erstellt das primäre Fenster
	 * 
	 * @param args übernimmt die Kommandozeilenobjekte
	 */
	public static void main(String[] args) {
		Main frame = new Main();
		frame.setLocation(100, 100);
		frame.setSize(500, 500);
		frame.setVisible(true);
	}
}
 
Hi lgorse,

wenn es dir darum ging das dein Panel eine fixe Größe haben soll, kann ich nicht sehen warum dein Code nicht laufen sollte. ARRR ich hab doch das NULL-Layout gesetzt. Ich hab dein Programm soweit abgespeckt, das es genau das macht, was es soll, sofern ich dich recht verstanden habe.
Ich habe lediglich die Hintergrundfarbe gesetzt um die Panelgröße sichtbar zu machen.

Guck mal hier:
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main extends JFrame {
	private JPanel panel;

	public Main() {
		super("...");
//		setLayout(null); // neue zeile

		panel = new JPanel();
		panel.setBackground(Color.black); // neue zeile
		panel.setBounds(10, 10, 300, 300);
//		panel.setSize(new Dimension(200, 200)); // geht auch

		getContentPane().setLayout(null);
		getContentPane().add(panel, BorderLayout.NORTH); // funktioniert zwar aber irreführend
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(new Dimension(500,500));
	}

	public static void main(String[] args) {
		new Main().setVisible(true);
	}
}

Der Aufruf mit dem BorderLayout.NORTH kannste getrost durch einen ohne diesen Parameter ersetzen, da man sonst fälschlicherweise annehmen könnte du würdest ein BorderLayout verwenden. Tatsächlich muss man noch differenzieren, dein ContentPane ist ein Container und kann daher einen LayoutManager gesetzt bekommen. Ein JFrame ist ebenfalls ein Container und kann theoretisch einen anderen LayoutManager bekommen. In diesem Fall leitet das JFrame den LayoutManager an sein ContentPane weiter.
Was das zeichnen im Panel angeht... besser wäre es wenn du die paintComponent Methode von deinem Panel überschreibst. Zum Beispiel indem du eine neue Klasse dafür anlegst.

Schau mal:
Java:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.JFrame;
import javax.swing.JPanel;

class MeinPanel extends JPanel{
	@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2d = (Graphics2D) g; // nützliche klasse, wenn man viel zeichnet
		g2d.setColor(Color.white);
		g2d.fill(getBounds());
		
		g2d.setColor(Color.black);
		g2d.drawString("Test paint", 10, 20);
	}
}

public class Main extends JFrame {
	private JPanel panel;

	public Main() {
		super("...");
		setLayout(null);

		panel = new MeinPanel(); // veränderte Zeile
//		panel.setBackground(Color.black);
		panel.setBounds(10, 10, 300, 300);

		getContentPane().add(panel);
		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setSize(new Dimension(500,500));
	}

	public static void main(String[] args) {
		new Main().setVisible(true);
	}
}

Solltest du viel zeichnen empfielt sich möglicherweise Graphics2D zu benutzen und häufig benutzte Dinge wie Kreise oder Kästen als Rectangle2D oder Ellipse2D zu speichern.
Topic Java2D...

Ich hoffe das hilft
gruß isaias
 
Zuletzt bearbeitet:
Hallo isaias,

vielen Dank für die umfassende Antwort. Dein Code funktioniert und hat mir sehr weiter geholfen ;) Dein Tip, die paintComponent-Methode zu überschreiben klappt auch. Die Klasse Graphics2D guck ich mir mal an, aber für mich reicht wahrscheinlich auch erstmal die normale Klasse.

LG,
lgorse
 
Zurück