Warum Ändert sich nicht der Text vom JButton?

2 Antworten

Ich nehme an, dass du in einem Texteditor entwickelst und nicht in einer IDE. Interessant wäre, ob das Programm auch einen Fehler wirft und wie der Stacktrace aussieht.

Auf Anhieb aber ein paar Sachen die mir so auffallen:

 for(int i = 1; i < feld.length; i++)

Was genau soll denn "&lt;" sein? Du muss "<" nicht codieren, es ist ein ganz normales Zeichen in Java.

 for(int i = 1; i < feld.length; i++)

Sollte dann auch funktionieren. Diesen Fehler hast du einige male im Code, auch für andere Zeichen.

Abgesehen davon sehe ich hier auch logische Fehler.

Du erstellst ein neues Spielfeld "f" und versuchst im Konstruktor von "Figuren" auf den wert "i" in Spielfeld "f" zuzugreifen:

f.feld[f.i].setText("O");

Da du aber keinen Konstruktor für "Spielfeld" definiert hast, wird der default Konstruktor gewählt. Daraus folgt, dass f.i = 0 ist. (0 ist der default-Wert für int in Java)
Die Methode Feld() wird zu keinem Zeitpunkt aufgerufen. Solltest du mit "Feld()" einen Konstruktor schreiben wollen, dann musst du die Methode entsprechend umbenennen.

  1. Wie kommst du darauf das ich in einem Texteditor arbeite, denn ich benutze Eclipse.
  2. Wegen den Zeichen die Codiert sind ich hab sie nicht Codiert. Gutefrage.net macht es selbst.
  3. Figur ist du kein Konstruktor, denn die Klasse heißt Figuren und die Methode Figur.
0
@DeathNoteGood

Hmm stimmt, da habe ich mich verlesen ;)
-> Genau deswegen sollte man immer eindeutige Name wählen xD

Aber unter diesem Gesichtspunkt sieht es natürlich anders aus:

Du versuchst hier zwei Sachen zu kombinieren. Statische Variablen/Methoden und initialisierte Objekte.

static Spielfeld f = new Spielfeld();

f ist ein Objekt. Wenn du nun also deine Firgur(Methode) aufrufst, änderst du die Werte von "f", nicht aber die statischen Werte der Klasse.

Spielfeld.feld[Spielfeld.i].setText("O");

sollte funktionieren. Jedoch musst du dann noch diese Zeile anpassen:

for(int i = 1; i &lt; feld.length; i++){

Du hast bereits oben eine statische Variable "int i" definiert und erstellst dir hier nochmal eine lokale. Abgesehen davon, dass es natürlich unsauber ist, kannst du auch auf das "neue", nicht statische "i" nicht von außen zugreifen, da es außerhalb der for-Schleife nicht existiert.

for(i = 1; i &lt; feld.length; i++){

So sollte es funktionieren.

Ich muss an der Stelle sagen, dass ich schon ewig nicht mehr mit statischen Variablen gearbeitet habe und deswegen nicht zu 100% sicher bin. Teste es doch mal und gib mir feedback. Vielleicht habe ich noch etwas übersehen.

0
Du erstellst ein neues Spielfeld "f" und versuchst im Konstruktor von "Figuren" auf den wert "i" in Spielfeld "f" zuzugreifen

Lustig, wenn es gar keinen Konstruktor gibt und daher der leere Standardkonstruktor verwendet wird.

public static void Figur()

Ist einfach nur eine statische Methode, die gegen die Konvention verstößt und groß geschrieben ist.

Gruß

1
@AldoradoXYZ

Das haben wir bereits festgestellt, dass ich mich mit Figur und Figuren() verlesen hatte ;)

Deswegen sind nicht-"ähnliche" Namen und die Namenskonventionen ja gerade wichtig, damit solche Fehler wie bei mir nicht so leicht passieren.

0
@AldoradoXYZ

Die bessere Frage ist wie löse ich das problem. Das programm gibt den Fehler java.lang.NullPointerException aus, aber ich hab doch alles definiert, also woran liegt das Problem?

0
@DeathNoteGood

Hallo DeathNoteGood,

ich arbeite grad an einer Lösung.

Du hast da "massive Lücken". Ich starte damit das ganze "static", ich nenne es die Anfänger static-Hölle, loszuwerden. Dabei bin ich wiedermal versucht ein YouTube-Video dazu zu machen.

Gib mir noch etwas Zeit, dann poste ich hier etwas. Die "Figuren" sehe ich schon auf dem Spielfeld.

Gruß

0
@AldoradoXYZ

Ich hab es schon paar mal gelesen aber nie verstanden was ist so schlimm daran static zu nutzen?

0
@DeathNoteGood

Nun, das grundlegend "Schlimme" daran ist, dass Du nicht weißt was es bedeutet. Damit verursachst Du Fehler die Du nicht verstehst und machst dir das Leben sehr schwer.

Gruß

0

Ich bin mal AldoradoXYZ Beispiel gefolgt und hab das Ganze mal ins Eclipse gestopft...

Mein Code sie nun so hier aus:

public class Figuren {

		public static void Figur(){

		Spielfeld.feld[Spielfeld.i].setText("XYZ");
	}
}
import java.awt.Color;

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

public class Spielfeld {

	static JFrame frame = new JFrame();
	static JPanel panel = new JPanel();
	static JButton[] feld = new JButton[65];
	static int z = 1;
	static int i;

	public static void Feld() {

		frame.setTitle("Spiel");
		frame.setSize(1920, 1080);
		frame.add(panel);
		panel.setLayout(new java.awt.GridLayout(8, 8));
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		for (i = 1; i < feld.length; i++) {
			feld[i] = new JButton();

			if (i % 2 == 0 && z == 1) {
				feld[i].setBackground(Color.BLACK);
			} else if (i % 2 == 1 && z == 2) {
				feld[i].setBackground(Color.BLACK);
			} else {
				feld[i].setBackground(Color.WHITE);
			}

			if (i % 8 == 0) {
				if (z == 2) {
					z = 0;
				}
				z++;
			}

			Figuren.Figur();
			panel.add(feld[i]);
		}
		frame.setVisible(true);
	}
}

Wenn ich nun

Spielfeld.Feld();

aufrufe bekomme ich dein Schachbrettmuster mit der gewünschten Zeichenkette.

0

Hallo DeathNoteGood,

wie schon geschrieben, solltest Du von dem ganzen "static" los kommen. Das ist nicht objektorientiert, bringt dir nichts und verursacht nur Fehler.

Du trennst in deinem Programm nicht zwischen "View" und "Model", daher tue ich das auch nicht. Üblicherweise würde man eine strikte Trennung vornehmen (Model-View-Controller oder auch MVC).

Da ich standardmäßig Englisch programmiere ist mir da einiges reingerutscht, man möge mir das nachsehen.

Zunächst eine Klasse für Figur. Aktuell nur ein Attribut, aber zukünftig wird sich das wohl ändern. Zum Spaß erzeuge ich Figuren mit zufälligen Zeichen, damit man was zum ansehen hat:

public class Figur {
    private final char zeichen;

    public Figur() {
        this.zeichen = getZufallsZeichen();
    }

    public char getZeichen() {
        return zeichen;
    }

    private char getZufallsZeichen() {
        double random = Math.random() * 100;
        if (random < 50) {
            return 'O';
        }

        return 'X';
    }
}

Dann benötigen wir ein Spielfeld. Wie bereits geschrieben werden hier Model und View gemischt, aber für den Einstieg reicht es wohl erstmal:

package spielfeld;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Point;

import static javax.swing.WindowConstants.EXIT_ON_CLOSE;

public class Spielfeld {

    private static final int FELD_BREITE = 8;

    private JPanel panel = new JPanel();
    private Feld[] felder = new Feld[FELD_BREITE * FELD_BREITE];

    public Spielfeld() {
        JFrame frame = new JFrame();
        frame.setTitle("Spiel");
        frame.setSize(1920, 1080);
        frame.add(panel);
        panel.setLayout(new java.awt.GridLayout(FELD_BREITE, FELD_BREITE));
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

        this.addButtons();
        this.addFiguren();

        frame.setVisible(true);
    }

    public Point indexToPoint(int index) {
        int x = index % FELD_BREITE;
        int y = index / FELD_BREITE;

        return new Point(x, y);
    }

    private void addButtons() {
        for (int i = 0; i < felder.length; i++) {
            Feld feld = new Feld(this, i);
            felder[i] = feld;

            JButton jButton = feld.getButton();
            panel.add(jButton);
        }
    }

    private void addFiguren() {
        for (int i = 0; i < felder.length; i++) {
            double random = Math.random();
            if (random < 0.3) {
                Figur figur = new Figur();
                felder[i].setFigur(figur);
            }
        }
    }
}

Ein Spielfeld besteht aus Feldern. Das Feld brauchen wir also auch. Hier werden ebenfalls Model und View gemischt, kann man überdenken, wenn man etwas weiter ist:

import javax.swing.JButton;
import java.awt.Color;
import java.awt.Point;

import static java.awt.Color.BLACK;
import static java.awt.Color.WHITE;

public class Feld {
    private final JButton button;
    private Figur figur;
    private Spielfeld spielfeld;

    public Feld(Spielfeld spielfeld, int index) {
        this.spielfeld = spielfeld;
        this.button = new JButton();
        Color backgroundColor = calculateColor(index);
        this.button.setBackground(backgroundColor);
    }

    public void setFigur(Figur figur) {
        if (hasFigur()) {
            throw new RuntimeException("Es steht bereits eine Figur auf dem Feld.");
        }
        this.figur = figur;
        this.button.setText("" + figur.getZeichen());
    }

    public JButton getButton() {
        return button;
    }

    private boolean hasFigur() {
        return figur != null;
    }

    private Color calculateColor(int index) {
        Point point = spielfeld.indexToPoint(index);

        if (point.y % 2 == 0) {
            if (point.x % 2 == 0) {
                return BLACK;
            }
            return WHITE;
        }

        if (point.x % 2 == 0) {
            return WHITE;
        }
        return BLACK;
    }
}

Zuletzt noch eine Main-Klasse mit main-Methode. Ich erzeuge hier extra ein neues Main-Objekt um das static der main-Methode "loszuwerden". Kann ich jedem Anfänger nur empfehlen. Klar kannst Du auch direkt in der main-Methode ein Spielfeld erzeugen, aber spätestens wenn die main-Methode wieder größer wird, schleicht sich doch wieder irgendwo ein "static" ein, wo es nicht hingehört.

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        Spielfeld spielfeld = new Spielfeld();
    }
}

