Farbkreis

Ruvok

Mitglied
Hallo,

ich mache gerade ein Java Tutorial und bin auch schon bei der GUI Programmierung.

Ich habe jetzt eine Aufgabe bekommen:
Kapitel 59 Programmieraufgaben
Aufgabe 2

Also ich muss einen Button machen, das habe ich schon so weit, aber pro Klick muss der Hintergrund seine Farbe ändern.

Ich komme da nicht weiter, kennt da jemmand die Antwort drauf?

Mein Quellcode:

Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Frame extends JFrame implements ActionListener {

	JButton klick;
	
	Frame(String title) {
		super(title);
		setLayout(new FlowLayout());
		
		//Buttons
		klick = new JButton("Klick mich!");
		add(klick);
		klick.addActionListener(this);
	}
	
	public void actionPerformed(ActionEvent e) {
		
		getContentPane().setBackground(Color.green);
	}
}
 
Zuletzt bearbeitet:

Saheeda

Top Contributor
z.B. mit einem Switch:

Java:
Color currentColor = getContentPane().getBackground();
Color newColor;

switch(currentColor){
	case Color.green:
		newColor = Color.red;
		break;
	case Color.red:
		newColor = Color.blue;
		break;
	[...]
}

getContentPane().setBackground(newColor);
 
Zuletzt bearbeitet:

minzee

Bekanntes Mitglied
Die Farben würde ich in einem Array auflisten.

Den Index der aktuellen Farbe würde ich in einer Eigenschaft i speichern.

Zu Beginn ist i 0, d. h. die erste Farbe aus dem Array wird angezeigt.

Bei jedem Click würde ich i inkrementieren, jedoch dabei aufpassen, dass i nicht die Anzahl der Arrayelement übersteigt. Falls das der Fall sein sollte, muss i wieder auf 0 gesetzt werden. Das kann man mit einem if oder mit % lösen.

if(i < colors.length - 1) ++i else i = 0;

Bzw.

i = (i + 1) % 4;
 

Ruvok

Mitglied
Ähh da gibt es ein kleines Problem:

@Saheeda

Dein Code zeigt bei mir Zeile 24 an also:

switch(currentColor)

das:

Cannot switch on a value of type Color. Only convertible int values, strings or enum variables are permitted
 

Network

Top Contributor
Das geht auch nicht, deshalb currentColor.asHex() verwenden.
Ist nicht der tatsächliche Name der Methode, aber die Klasse Color hat mehrere Methoden um die Farbe als eindeutige Zahl darzustellen.
(Auf dem Handy kann ich das jetzt aber nicht nachschauen.)

Minzees Lösung ist aber die weitaus bessere weil gleiches Ergebnis, weit weniger Code und nach belieben einfach skalierbar.
Switch ist hier einfach nur fehl am Platz.
 

ralli85

Mitglied
Hallo, bin neu hier im Forum und bin auch grad bei der obigen Aufgabe des selben Tutorials.
Hab das auf Grundlage der vorangegangenen Programmieraufgabe so gelöst:

Java:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class EinButton extends JFrame implements ActionListener
{
    JButton button;

    EinButton(String title)
    {
        super(title);
        button = new JButton("Button");
        button.addActionListener(this);
        setLayout(new FlowLayout());
        add(button);
        button.setActionCommand("ändern");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    
    public void actionPerformed(ActionEvent evt)
    {
        Color hgrund = getContentPane().getBackground();
            
        if(evt.getActionCommand().equals("ändern"))
            getContentPane().setBackground(Color.red);
        repaint();

        if((evt.getActionCommand().equals("ändern")&&(hgrund == (Color.red))))
            getContentPane().setBackground(Color.green);
        repaint();

        if((evt.getActionCommand().equals("ändern")&&(hgrund == (Color.green))))
            getContentPane().setBackground(Color.blue);
        repaint();

        if((evt.getActionCommand().equals("ändern")&&(hgrund == (Color.blue))))
            getContentPane().setBackground(Color.yellow);
        repaint();

        if((evt.getActionCommand().equals("ändern")&&(hgrund == (Color.yellow))))
            getContentPane().setBackground(Color.red);
        repaint();
    
        
    }


    public static void main(String[] args) {
    
        EinButton demo = new EinButton("Klicken Sie auf den Button");
        demo.setSize(200,100);
        demo.setVisible(true);

    }

}

Ist die Lösung OK oder sollte man es besser lösen? bin für alle Kommentare dankbar
 
K

kneitzel

Gast
Du brauchst nicht so viele repaint Aufrufe. Wenn Du etwas änderst an der GUI, das ein repaint erforderlich macht (z.B. ein add, ein setBackground sollte es nicht notwendig machen und meine Tests haben dies auch bestätigt), so reicht ein einzelner repaint aufruf. Und ich vermute, dass die repaint Aufrufe zu den ifs gehören - das bedeutet, dass Du { } verwenden musst, um die repaints nur zu haben, wenn auch setBackground ausgeführt wurde.

Und dann kann man da noch etwas optimieren - Du hast da sehr viele Prüfungen auf evt.getActionCommand().equals("ändern") - daher würde ich das etwas umschreiben:

Code:
public void actionPerformed(ActionEvent evt)
{
    Color hgrund = getContentPane().getBackground();

    if(evt.getActionCommand().equals("ändern")) {
        if (hgrund == Color.red) {
            getContentPane().setBackground(Color.green);
        } else if (hgrund == Color.green) {
            getContentPane().setBackground(Color.blue);
        } else if (hgrund == Color.blue) {
            getContentPane().setBackground(Color.yellow);
        } else if (hgrund == Color.yellow) {
            getContentPane().setBackground(Color.red);
        } else {
            getContentPane().setBackground(Color.red);    
        }
        // repaint(); // Wenn, dann nur ein Aufruf - aber nicht notwendig und nur noch als Kommentar um es prinzipiell zu zeigen.
    }
}
 

Joose

Top Contributor
Ist die Lösung OK oder sollte man es besser lösen? bin für alle Kommentare dankbar

Funktioniert sie? Dann ist das ja schon mal gut ;)
Ansonsten kann man sicher Kleinigkeiten optimieren:

na gut kneitzel war schneller ;)
Mein Code würde genauso ausschauen .. einzig die Variable "hgrund" würde ich noch innerhalb der 1.if-Bedingung deklarieren. Wird ja nur gebraucht wenn man etwas ändern will.
Java:
public void actionPerformed(ActionEvent evt) {
   if(evt.getActionCommand().equals("ändern")) {
     Color hgrund = getContentPane().getBackground();     
     if(hgrund == Color.red) {
......
 

ralli85

Mitglied
Danke für die Antworten, mit der verschachtelten if Anweisung sieht das natürlich besser aus. Die repaint kann ich tatsächlich ganz weglassen. Irgendwie hatte mein Code ohne die repaint Methode nicht funktioniert, der Fehler dürfte aber allem Anschein nach woanders gelegen haben.
 

Neue Themen


Oben