2016-04-08 6 views
2

Ich bin sehr neu in der Codierung (2 Monate) und ich habe versucht, Tic-Tac-Toe in Java zu machen. Ich bin etwas über meinem Kopf, aber ich habe es mit Swing geschafft. Mein Hauptproblem ist in der button1 Klasse. Ich würde die getText() Methode verwenden, aber am Ende brauchte ich es nicht oder so dachte ich. Ich habe versucht, es zu löschen, aber wie sich herausstellt, schalten meine Tictactoe-Tasten Buchstaben nicht ohne es um. Der Compiler sagte mir, es überschreibt AbstractButton 's getText() Methode, aber ich sehe nicht, warum das wichtig sein sollte, da ich es nie wirklich verwendet habe, dachte ich. Ich denke, es ist vielleicht ein Scope-Problem, das dadurch gehandhabt wird, dass es irgendwie überschrieben wird, aber ich bin mir nicht sicher. Ich versuchte, die Variable text zu verwenden, um die Schaltfläche mit setText() zu aktualisieren, und das scheint nicht zu funktionieren, wie ich dachte, dass es sollte. Ich verstehe auch nicht, warum das 3 mal 3 Rasterlayout meistens richtig funktioniert, aber manchmal ist die Anzahl der hinzugefügten Buttons falsch.Brauchen Sie Hilfe zu verstehen, wie ein bestimmter Getter mein Programm beeinflusst

So funktioniert das Programm (meistens), aber ich verstehe nicht vollständig, wie die button1 Klasse funktioniert.

TicTacToe.java

import java.awt.*; 
import java.util.*; 
import javax.swing.*; 

public class TicTacToe extends JFrame { 

public static void main(String[] args) { 
    JFrame window = new JFrame("Tic-Tac-Toe"); 
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setVisible(true); 
    window.setSize(600, 600); 
    window.setLayout(new GridLayout(3, 3)); 

    ArrayList<button1> buttonArrayList = new ArrayList<>(9); 

    for (int i = 0; i < 9; i++) { 
     button1 newbutton = new button1(); 
     buttonArrayList.add(newbutton); 
     window.add(buttonArrayList.get(i)); 
    } 
} 
} 

button1.java

import java.awt.*; 
import java.awt.event.ActionEvent; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 

public class button1 extends JButton { 
int value = 0; 
String text = ""; 

public button1() { 

    class ButtonAction extends AbstractAction { 
     public ButtonAction() {} 
     @Override 
     public void actionPerformed(ActionEvent Switcher) { 
      System.out.println(text + " " + value); 
      value++;//value is a relic from earlier attempts that i just felt like keeping. 
      if (text.equals("O")) { 
       text = "X"; 
      } else if (text.equals("X")) { 
       text = ""; 
      } else if (text.equals("")) { 
       text = "O"; 
      } 
     } 
    } 
    this.setAction(new ButtonAction()); 
    this.setText(text); 
    this.setFont(new Font("Arial",Font.PLAIN,120)); 
} 

public String getText()// <----culprit 
{ 
    return text; 
} 
} 

Antwort

3

A JButton Klasse hat ein Verfahren für sich definiert, einschließlich setText() (die den angezeigten Text auf dem Knopf eingestellt wird) und getText() (was den aktuellen Text zurückgibt, der auf der Schaltfläche angezeigt wird).

Sie haben eine Klasse button1 erstellt (Anmerkung: Klassen sollten mit Großbuchstaben beginnen).

Sie haben der Klasse button1 eine Aktion hinzugefügt, was bedeutet, dass etwas passiert, wenn die Aktion aktiviert wird. Beachten Sie, dass Sie in dieser actionPerformed Methode setText(text) aufrufen sollten, um den angezeigten Wert zu aktualisieren.

Sie haben auch eine getText()-Methode definiert, die die in JButton definierte Methode getText() überschreibt. Dieser Ansatz ist in Ordnung, wenn es sich um eine bewusste Designentscheidung handelt. So wie es ist, sollten Sie die Methode getText() aus der Klasse button1 entfernen und zulassen, dass die JButton-Standardklasse das Update verarbeitet. Momentan versuchen Sie, eine Instanzvariable text mit dem Wert beizubehalten, aber es ist möglich, dass diese Instanzvariable nicht mit dem tatsächlich angezeigten Wert der Schaltfläche übereinstimmt (berücksichtigen Sie eine andere Klasse, die .setText() auf der Schaltfläche aufruft).

BEARBEITEN: Es ist wahr, dass this Bezug auf die JButton in der ButtonAction nicht verfügbar ist. Die Aktion selbst enthält jedoch die Schaltfläche, die gedrückt wurde.

@Override 
    public void actionPerformed(ActionEvent e) 
    { 
     JButton btn = (JButton)e.getSource(); 

     // if desired, String cur = btn.getText() may be called to find the 
     // current setting; get and process if needed 
     btn.setText(WHAT_EVER_TEXT); 
    } 