Wie bereits geschrieben würde ich an dem ganzen Code noch einiges ändern, aber ich würde sagen, dass ich das für den Anfang lasse - man würde nichts mehr wiedererkennen.

Gruß und viel Spaß

Kennt Beziehung/Assoziation/Bezugsobjekte in Java?

Ich möchte in Java drei Klassen haben. Die erste führt mit der main-Methode nur die zweite aus. Die zweite erstellt ein Objekt der dritten Klasse. Diese soll aber auf die Variablen und Methoden der zweiten Klasse zugreifen (OHNE static).

Erste Klasse:

public class Start {
public static void main(String[] args) {
    new Spiel();
}

}

Zweite Klasse:

public class Spiel {
Spielfeld meinSpielfeld = new Spielfeld();

int spieler = 1;

public int getSpieler() {
    return spieler;
}

public void setSpieler(int spieler) {
    this.spieler = spieler;
}

}

Dritte Klasse:

public class Spielfeld {
private Spiel meinSpiel;

public void test() {
        
    if (meinSpiel.getSpieler() == 1) {
            meinSpiel.setSpieler(2);        
    }
}

}

Alle Klassen auf das nötigste reduziert.

Was ist zu tun, dass bei der dritten Klasse nicht immer nullPointerException kommt?

...zur Frage

