2017-10-01 2 views
0

Ich bin fasziniert von dem Fehler, der in dem Code, den ich geschrieben habe, erscheint. Es funktioniert perfekt in C#, aber irgendwie funktioniert es nicht in Java. Ich bin mir nicht sicher, ob es etwas mit dem zweiten Mal zu tun hat. Ich habe es mit meiner anderen Klasse überprüft, die die Schaltflächen in diese Klasse übergibt, und ich finde nichts, was diese Klasse beeinflussen würde. Eine andere Sache zu beachten ist, dass alle Swing-Komponenten nicht null sind, wenn sie in diese Klasse übergeben werden.Java-Text-Adventure-Spiel Swing-Komponenten nicht korrekt aktualisiert und Enum wird zweimal pro Funktion ausgewählt

Mein Hauptproblem ist, dass alle Tasten nicht nach dem Einstellen des Textes für die Sekunde Zeit aktualisieren.

public class StoryManager extends Text{ 
    // this is the body of the story 
    private JTextPane textPane; 
    // the choices that the user can make 
    private JButton btnChoice1; 
    // this would determine which ending the user will get 
    private short ending = 0; 

/** 
* checkpoint for each part of the story 
* */ 
public enum Part{ 
    START, A_JOKE, B_BASE 
} 
// the part that the user is currently in 
Part userPart; 

/** 
* This runs the story. 
* */ 
public void PlayStory() { 
    printText(); 
    processDecision(); 
} 
/** 
* This attaches the buttons and the textPane to their corresponding variables in the class. 
* */ 
public StoryManager(WindowHandler windowHandler) { 
    // pane 
    textPane = windowHandler.getTextPane(); 
    // buttons 
    btnChoice1 = windowHandler.getBtnChoice1(); 
    // set the user to start the story from the beginning 
    userPart = Part.START; 
} 

@Override 
public void printText() { 
    switch(userPart) { 
    case START: 
     System.out.println("Start event started"); 
     textPane.setText("some text" 
       + "[1] option 1\n"); 
     break; 
    case A_JOKE: 
     System.out.println("A_JOKE event started"); 
     textPane.setText("another text 1" 
       + "[1] option 1\n"); 
     break; 
    case B_BASE: 
     System.out.println("B_BASE event started"); 
     textPane.setText("another text 2" 
       + "[1] option 1\n"); 

     break; 
    default: 
    } 
    textPane.setCaretPosition(0); 
    textPane.repaint(); 
} 
/** 
* Enables all the buttons. 
* */ 
private void EnableAllButtons() { 
    if(!btnChoice1.isEnabled()) { 
     btnChoice1.setEnabled(true); 
     btnChoice1.setOpaque(true); 
     btnChoice1.setContentAreaFilled(true); 
     btnChoice1.setBorderPainted(true); 
    } 
    btnChoice1.repaint(); 
    //System.out.println("Button1: "+btnChoice1.isEnabled()); 
} 
/** 
* Temporarily disables the other buttons and runs the PlayStory() again to continue the story. 
* 
* @param button The button that is clicked. 
* */ 
private void SetDecisionText(JButton button) { 
    button.setText("Next"); 
    btnChoice1.revalidate(); 
    PlayStory(); 
} 
/** 
* Sets the action of the button per part. 
* */ 
@Override 
public void processDecision() { 
    switch(userPart) { 
    case START: 
     btnChoice1.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       ending -= 10; 
       userPart = Part.A_JOKE; 
       SetDecisionText(btnChoice1); 
      } 
     }); 
     break; 
    case A_JOKE: 
     btnChoice1.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       btnChoice1.setText("Choice 1"); 
       //btnChoice1.revalidate(); <- tried this but it isn't working 
       GoToBase(); 
      } 
     }); 
     break; 
    case B_BASE: 
     System.out.println("Updated with B_BASE"); 
     btnChoice1.addActionListener(new ActionListener() { 
      @Override 
      public void actionPerformed(ActionEvent arg0) { 
       ending -= 10; 
       userPart = Part.B_ARGUE; 
       SetDecisionText(btnChoice1); 
      } 
     }); 
    } 

} 
private void GoToBase() { 
    EnableAllButtons(); 
    switch(userPart) { 
    case A_JOKE: 
     userPart = Part.B_BASE; 
     System.out.println("GotoBase: " + userPart); 
     break; 
    default: 
     System.out.println("Error"); 
    } 
    PlayStory(); 
} 

} 