Sofern es sich um eine spezifische Anforderung ist, den aktuellen Text zu verarbeiten, jedoch (so dass ein O zu einem X auf eine leere Auswahl), würde ich etwas zu verfolgen die aktuelle Runde umzusetzen.Dieser Code ist etwas, das ich mit experimentiert, und hat gute und schlechte Punkte, um es (wie es beispielhaft ist):

static class TurnController 
{ 
    // whose turn it is; start with X 
    private Player whoseTurn = Player.X; 

    // the instance variable 
    private static final TurnController instance = new TurnController(); 


    private TurnController() 
    { 
    } 

    public static Player currentTurn() 
    { 
     return instance.whoseTurn; 
    } 

    public static Player nextTurn() 
    { 
     switch (instance.whoseTurn) { 
     case X: 
      instance.whoseTurn = Player.O; 
      break; 

     case O: 
      instance.whoseTurn = Player.X; 
      break; 
     } 

     return instance.whoseTurn; 
    } 

    public static String getMarkerAndAdvance() 
    { 
     String marker = currentTurn().toString(); 

     nextTurn(); 

     return marker; 
    } 

    enum Player 
    { 
     X, 
     O, 
     ; 
    } 
} 

dieses TurnController Unter Verwendung der actionPerformed wird:

@Override 
    public void actionPerformed(ActionEvent e) 
    { 
     JButton btn = (JButton)e.getSource(); 

     btn.setText(TurnController.getMarkerAndAdvance()); 
    } 

und die Button1 Klasse Möglicherweise wurde die String text Instanzvariable entfernt.

+0

Wenn ich Ihren Vorschlag richtig verstehe, sagen Sie, dass Sie den Text auf der Schaltfläche von der "actionperformed" -Methode festlegen. Wenn das so ist, dann wollte ich das von Anfang an tun, aber ich wusste nicht, wie ich es richtig umsetzen sollte. Ich weiß es immer noch nicht, ich weiß, dass ich 'this' dort nicht benutzen kann. Würde es dir etwas ausmachen, mir zu zeigen, wie das geht? Danke btw – ApatheticWrath

+0

@ApathéticWrath, machte eine Bearbeitung der Antwort zu versuchen, zu veranschaulichen, wie Sie die ausgewählte Schaltfläche aus der 'actionPerformed'-Methode zu erhalten. – KevinO

+0

Es wird mich ein bisschen brauchen, um mich vollständig in diese neue Klasse einzuwickeln, aber ich denke, ich werde es bekommen. Die einzige Sache, die mich abstößt, ist genau das, was diese Zeile bedeutet und tut 'JButton btn = (JButton) e.getSource();'. Es verweist auf die Schaltfläche, in der es sich befindet, und setzt Dinge über eine lokale Instanz der Schaltfläche? – ApatheticWrath

0

Was Sie versucht haben, ist zu versuchen, eine benutzerdefinierte Button Klasse zu machen und seine EventHandler nur durch die Erweiterung AbstractAction namee button1 wie wir in Ihrer Frage finden.

Sie haben die Methode außer Kraft setzen actionPerformed(ActionEvent Switcher), die zu der Klasse gehört eigentlich AbstractAction durch eigene Definition (Was auf Action-Ereignisse jeder Taste ausgeführt soll).

class ButtonAction extends AbstractAction { 
     public ButtonAction() {} 
     @Override 
     public void actionPerformed(ActionEvent Switcher) { // Your Definition For actionPerformed.. 
      System.out.println(text + " " + value); 
      value++;//value is a relic from earlier attempts that i just felt like keeping. 
      if (text.equals("O")) { 
       text = "X"; 
      } else if (text.equals("X")) { 
       text = ""; 
      } else if (text.equals("")) { 
       text = "O"; 
      } 
     } 
    } 
    this.setAction(new ButtonAction()); // add ActionListener to each Button. 
    this.setText(text); // Setting Text to each Button 
    this.setFont(new Font("Arial",Font.PLAIN,120)); //add Font to each Button. 
} 

Jetzt in diesem Code.

ArrayList buttonArrayList = neue ArrayList <>();

for (int i = 0; i < 9; i++) { 
    button1 newbutton = new button1(); // Creating 9 new buttons. 
    buttonArrayList.add(newbutton); // add each button into the ArrayList. 
    window.add(buttonArrayList.get(i)); // each Button to the the AWT Window. 
} 

Above-Code wird 9 Buttons generieren und an Ihre AWT Window hinzuzufügen. Jede button haben actionPerformed() Methode, die die overrided Definition enthält.

Jetzt Jede Schaltfläche wird Aktion gemäß der Definition durchgeführt, die Sie actionPerformed() Methode geben.

Vielen Dank.

Verwandte Themen