Hintergrundfarbe setzen in JPanel funktioneirt nicht

ernst

Top Contributor
Hallo allerseits,
Im folgenden, einfachen Grafikprogramm wird leider die Hintergrundfarbe nicht auf grün gesetzt:
In der Klasse KSZeichenfläche extends JPanel wird ein JButton und ein Objekt der Klasse
Malflaeche extends JPanel angeheftet.
Ich will die Hintergrundfarbe von Malflaeche auf Grün setzen.
Habe alles mögliche probiert (siehe Quellcode mit Kommentar "Hilft nichts" versehen).
Habe auch im Internet recherchiert.
Warum klappt das alles nicht?
Welchen Quellcode muß man einfügen, damit es funktioniert ?
Was ist so schwer daran, nur eine Hintergrundfarbe zu ändern ?
mfg
ern

Hier befindet sich das vollständige lauffähige Projekt:
Code:
package hintergrundtest1;
import javax.swing.event.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Startklasse {
    public static void main(String[] args) {
        KSZeichenflaeche ks = new KSZeichenflaeche();
        // Hilft nichts
        ks.setBackground(Color.GREEN);
        JFrame f = new JFrame();
        f.setSize(700, 800);
        f.getContentPane().add(ks);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // Hilft nichts
        f.getContentPane().setBackground(Color.GREEN);
        f.setVisible(true);
        ks.getMalflaeche().maleInsBild();
        // Hilft nichts
        f.getContentPane().setBackground(Color.GREEN);
        // Hilft nichts    
        ks.setBackground(Color.GREEN);
    }
}

class KSZeichenflaeche extends JPanel {
    private Malflaeche malflaeche;

    public KSZeichenflaeche() {
        JButton buttonHilfe;
        Malflaeche malflaeche;
        GridBagLayout gbl;
        gbl = new GridBagLayout();
        buttonHilfe = new JButton("HILFE");
        malflaeche = new Malflaeche();
        this.malflaeche = malflaeche;
        // Hilft nichts    
        malflaeche.setBackground(Color.GREEN);
        setLayout(gbl);
        addiereKomponente(gbl, buttonHilfe, 0, 0, 1, 1, 2, 0);
        addiereKomponente(gbl, malflaeche, 0, 1, 3, 1, 1, 1);
    }

    public void addiereKomponente(GridBagLayout gbl, Component c, int x, int y, int width, int height, double weightx, double weighty) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = width;
        gbc.gridheight = height;
        gbc.weightx = weightx;
        gbc.weighty = weighty;
        gbl.setConstraints(c, gbc);
        add(c);
    }

    public Malflaeche getMalflaeche() {
        return malflaeche;
    }
}

class Malflaeche extends JPanel {
    private Image image;

    public Malflaeche() {
    }

    public void maleInsBild() {
        Graphics graphics = null;
        int sx, sy;

        sx = this.getSize().width;
        sy = this.getSize().height;
        image = createImage(sx, sy);
        graphics = image.getGraphics();
        System.out.println("sx=" + sx + "sy=" + sy);
        // Hilft nichts
        setBackground(Color.GREEN);
        // Hilft nichts    
        repaint();
        graphics.setColor(Color.RED);
        graphics.drawLine(30, 40, 300, 400);
        graphics.drawLine(400, 300, 30, 40);
    }

    public void paintComponent(Graphics g) {
        // Hilft nichts    
        super.paintComponent(g);
        g.drawImage(image, 0, 0, null);
    }
}
 
In der Klasse Malflaeche erzeugst du ja auch in maleInsBild() ein Image mit der Größe der Malfläche und zeichnest es in paintComponent() mit `g.drawImage(image, 0, 0, null);`. Das überdeckt dann natürlich den kompletten Hintergrund. Kommentiere `g.drawImage(image, 0, 0, null);` aus und du siehst grün.
 