Ich teile die Ausgabe meines Programms hier. Ich habe die erste Taste zweimal ausgewählt, dann passiert das. Wenn ich es erneut drücke, wird userPart null oder so.

// pressed play 
Start event started 

// click 1st button 
A_JOKE event started 

// click 1st button again 
GotoBase: B_BASE 
B_BASE event started 
Updated with B_BASE 
A_JOKE event started 

// click 1st button for the third time 
GotoBase: B_BASE 
B_BASE event started 
Updated with B_BASE 
Error 
A_JOKE event started 
+0

* "Liste der Probleme:" * Was ist Ihre ** single ** Frage für dieses Q & A-Thema? Dies ist eine Q & A-Site, kein Helpdesk. Separate Fragen sollten in separaten Threads mit jeweils einem für die Frage spezifischen MCVE angezeigt werden. –

+1

Siehe Bearbeiten, um zum Beispiel zu antworten, was ich meine, indem ich Listener entferne. Aber wieder für mein Geld würde ich daran arbeiten, das Ganze zu refaktorisieren, wenn ich in deinen Schuhen wäre. Streben Sie nach einem Modell (logischem Teil), das bei Bedarf mit Swing, JavaFX oder sogar einem Konsolenprogramm arbeiten könnte. –

Antwort

1

Sie erscheinen innerhalb des logischen Teil des Codes Hinzufügen ActionListeners, um Ihre Schaltflächen zu werden und Ihr dies zu tun bedeutet, dass Tasten ActionListeners hinzugefügt, um sie mehrfach haben wird, wann immer die processDecision() Methode aufgerufen wird, was schließlich in Schaltflächen mit mehreren Zuhörern hinzugefügt, was nicht das ist, was Sie wollen. Die Listener sollten einmal bei der Komponentenerstellung hinzugefügt werden.

Oder, wenn Sie ActionListeners tauschen möchten, dann müssen Sie die alten Listener entfernen, wenn Sie durch die neuen ersetzen.

Es gibt wahrscheinlich andere logische Probleme in Ihrem Code, aber das ist die Grenze dessen, was ich vorschlagen kann, bis Sie in der Lage sind, eine gültige Minimal, Complete, and Verifiable Example Program für uns bereitzustellen. Hier verdichten Sie Ihren Code in das kleinste Bit, das noch kompiliert und ausgeführt wird, keine externen Abhängigkeiten aufweist (wie zum Beispiel eine Verknüpfung zu einer Datenbank oder Bildern), keinen zusätzlichen Code, der für Ihr Problem nicht relevant ist, aber Ihr Problem immer noch demonstriert .

Ein großes Problem, das ich sehe, ist, dass Ihr Code sehr hohe Kopplung und geringe Kohäsion hat, was für sehr spröden Code und Code macht, der schwer zu debuggen ist. Erwägen Sie ein Refactoring, indem Sie Ihr Modell (den Logikteil Ihres Programms) von Ihrer Sicht (dem GUI-Teil) trennen und die Daten vom Code trennen, z. B. den hartcodierten Anzeigetext loswerden und in ein Daten-Repository einfügen, sei es eine Textdatei, Datenbank oder was auch immer am besten funktioniert.

Beispiel für das Entfernen Zuhörer:

case A_JOKE: 
    for (ActionListener l : btnChoice1.getActionListeners()) { 
     btnChoice1.removeActionListener(l); 
    } 
    btnChoice1.addActionListener(new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent arg0) { 
      btnChoice1.setText("Choice 1"); 
      // btnChoice1.revalidate(); <- tried this but it isn't 
      // working 
      GoToBase(); 
     } 
    }); 
    break; 

Als Nebenwirkung werden Sie wollen lernen und Java naming conventions zu benutzen, die als die andere sind für C# verwendet. Variablennamen sollten alle mit einem niedrigeren Buchstaben beginnen, während Klassennamen mit einem Großbuchstaben beginnen. Wenn wir dies lernen und diesem Beispiel folgen, können wir Ihren Code besser verstehen und den Code anderer besser verstehen.

+0

Andere Probleme - Sie mischen Code mit Daten, und dies wird später zu schweren Kopfschmerzen für Sie führen. –

Verwandte Themen