Gutes Forum für's Java Programmieren?

Hallo allerseits,

ich (versuche) grade das programmieren von Java zu erlernen. Da ich bis jetzt (nach 2 Monaten) immer noch nicht verstanden habe und gelsen habe, dass man am besten lernt, indem man Fehler macht, wollte ich fragen, ob jemand irgendein gutes Forum kennt, wo leute aktiv und neulingen helfen können, was sie falsch gemacht haben ... .

Danke im Vorraus ;)

...zur Frage

Wie kann ich bei einem JLabel die Schriftfarbe und Schriftgröße verändern ohne den voraussichtlichen Text zu kennen?

Ich würde gerne den String "Kw" weiß erscheinen lassen und vergrößern, kann es aber nicht wie sonst mit html verändern (ich gebe es natürlich in einem Fenster aus).

private static void setupContent(JFrame fenster) {
	Calendar calendar = Calendar.getInstance();
	int weekNumber = calendar.get(Calendar.WEEK_OF_YEAR);
	String Kw = String.valueOf(weekNumber);
	JPanel content = new JPanel ();
	JLabel Text = new JLabel ();
	content.add(Text);
	Text.setText(Kw);
	fenster.setContentPane(content);
	fenster.getContentPane().setBackground(Color.black);

} }

...zur Frage

2 JPanels an der gleichen Stelle, Jeweils 1 in den Vordergrund setzen

Hallo, ich habe ein Programm mit diesem (gekürzten) Quellcode:

package spielPackage; import javax.swing.*; public class Test2 extends JFrame { private static final long serialVersionUID = 1L; JPanel startMenuPanel; JButton spielStartButton; JPanel gameMenuPanel; JButton zumStartMenuButton;

public Test2()
{
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setTitle("Hammer Spiel");
    this.setSize(1000,600);
    this.setLocationRelativeTo(null);
    startMenuPanel = new JPanel();
    spielStartButton = new JButton("Spiel starten");
    startMenuPanel.add(spielStartButton);
    this.add(startMenuPanel);
    gameMenuPanel = new JPanel();
    zumStartMenuButton = new JButton("zum Startmenü");
    gameMenuPanel.add(zumStartMenuButton);
    this.add(gameMenuPanel);
}

public void startMenu()
{   
    gameMenuPanel.setVisible(false);
    startMenuPanel.setVisible(true);
    this.setVisible(true);
}

public static void main(String[] args)
{
    new Test2();
}}

Jetzt will ich, dass durch die startMenu() - Methode das JPanel startMenuPanel sichtbar wird, wenn ich das Programm ausführe, seche ich jedoch nur das JFrame. Was muss ich ändern, dass ich dann tatsächlich das startMenuPanel sehe? Was muss ich machen, wenn ich das gameMenuPanel dann wieder sehen will?

Danke

...zur Frage

Wie kann ich bei Java ein Bild als JLabel einfügen?

Mein aktueller Stand:

public class Fenster1 {
  public static void main(String[] args) {
    JFrame fenster = new JFrame();
    setupContent(fenster);

    fenster.setSize(500, 500);
    fenster.setMinimumSize(new Dimension(100, 100));
    fenster.setVisible(true);
    fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }

  private static void setupContent(JFrame fenster) {
    JPanel content = new JPanel();
    JLabel Bild = new JLabel("hier soll das Bild hinkommen");
    content.add(Bild);
    fenster.setContentPane(content);
  }
}

PS.: Das Bild ist auf dem Desktop unter Bilder als smyley.jpg gespeichert.

...zur Frage

Kann man mit Java ein 3D Spiel Programmieren und wenn ja welche Programmieroberfläche ist dazu geeignet(ich benutze Eclipse)?

...zur Frage

Was möchtest Du wissen?