In der Klasse Malflaeche erzeugst du ja auch in maleInsBild() ein Image mit der Größe der Malfläche und zeichnest es in paintComponent() mit `g.drawImage(image, 0, 0, null);`. Das überdeckt dann natürlich den kompletten Hintergrund. Kommentiere `g.drawImage(image, 0, 0, null);` aus und du siehst grün.

Erst mal vielen Dank für die Antwort.
1)
welches setBackground(Color.GREEN) ist nun nötig ?
Kannst du mir die Zeile genau nennen bzw. die Anweisung?
Ich habe ja viele probiert.
welche kann ich weglassen?

2)
was macht
g.drawImage(image, 0, 0, null);
genau ?
Warum überdeckt es den kompletten Hintergrund ?

3)
Braucht man
super.paintComponent(g);
bzw. was macht diese Anweisung ?

4)
Leider werden meine 2 Geraden nicht mahr angezeigt.
Was muss ich machen, damit diese wieder auf dem Bildschirm erscheinen ?

mfg
ern
 
welche kann ich weglassen?
Ich würde alle außer malflaeche.setBackground(Color.GREEN) entfernen, damit man die Hintergrundfarbe "von außen" einstellen kann.

Was ist so schwer daran, nur eine Hintergrundfarbe zu ändern ?
Nichts. Du musst es nur machen.

Hintergrund ist nur eine Illusion. Stell Dir einfach eine Leinwand vor. Dort gibt es keinen Hintergrund und keinen Vordergrund; das Ding ist eine Ebene und damit flach.

Um den Eindruck entstehen zu lassen, es gäbe etwas wie Hintergrund, zeichnet man die Komponente von "hinten" nach "vorne". D. h. man pinselt erst mal die Hintergrundfarbe auf die Leinwand und erst dann die Elemente, die sich weiter im Vordergrund befinden sollen.

Die Methode setBackground sorgt in erster Linie nur dafür, dass sich die Komponente die angegebene Farbe merkt. Erst beim Zeichnen wird dann der richtige Pinsel in die betreffende Farbe getunkt, um den Hintergrund auf die Leinwand zu bringen. D. h. paintComponent beginnt damit, erstmal ein Rechteck mit der zuvor gemerkten Hintergrundfarbe zu füllen. Schon hat man einen "Hintergrund". Danach werden andere Elemente gemalt.

Bei Dir ist im "Vordergrund" ein Bild image, das mit g.drawImage(image, 0, 0, null) an den Koordinaten 0, 0 gezeichnet wird. Da das Bild so groß wie die Komponente selbst ist, wird es den ggf. zuvor gepinselten Hintergrund überdecken.

Du brauchst also in paintComponent gar nicht erst den Hintergrund zu malen. Daher kannst Du Dir auch super.paintComponent sparen, denn damit würde die Implementierung von paintComponent in der Elternklasse (hier JPanel) aufgerufen. Egal, was dort passiert: Du würdest es gleich im Anschluss durch Dein Bild ersetzen.

Was Du machen musst, ist den Hintergrund in Deinem Bild zu zeichnen. Konkret könnte das so aussehen:

Java:
    public void maleInsBild() {
        int sx = getSize().width;
        int sy = getSize().height;
        image = createImage(sx, sy);
        Graphics graphics = image.getGraphics();
        graphics.setColor(getBackground());
        graphics.fillRect(0, 0, sx, sy);
        graphics.setColor(Color.RED);
        graphics.drawLine(30, 40, 300, 400);
        graphics.drawLine(400, 300, 30, 40);
        graphics.dispose(); // Ressourcen freigeben
        repaint(); // die Komponente neu zeichnen
    }
 
Hintergrund ist nur eine Illusion. Stell Dir einfach eine Leinwand vor. Dort gibt es keinen Hintergrund und keinen Vordergrund; das Ding ist eine Ebene und damit flach.
....
Hallo mihe7,
vielen, vielen herzlichen Dank für deine tolle Erklärung und deine wertvolle Hilfe.
So gut erklärt habe ich es nie im Internet gefunden.
Jetzt klappt alles.

mfg
ern
 

Neue Themen


Zurück
Oben