Skip to main content
Code Review

Return to Question

Post Reopened by Community Bot, Phrancis, janos, Simon Forsberg, Donald.McLean
indent fix
Source Link
janos
  • 112.9k
  • 15
  • 154
  • 396
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.swing.*;


public class Hangman {
 String[] wordList;
 String secretWord;
 Set<Character> alphabet;
 Set<Character> lettersGuessed; // letters the user has guessed
 boolean[] lettersRevealed; // determines if the letter should be revealed or not

 int GuessesRemaining;

 // GUI
 JFrame f;
 JTextField textField;
 JLabel guessesRemainingLabel;
 JLabel lettersGuessedLabel;
 JLabel secretWordLabel;


 public static void main(String[] args){
 Hangman h = new Hangman();
 h.createAlphabetSet();
 h.readFile("words.txt");
 h.buildGUI();
 h.setUpGame();
 h.drawSecretWord();
 }

 // buildGUI - builds the GUI
 private void buildGUI(){
 f = new JFrame("Hangman");

 // JLabels
 guessesRemainingLabel = new JLabel("Guesses remaining: " + String.valueOf(GuessesRemaining));
 lettersGuessedLabel = new JLabel("Already guessed: ");
 secretWordLabel = new JLabel();

 // Text field for user to type letters in
 textField = new JTextField();
 JButton checkButton = new JButton("Guess");

 // Add listeners to textField & checkButton
 TextListener textListener = new TextListener();
 checkButton.addActionListener(textListener);
 textField.addActionListener(textListener);

 // Panel for all the labels
 JPanel labelPanel = new JPanel();
 labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
 labelPanel.add(guessesRemainingLabel);
 labelPanel.add(lettersGuessedLabel);
 labelPanel.add(secretWordLabel);

 // User panel
 JPanel userPanel = new JPanel(new BorderLayout());
 userPanel.add(BorderLayout.CENTER, textField);
 userPanel.add(BorderLayout.EAST, checkButton);
 labelPanel.add(userPanel);

 // Add everything to frame
 f.add(BorderLayout.CENTER, labelPanel);

 f.setSize(250, 100);
 f.setLocationRelativeTo(null);
 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 f.setVisible(true);
 }
 // checkIfWon - sees if the user has won the game
 private boolean checkIfWon(){
 for(boolean tof : lettersRevealed){
 if(!tof)
 return false;
 }
 return true;
 // checkIfWon}
 - sees if the// userget hasinput wonfrom the gameuser
 private boolean checkIfWoncheckUserGuess(String l){
 if(l.length() == 1 && for!lettersGuessed.contains(boolean tofl.charAt(0)) :&& lettersRevealedalphabet.contains(l.charAt(0))){
 ifsetText(!tofnull)
 return false;;
 }lettersGuessed.add(l.charAt(0));
 return true;
 }
 
 // get input from the user
 private boolean checkUserGuess(String l){
 if(l.length() == 1 && !lettersGuessed.contains(l.charAt(0)) && alphabet.contains(l.charAt(0))) {
 setText(null);
 lettersGuessed.add(l.charAt(0));
 return true;
 }else {
 Toolkit.getDefaultToolkit().beep();
 }
 return false;
 }
 
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 return false;
 }
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 // createAlphabetSet - Creates the alphabet set that's used to ensure that the user's guess not a number nor a special character
 private void createAlphabetSet(){
 alphabet = new HashSet<Character>(26);
 for(Character c = 'a'; c<='z'; c++){
 alphabet.add(c);
 }
 }
 }
 // drawGuessesRemaining - Outputs the guesses remaining
 void drawGuessesRemaining(){
 final String guessesMessage = "Guesses remaining: " + String.valueOf(GuessesRemaining);
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 guessesRemainingLabel.setText(guessesMessage);
 guessesRemainingLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
 }
 }
 }
 );
 }
 // drawLettersGuessed - Outputs the letters guessed
 void drawLettersGuessed(){
 StringBuilder lettersBuilder = new StringBuilder();
 for (Character el : lettersGuessed) {
 String s = el + " ";
 lettersBuilder.append(s);
 }
 
 // drawLettersGuessed - Outputs the letters guessed
 void drawLettersGuessed(){
 StringBuilder lettersBuilder = new StringBuilder();
 for (Character el : lettersGuessed) {
 String s = el + " ";
 lettersBuilder.append(s);
 }
 
 final String letters = lettersBuilder.toString();
 SwingUtilities.invokeLater(
 new Runnable() {
 @Override
 public void run() {
 lettersGuessedLabel.setText("Already guessed: " + letters);
 }
 }
 );
 }
 
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 );
 }
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 
 final String w = word.toString();
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 secretWordLabel.setText(w);
 }
 }
 );
 }

 final String w = word.toString();
  SwingUtilities.invokeLater(
 new Runnable(){
  @Override
 public void run(){
  secretWordLabel.setText(w);
 }
 }
 );
 }
 // loseSequence - when the the user runs out of guesses
 private void loseSequence(){
 for(int i=0; i<lettersRevealed.length; i++)
 lettersRevealed[i] = true;
 drawSecretWord();
 playAgain("Tough luck. The secret word was " + secretWord + ".\nWould you like to play another game of hangman?");
 }
 // playAgain - Allows the user to play another game of hangman
 private void playAgain(String message){
 int ans = JOptionPane.showConfirmDialog(f, message,
 "Play again?", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
 if(ans == JOptionPane.YES_OPTION) {
 setUpGame();
 }else {
 System.exit(0);
 }
 }
 // playAgainreadFile - Allows theread userin towordList
 play another game ofprivate hangman
String[] readFile(String loc){
 private void playAgain(Stringtry message){
 intFile ansf = JOptionPane.showConfirmDialog(f,new message,File(loc);
 assert f.exists() : "File doesn't exist";
 "Play again?",BufferedReader JOptionPane.YES_NO_OPTION,input JOptionPane.PLAIN_MESSAGE= new BufferedReader(new FileReader(f));
 // read in if(ansthe ==stuff JOptionPane.YES_OPTION)into {
an arrayList here
 wordList = setUpGameinput.readLine().split(" ");
 }else {
// close the input stream
 Systeminput.exitclose(0);
 }catch(IOException ioException){
 } ioException.printStackTrace();
 }
 return wordList;
 }
 // readFilesetUpGame - read in wordList
sets up the variables appropriately
 private String[]void readFilesetUpGame(String loc){
 GuessesRemaining try= {5;
 secretWord = chooseSecretWord(wordList);
 File f lettersRevealed = new Fileboolean[secretWord.length(loc);];
 Arrays.fill(lettersRevealed, false);
 lettersGuessed = assertnew f.existsHashSet<Character>(26); : "File doesn't exist";
 // 26 letters in alphabet

 drawSecretWord();
 BufferedReaderdrawLettersGuessed();
 input = new BufferedReader(new FileReader drawGuessesRemaining(f));
 }
 // updateSecretWord - updates which letters of the secret word have //been readrevealed
 in the stuff intoprivate anvoid arrayListupdateSecretWord(String herel){
 List<Integer> changeBool = new ArrayList<Integer>();
 wordList = input.readLine if()secretWord.splitcontains(" "l);){
 // Searches through secretWord & notes down all //letters closethat equal the inputuser's streamguess
 for(int i=0; inputi<secretWord.closelength(); i++){
 }catch if(IOExceptionsecretWord.charAt(i) ioException== l.charAt(0){)
 ioException changeBool.printStackTraceadd(i);
 }
 return wordList;
 }
 // setUpGame - sets upChanges the variables appropriately
  private void setUpGame(){
 boolean value for those letters @ GuessesRemainingtheir =corresponding 5;indexes
 secretWord = chooseSecretWordfor(wordList);
 lettersRevealedInteger =idx new: boolean[secretWord.length(changeBool)];
 Arrays.fill(lettersRevealed, false);
  lettersGuessedlettersRevealed[idx] = new HashSet<Character>(26); // 26 letters in alphabet
 true;
 drawSecretWord();}else{
 drawLettersGuessed()GuessesRemaining--;
 drawGuessesRemaining();
 }
 
 // updateSecretWord - updates which letters of the secret word have been revealed
 private void updateSecretWord(String l){
 List<Integer> changeBool = new ArrayList<Integer>();
 
 if(secretWord.contains(l)){
 // Searches through secretWord & notes down all letters that equal the user's guess
 for(int i=0; i<secretWord.length(); i++){
 if(secretWord.charAt(i) == l.charAt(0))
 changeBool.add(i);
 }

 // Changes the boolean value for those letters @ their corresponding indexes
 for(Integer idx : changeBool)
 lettersRevealed[idx] = true;
 }else{
 GuessesRemaining--;
 drawGuessesRemaining();
 }
 }
 
 // winSequence - when the user has correctly guessed the secret word
 private void winSequence(){
 playAgain("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!\n" +
 "Would you like to play another game of hangman?");
 }




 // GETTERS
 private String getText(){
 return textField.getText();
 }


 // SETTERS
 private void setText(final String t){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 textField.setText(t);
 }
 }
 );
 }
 
 
 // ActionListener
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 String guess = getText();
 
 if(checkUserGuess(guess)) {
 updateSecretWord(guess);
 drawSecretWord();
 
 if(lettersGuessed.size() != 0) // No letters have been guessed by the user at the beginning
 drawLettersGuessed();
 
 // Checks if the user has won or lost
 if (checkIfWon())
 winSequence();
 else if (GuessesRemaining == 0)
 loseSequence();
 }
 );
 }
 // ActionListener
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 String guess = getText();
 if(checkUserGuess(guess)) {
 updateSecretWord(guess);
 drawSecretWord();
 if(lettersGuessed.size() != 0) // No letters have been guessed by the user at the beginning
 drawLettersGuessed();
 // Checks if the user has won or lost
 if (checkIfWon())
 winSequence();
 else if (GuessesRemaining == 0)
 loseSequence();
 }
 }
 }
}
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.swing.*;


public class Hangman {
 String[] wordList;
 String secretWord;
 Set<Character> alphabet;
 Set<Character> lettersGuessed; // letters the user has guessed
 boolean[] lettersRevealed; // determines if the letter should be revealed or not

 int GuessesRemaining;

 // GUI
 JFrame f;
 JTextField textField;
 JLabel guessesRemainingLabel;
 JLabel lettersGuessedLabel;
 JLabel secretWordLabel;


 public static void main(String[] args){
 Hangman h = new Hangman();
 h.createAlphabetSet();
 h.readFile("words.txt");
 h.buildGUI();
 h.setUpGame();
 h.drawSecretWord();
 }

 // buildGUI - builds the GUI
 private void buildGUI(){
 f = new JFrame("Hangman");

 // JLabels
 guessesRemainingLabel = new JLabel("Guesses remaining: " + String.valueOf(GuessesRemaining));
 lettersGuessedLabel = new JLabel("Already guessed: ");
 secretWordLabel = new JLabel();

 // Text field for user to type letters in
 textField = new JTextField();
 JButton checkButton = new JButton("Guess");

 // Add listeners to textField & checkButton
 TextListener textListener = new TextListener();
 checkButton.addActionListener(textListener);
 textField.addActionListener(textListener);

 // Panel for all the labels
 JPanel labelPanel = new JPanel();
 labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
 labelPanel.add(guessesRemainingLabel);
 labelPanel.add(lettersGuessedLabel);
 labelPanel.add(secretWordLabel);

 // User panel
 JPanel userPanel = new JPanel(new BorderLayout());
 userPanel.add(BorderLayout.CENTER, textField);
 userPanel.add(BorderLayout.EAST, checkButton);
 labelPanel.add(userPanel);

 // Add everything to frame
 f.add(BorderLayout.CENTER, labelPanel);

 f.setSize(250, 100);
 f.setLocationRelativeTo(null);
 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 f.setVisible(true);
 }
 // checkIfWon - sees if the user has won the game
 private boolean checkIfWon(){
 for(boolean tof : lettersRevealed){
 if(!tof)
 return false;
 }
 return true;
 }
 
 // get input from the user
 private boolean checkUserGuess(String l){
 if(l.length() == 1 && !lettersGuessed.contains(l.charAt(0)) && alphabet.contains(l.charAt(0))) {
 setText(null);
 lettersGuessed.add(l.charAt(0));
 return true;
 }else {
 Toolkit.getDefaultToolkit().beep();
 }
 return false;
 }
 
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 
 // createAlphabetSet - Creates the alphabet set that's used to ensure that the user's guess not a number nor a special character
 private void createAlphabetSet(){
 alphabet = new HashSet<Character>(26);
 for(Character c = 'a'; c<='z'; c++){
 alphabet.add(c);
 }
 }
 
 // drawGuessesRemaining - Outputs the guesses remaining
 void drawGuessesRemaining(){
 final String guessesMessage = "Guesses remaining: " + String.valueOf(GuessesRemaining);
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 guessesRemainingLabel.setText(guessesMessage);
 guessesRemainingLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
 }
 }
 );
 }
 
 // drawLettersGuessed - Outputs the letters guessed
 void drawLettersGuessed(){
 StringBuilder lettersBuilder = new StringBuilder();
 for (Character el : lettersGuessed) {
 String s = el + " ";
 lettersBuilder.append(s);
 }
 
 final String letters = lettersBuilder.toString();
 SwingUtilities.invokeLater(
 new Runnable() {
 @Override
 public void run() {
 lettersGuessedLabel.setText("Already guessed: " + letters);
 }
 }
 );
 }
 
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 }
 
 final String w = word.toString();
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 secretWordLabel.setText(w);
 }
 }
 );
 }
 
 // loseSequence - when the the user runs out of guesses
 private void loseSequence(){
 for(int i=0; i<lettersRevealed.length; i++)
 lettersRevealed[i] = true;
 drawSecretWord();
 playAgain("Tough luck. The secret word was " + secretWord + ".\nWould you like to play another game of hangman?");
 }
 
 // playAgain - Allows the user to play another game of hangman
 private void playAgain(String message){
 int ans = JOptionPane.showConfirmDialog(f, message,
 "Play again?", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
 if(ans == JOptionPane.YES_OPTION) {
 setUpGame();
 }else {
 System.exit(0);
 }
 }
 
 // readFile - read in wordList
 private String[] readFile(String loc){
 try {
 File f = new File(loc);
 assert f.exists() : "File doesn't exist";
 
 BufferedReader input = new BufferedReader(new FileReader(f));
 
 // read in the stuff into an arrayList here
 wordList = input.readLine().split(" ");
 // close the input stream
 input.close();
 }catch(IOException ioException){
 ioException.printStackTrace();
 }
 return wordList;
 }
 // setUpGame - sets up the variables appropriately
  private void setUpGame(){
  GuessesRemaining = 5;
 secretWord = chooseSecretWord(wordList);
 lettersRevealed = new boolean[secretWord.length()];
 Arrays.fill(lettersRevealed, false);
  lettersGuessed = new HashSet<Character>(26); // 26 letters in alphabet
 
 drawSecretWord();
 drawLettersGuessed();
 drawGuessesRemaining();
 }
 
 // updateSecretWord - updates which letters of the secret word have been revealed
 private void updateSecretWord(String l){
 List<Integer> changeBool = new ArrayList<Integer>();
 
 if(secretWord.contains(l)){
 // Searches through secretWord & notes down all letters that equal the user's guess
 for(int i=0; i<secretWord.length(); i++){
 if(secretWord.charAt(i) == l.charAt(0))
 changeBool.add(i);
 }

 // Changes the boolean value for those letters @ their corresponding indexes
 for(Integer idx : changeBool)
 lettersRevealed[idx] = true;
 }else{
 GuessesRemaining--;
 drawGuessesRemaining();
 }
 }
 
 // winSequence - when the user has correctly guessed the secret word
 private void winSequence(){
 playAgain("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!\n" +
 "Would you like to play another game of hangman?");
 }




 // GETTERS
 private String getText(){
 return textField.getText();
 }


 // SETTERS
 private void setText(final String t){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 textField.setText(t);
 }
 }
 );
 }
 
 
 // ActionListener
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 String guess = getText();
 
 if(checkUserGuess(guess)) {
 updateSecretWord(guess);
 drawSecretWord();
 
 if(lettersGuessed.size() != 0) // No letters have been guessed by the user at the beginning
 drawLettersGuessed();
 
 // Checks if the user has won or lost
 if (checkIfWon())
 winSequence();
 else if (GuessesRemaining == 0)
 loseSequence();
 }
 }
 }
 }
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.*;
import java.util.List;
import javax.swing.*;
public class Hangman {
 String[] wordList;
 String secretWord;
 Set<Character> alphabet;
 Set<Character> lettersGuessed; // letters the user has guessed
 boolean[] lettersRevealed; // determines if the letter should be revealed or not
 int GuessesRemaining;
 // GUI
 JFrame f;
 JTextField textField;
 JLabel guessesRemainingLabel;
 JLabel lettersGuessedLabel;
 JLabel secretWordLabel;
 public static void main(String[] args){
 Hangman h = new Hangman();
 h.createAlphabetSet();
 h.readFile("words.txt");
 h.buildGUI();
 h.setUpGame();
 h.drawSecretWord();
 }
 // buildGUI - builds the GUI
 private void buildGUI(){
 f = new JFrame("Hangman");
 // JLabels
 guessesRemainingLabel = new JLabel("Guesses remaining: " + String.valueOf(GuessesRemaining));
 lettersGuessedLabel = new JLabel("Already guessed: ");
 secretWordLabel = new JLabel();
 // Text field for user to type letters in
 textField = new JTextField();
 JButton checkButton = new JButton("Guess");
 // Add listeners to textField & checkButton
 TextListener textListener = new TextListener();
 checkButton.addActionListener(textListener);
 textField.addActionListener(textListener);
 // Panel for all the labels
 JPanel labelPanel = new JPanel();
 labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
 labelPanel.add(guessesRemainingLabel);
 labelPanel.add(lettersGuessedLabel);
 labelPanel.add(secretWordLabel);
 // User panel
 JPanel userPanel = new JPanel(new BorderLayout());
 userPanel.add(BorderLayout.CENTER, textField);
 userPanel.add(BorderLayout.EAST, checkButton);
 labelPanel.add(userPanel);
 // Add everything to frame
 f.add(BorderLayout.CENTER, labelPanel);
 f.setSize(250, 100);
 f.setLocationRelativeTo(null);
 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 f.setVisible(true);
 }
 // checkIfWon - sees if the user has won the game
 private boolean checkIfWon(){
 for(boolean tof : lettersRevealed){
 if(!tof)
 return false;
 }
 return true;
 }
 // get input from the user
 private boolean checkUserGuess(String l){
 if(l.length() == 1 && !lettersGuessed.contains(l.charAt(0)) && alphabet.contains(l.charAt(0))){
 setText(null);
 lettersGuessed.add(l.charAt(0));
 return true;
 }else {
 Toolkit.getDefaultToolkit().beep();
 }
 return false;
 }
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 // createAlphabetSet - Creates the alphabet set that's used to ensure that the user's guess not a number nor a special character
 private void createAlphabetSet(){
 alphabet = new HashSet<Character>(26);
 for(Character c = 'a'; c<='z'; c++){
 alphabet.add(c);
 }
 }
 // drawGuessesRemaining - Outputs the guesses remaining
 void drawGuessesRemaining(){
 final String guessesMessage = "Guesses remaining: " + String.valueOf(GuessesRemaining);
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 guessesRemainingLabel.setText(guessesMessage);
 guessesRemainingLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
 }
 }
 );
 }
 // drawLettersGuessed - Outputs the letters guessed
 void drawLettersGuessed(){
 StringBuilder lettersBuilder = new StringBuilder();
 for (Character el : lettersGuessed) {
 String s = el + " ";
 lettersBuilder.append(s);
 }
 final String letters = lettersBuilder.toString();
 SwingUtilities.invokeLater(
 new Runnable() {
 @Override
 public void run() {
 lettersGuessedLabel.setText("Already guessed: " + letters);
 }
 }
 );
 }
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 }

 final String w = word.toString();
  SwingUtilities.invokeLater(
 new Runnable(){
  @Override
 public void run(){
  secretWordLabel.setText(w);
 }
 }
 );
 }
 // loseSequence - when the the user runs out of guesses
 private void loseSequence(){
 for(int i=0; i<lettersRevealed.length; i++)
 lettersRevealed[i] = true;
 drawSecretWord();
 playAgain("Tough luck. The secret word was " + secretWord + ".\nWould you like to play another game of hangman?");
 }
 // playAgain - Allows the user to play another game of hangman
 private void playAgain(String message){
 int ans = JOptionPane.showConfirmDialog(f, message,
 "Play again?", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
 if(ans == JOptionPane.YES_OPTION) {
 setUpGame();
 }else {
 System.exit(0);
 }
 }
 // readFile - read in wordList
 private String[] readFile(String loc){
 try {
 File f = new File(loc);
 assert f.exists() : "File doesn't exist";
 BufferedReader input = new BufferedReader(new FileReader(f));
 // read in the stuff into an arrayList here
 wordList = input.readLine().split(" ");
 // close the input stream
 input.close();
 }catch(IOException ioException){
  ioException.printStackTrace();
 }
 return wordList;
 }
 // setUpGame - sets up the variables appropriately
 private void setUpGame(){
 GuessesRemaining = 5;
 secretWord = chooseSecretWord(wordList);
  lettersRevealed = new boolean[secretWord.length()];
 Arrays.fill(lettersRevealed, false);
 lettersGuessed = new HashSet<Character>(26);  // 26 letters in alphabet

 drawSecretWord();
 drawLettersGuessed();
  drawGuessesRemaining();
 }
 // updateSecretWord - updates which letters of the secret word have been revealed
 private void updateSecretWord(String l){
 List<Integer> changeBool = new ArrayList<Integer>();
  if(secretWord.contains(l)){
 // Searches through secretWord & notes down all letters that equal the user's guess
 for(int i=0; i<secretWord.length(); i++){
  if(secretWord.charAt(i) == l.charAt(0))
  changeBool.add(i);
 }
 // Changes the boolean value for those letters @ their corresponding indexes
 for(Integer idx : changeBool)
 lettersRevealed[idx] = true;
 }else{
 GuessesRemaining--;
 drawGuessesRemaining();
 }
 }
 // winSequence - when the user has correctly guessed the secret word
 private void winSequence(){
 playAgain("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!\n" +
 "Would you like to play another game of hangman?");
 }
 // GETTERS
 private String getText(){
 return textField.getText();
 }
 // SETTERS
 private void setText(final String t){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 textField.setText(t);
 }
 }
 );
 }
 // ActionListener
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 String guess = getText();
 if(checkUserGuess(guess)) {
 updateSecretWord(guess);
 drawSecretWord();
 if(lettersGuessed.size() != 0) // No letters have been guessed by the user at the beginning
 drawLettersGuessed();
 // Checks if the user has won or lost
 if (checkIfWon())
 winSequence();
 else if (GuessesRemaining == 0)
 loseSequence();
 }
 }
 }
}
Fixed code
Source Link
Calculus5000
  • 787
  • 1
  • 8
  • 17

Today I wroteHere's an implementation of Hangman (code below) that was originally written to be used on the command-line. I'm in the process of getting it to work on some simple GUI, and I've almost got it to work onwritten that uses a basic GUI, however I'm having difficulty in determining how to get the user input from the JTextField into the appropriate parts of the code (like the userGuess() invoked in the play() method).

I understand that the action listener linked to the JTextField will run on the EDT & so isn't that a separate thread from the thread of that play() is in? Do I need to send the info from the EDT thread to the main thread? I know As I can get the text using .getText() but I'd like for the code to wait for the useram new to make a guess (i.e. block), like how it waits in the command-line when Scanner(System.in) is used.

AlsoJava, please let me know of any improvements I can make to my coding style. Thanks for your help.

 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.*;
 import java.util.*;
 import java.util.List;
 import javax.swing.*;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 
 
 public class Hangman {
 String[] wordList;
 String secretWord;
 Set<Character> alphabet;
 Set<Character> lettersGuessed; // letters the user has guessed
 boolean[] lettersRevealed; // determines if the letter should be revealed or not
 
 Scanner k = new Scanner(System.in);
 
 boolean keepGoing;
 boolean keepPlaying; // allows the player to play another game of hangman
 int GuessesRemaining;
 
 // GUI
 DocumentJFrame doc;f;
 JTextField textField;
 JLabel guessesRemainingLabel;
 JLabel lettersGuessedLabel;
 JLabel secretWordLabel;
 
 
 public static void main(String[] args){
 Hangman h = new Hangman();
 h.createAlphabetSet();
 h.readFile("words.txt");
 h.buildGUI();
 h.play();
 }
 
 // appendMessage - appends text to the text area
 private void appendMessage(final String message){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 try{
 doc.insertString(doc.getLengthsetUpGame(), message, null);
 }catch(BadLocationException badLocationException){
  badLocationExceptionh.printStackTracedrawSecretWord();
 }
 }
 }
 );
 }
 
 // buildGUI - builds the GUI
 private void buildGUI(){
 JFrame f = new JFrame("Hangman");
 
 // Text area
 JTextArea textArea = new JTextArea();
 doc = textArea.getDocument();
 textArea.setEditable(false);
 textArea.setLineWrap(true);
 textArea.setWrapStyleWord(true);
 
 JScrollPane// jspJLabels
  guessesRemainingLabel = new JScrollPaneJLabel(textArea"Guesses remaining: " + String.valueOf(GuessesRemaining));
 lettersGuessedLabel = new JLabel("Already guessed: ");
 secretWordLabel = new JLabel();
 
 // Text field for user to type letters in
 textField = new JTextField(10); // TODO fix the textField's size
 JButton checkButton = new JButton("Send""Guess");
 
 // Add listeners to textField & checkButton
 TextListener textListener = new TextListener();
 checkButton.addActionListener(textListener);
 textField.addActionListener(textListener);
 
 // AddPanel everythingfor toall framethe labels
 JPanel panellabelPanel = new JPanel();
 panellabelPanel.addsetLayout(BorderLayout.WESTnew BoxLayout(labelPanel, textFieldBoxLayout.PAGE_AXIS));
 panellabelPanel.add(BorderLayoutguessesRemainingLabel);
 labelPanel.EAST,add(lettersGuessedLabel);
 checkButton labelPanel.add(secretWordLabel);
 
 f// User panel
 JPanel userPanel = new JPanel(new BorderLayout());
 userPanel.add(BorderLayout.CENTER, jsptextField);
 fuserPanel.add(BorderLayout.SOUTHEAST, panelcheckButton);
 labelPanel.add(userPanel);
 
 // Add everything to frame
 f.add(BorderLayout.CENTER, labelPanel);
 
 f.setSize(300250, 300100);
 f.setLocationRelativeTo(null);
 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 f.setVisible(true);
 }
 
 // checkIfWon - sees if the user has won the game
 private boolean checkIfWon(){
 for(boolean tof : lettersRevealed){
 if(!tof)
 return false;
 }
 return true;
 }
 
 // get input from the user
 private boolean checkUserGuess(String l){
 if(l.length() == 1 && !lettersGuessed.contains(l.charAt(0)) && alphabet.contains(l.charAt(0))) {
 setText(null);
 lettersGuessed.add(l.charAt(0));
 return true;
 }else {
 Toolkit.getDefaultToolkit().beep();
 }
 return false;
 }
 
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 
 // createAlphabetSet - Creates the alphabet set that's used to ensure that the user's guess not a number nor a special character
 private void createAlphabetSet(){
 alphabet = new HashSet<Character>(26);
 for(Character c = 'a'; c<='z'; c++){
 alphabet.add(c);
 }
 }
 
 // drawGuessesRemaining - Outputs the guesses remaining
 void drawGuessesRemaining(){
 final String guessesMessage = "Guesses remaining: " + String.valueOf(GuessesRemaining);
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 guessesRemainingLabel.setText(guessesMessage);
 guessesRemainingLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
 }
 }
 );
 }
 
 // drawLettersGuessed - Outputs the letters guessed
 void drawLettersGuessed(){
 StringBuilder lettersBuilder = new StringBuilder();
 for (Character el : lettersGuessed) {
 String s = el + " ";
 lettersBuilder.append(s);
 }
 
 final String letters = lettersBuilder.toString();
 SwingUtilities.invokeLater(
 new Runnable() {
 @Override
 public void run() {
 lettersGuessedLabel.setText("Already guessed: " + letters);
 }
 }
 );
 }
 
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 }
 appendMessage(word + "\n");
 System.out.println(word);
 }
 
 // play - Initiates a game of hangman
 public void play(){
 keepPlaying = true;
 createAlphabetSet();
 
 while(keepPlaying) {
 setUpGame();
 appendMessage("Welcome to hangman! You have 5 guesses to guess the secret word.\n");
 System.out.println("Welcome to hangman! You have 5 guesses to guess the secret word.");
 
 // user's guess
 String guess;
 while (GuessesRemaining > 0 && keepGoing) {
 drawSecretWord();
 
 // Doesn't output this at the beginning
 final String w = if(lettersGuessedword.sizetoString() != 0) {;
 appendMessageSwingUtilities.invokeLater("Letters already guessed: ");
 new System.out.printRunnable("Letters already guessed: ");{
 for (Character el : lettersGuessed) {@Override
 public void appendMessagerun(el + " ");{
 System.outsecretWordLabel.printsetText(el + " "w);
 }
 appendMessage("\n");
 System.out.println();
 }
 
 guess = userGuess("Guess a letter:");
 updateSecretWord(guess);
 
 appendMessage("\n");
 System.out.println();
 
 if (checkIfWon()) {
 keepGoing = false;
 appendMessage("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!\n");
 System.out.println("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!");
 }
 }
 
 // If player runs out of guesses
 if (GuessesRemaining == 0) {
 appendMessage("Tough luck. The secret word was " + secretWord + "\n");
 System.out.println("Tough luck. The secret word was " + secretWord);
 }
 
 // loseSequence - when the the user runs out of guesses
 playAgain private void loseSequence("Would){
 you like to play another game of hangman? for(typeint yesi=0; ori<lettersRevealed.length; noi++)"
 lettersRevealed[i] = true;
 drawSecretWord();
 }playAgain("Tough luck. The secret word was " + secretWord + ".\nWould you like to play another game of hangman?");
 }
 
 // playAgain - Allows the user to play another game of hangman
 private void playAgain(String message){
 appendMessage(messageint +ans "\n");
= JOptionPane.showConfirmDialog(f, message,
 System.out.println(message);
  String ans"Play =again?", kJOptionPane.next()YES_NO_OPTION, JOptionPane.toLowerCase(PLAIN_MESSAGE);
 
 if(ans == JOptionPane.equals("yes")YES_OPTION) {
 appendMessage("Okay! Let's play another game of hangman!\n\n\n");
 System.out.printlnsetUpGame("Okay! Let's play another game of hangman!\n\n");
 }else if(ans.equals("no")){
 keepPlaying = false;
 appendMessage("Fair enough. Bye!");
 System.out.println("Fair enough. Bye!");
 }else{
 playAgainexit("Invalid input. Please type in yes or no: "0);
 }
 }
 
 // readFile - read in wordList
 private String[] readFile(String loc){
 try {
 File f = new File(loc);
 assert f.exists() : "File doesn't exist";
 
 BufferedReader input = new BufferedReader(new FileReader(f));
 
 // read in the stuff into an arrayList here
 wordList = input.readLine().split(" ");
 
 // close the input stream
 input.close();
 }catch(IOException ioException){
 ioException.printStackTrace();
 }
 return wordList;
 }
 
 // setUpGame - sets up the variables appropriately
 private void setUpGame(){
 keepGoing = true;
 GuessesRemaining = 5;
 secretWord = chooseSecretWord(wordList);
 lettersRevealed = new boolean[secretWord.length()];
 Arrays.fill(lettersRevealed, false);
 lettersGuessed = new HashSet<Character>(26); // 26 letters in alphabet
 
 drawSecretWord();
 drawLettersGuessed();
 drawGuessesRemaining();
 }
 
 // updateSecretWord - updates which letters of the secret word have been revealed
 private void updateSecretWord(String l){
 List<Integer> changeBool = new ArrayList<Integer>();
 
 if(secretWord.contains(l)){
 // Searches through secretWord & notes down all letters that equal the user's guess
 for(int i=0; i<secretWord.length(); i++){
 if(secretWord.charAt(i) == l.charAt(0))
 changeBool.add(i);
 }
 
 // Changes the boolean value for those letters @ their corresponding indexes
 for(Integer idx : changeBool)
 lettersRevealed[idx] = true;
 }else{
 GuessesRemaining--;
 appendMessage("Letter not found. You have " + GuessesRemaining + " guesses remaining.\n");
 System.out.printlndrawGuessesRemaining("Letter not found. You have " + GuessesRemaining + " guesses remaining.");
 }
 }
 
 // getwinSequence input- fromwhen the user has correctly guessed the secret word
 private Stringvoid userGuesswinSequence(String message){
 appendMessageplayAgain(message"Well done! You guessed " + "\n");secretWord + " with " + GuessesRemaining + " guesses left!\n" +
 System.out.println(message);
 "Would you like to Stringplay lanother =game k.next().toLowerCase(of hangman?");
 }
 
 if(l.length() == 0) {
 l = userGuess("Nothing has been typed. Please guess a letter:");
 }else if(l.length() > 1) {
 l = userGuess("More than one letter was typed. Please select only one letter:");
 }else if(lettersGuessed.contains(l.charAt(0))){
 l = userGuess("Letter already guessed. Please choose another letter:");
 }else if(!alphabet.contains(l.charAt(0))){
 l = userGuess("Not a letter. Please choose a letter:");
 }
 
 lettersGuessed.add(l.charAt(0));
 return l;
 }
 
 
 // GETTERS
 private String getText(){
 return textField.getText();
 }
 
 
 // SETTERS
 private void setText(final String t){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 textField.setText(t);
 }
 }
 );
 }
 
 
 // ActionListener -- TODO need the input from the the textField to go into userGuess method somehow
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 appendMessage(String guess = getText();
 
 if(checkUserGuess(guess)) {
 updateSecretWord(guess);
 setText drawSecretWord(null);
 
 if(lettersGuessed.size() != 0) // No letters have been guessed by the user at the beginning
 drawLettersGuessed();
 
 // Checks if the user has won or lost
 if (checkIfWon())
 winSequence();
 else if (GuessesRemaining == 0)
 loseSequence();
 }
 }
 }
 }

Today I wrote an implementation of Hangman (code below) that was originally written to be used on the command-line. I'm in the process of getting it to work on some simple GUI, and I've almost got it to work on a GUI, however I'm having difficulty in determining how to get the user input from the JTextField into the appropriate parts of the code (like the userGuess() invoked in the play() method).

I understand that the action listener linked to the JTextField will run on the EDT & so isn't that a separate thread from the thread of that play() is in? Do I need to send the info from the EDT thread to the main thread? I know I can get the text using .getText() but I'd like for the code to wait for the user to make a guess (i.e. block), like how it waits in the command-line when Scanner(System.in) is used.

Also, please let me know of any improvements I can make to my coding style. Thanks for your help.

 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.*;
 import java.util.*;
 import java.util.List;
 import javax.swing.*;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 
 
 public class Hangman {
 String[] wordList;
 String secretWord;
 Set<Character> alphabet;
 Set<Character> lettersGuessed; // letters the user has guessed
 boolean[] lettersRevealed; // determines if the letter should be revealed or not
 
 Scanner k = new Scanner(System.in);
 
 boolean keepGoing;
 boolean keepPlaying; // allows the player to play another game of hangman
 int GuessesRemaining;
 
 // GUI
 Document doc;
 JTextField textField;
 
 
 public static void main(String[] args){
 Hangman h = new Hangman();
 h.readFile("words.txt");
 h.buildGUI();
 h.play();
 }
 
 // appendMessage - appends text to the text area
 private void appendMessage(final String message){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 try{
 doc.insertString(doc.getLength(), message, null);
 }catch(BadLocationException badLocationException){
  badLocationException.printStackTrace();
 }
 }
 }
 );
 }
 
 // buildGUI - builds the GUI
 private void buildGUI(){
 JFrame f = new JFrame("Hangman");
 
 // Text area
 JTextArea textArea = new JTextArea();
 doc = textArea.getDocument();
 textArea.setEditable(false);
 textArea.setLineWrap(true);
 textArea.setWrapStyleWord(true);
 
 JScrollPane jsp = new JScrollPane(textArea);
 
 // Text field for user to type letters in
 textField = new JTextField(10); // TODO fix the textField's size
 JButton checkButton = new JButton("Send");
 
 // Add listeners to textField & checkButton
 TextListener textListener = new TextListener();
 checkButton.addActionListener(textListener);
 textField.addActionListener(textListener);
 
 // Add everything to frame
 JPanel panel = new JPanel();
 panel.add(BorderLayout.WEST, textField);
 panel.add(BorderLayout.EAST, checkButton);
 
 f.add(BorderLayout.CENTER, jsp);
 f.add(BorderLayout.SOUTH, panel);
 
 f.setSize(300, 300);
 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 f.setVisible(true);
 }
 
 // checkIfWon - sees if the user has won the game
 private boolean checkIfWon(){
 for(boolean tof : lettersRevealed){
 if(!tof)
 return false;
 }
 return true;
 }
 
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 
 // createAlphabetSet - Creates the alphabet set that's used to ensure that the user's guess not a number nor a special character
 private void createAlphabetSet(){
 alphabet = new HashSet<Character>(26);
 for(Character c = 'a'; c<='z'; c++){
 alphabet.add(c);
 }
 }
 
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 }
 appendMessage(word + "\n");
 System.out.println(word);
 }
 
 // play - Initiates a game of hangman
 public void play(){
 keepPlaying = true;
 createAlphabetSet();
 
 while(keepPlaying) {
 setUpGame();
 appendMessage("Welcome to hangman! You have 5 guesses to guess the secret word.\n");
 System.out.println("Welcome to hangman! You have 5 guesses to guess the secret word.");
 
 // user's guess
 String guess;
 while (GuessesRemaining > 0 && keepGoing) {
 drawSecretWord();
 
 // Doesn't output this at the beginning
  if(lettersGuessed.size() != 0) {
 appendMessage("Letters already guessed: ");
 System.out.print("Letters already guessed: ");
 for (Character el : lettersGuessed) {
 appendMessage(el + " ");
 System.out.print(el + " ");
 }
 appendMessage("\n");
 System.out.println();
 }
 
 guess = userGuess("Guess a letter:");
 updateSecretWord(guess);
 
 appendMessage("\n");
 System.out.println();
 
 if (checkIfWon()) {
 keepGoing = false;
 appendMessage("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!\n");
 System.out.println("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!");
 }
 }
 
 // If player runs out of guesses
 if (GuessesRemaining == 0) {
 appendMessage("Tough luck. The secret word was " + secretWord + "\n");
 System.out.println("Tough luck. The secret word was " + secretWord);
 }
 
 playAgain("Would you like to play another game of hangman? (type yes or no)");
 }
 }
 
 // playAgain - Allows the user to play another game of hangman
 private void playAgain(String message){
 appendMessage(message + "\n");
 System.out.println(message);
  String ans = k.next().toLowerCase();
 
 if(ans.equals("yes")) {
 appendMessage("Okay! Let's play another game of hangman!\n\n\n");
 System.out.println("Okay! Let's play another game of hangman!\n\n");
 }else if(ans.equals("no")){
 keepPlaying = false;
 appendMessage("Fair enough. Bye!");
 System.out.println("Fair enough. Bye!");
 }else{
 playAgain("Invalid input. Please type in yes or no: ");
 }
 }
 
 // readFile - read in wordList
 private String[] readFile(String loc){
 try {
 File f = new File(loc);
 assert f.exists() : "File doesn't exist";
 
 BufferedReader input = new BufferedReader(new FileReader(f));
 
 // read in the stuff into an arrayList here
 wordList = input.readLine().split(" ");
 
 // close the input stream
 input.close();
 }catch(IOException ioException){
 ioException.printStackTrace();
 }
 return wordList;
 }
 
 // setUpGame - sets up the variables appropriately
 private void setUpGame(){
 keepGoing = true;
 GuessesRemaining = 5;
 secretWord = chooseSecretWord(wordList);
 lettersRevealed = new boolean[secretWord.length()];
 Arrays.fill(lettersRevealed, false);
 lettersGuessed = new HashSet<Character>(26); // 26 letters in alphabet
 }
 
 // updateSecretWord - updates which letters of the secret word have been revealed
 private void updateSecretWord(String l){
 List<Integer> changeBool = new ArrayList<Integer>();
 
 if(secretWord.contains(l)){
 // Searches through secretWord & notes down all letters that equal the user's guess
 for(int i=0; i<secretWord.length(); i++){
 if(secretWord.charAt(i) == l.charAt(0))
 changeBool.add(i);
 }
 
 // Changes the boolean value for those letters @ their corresponding indexes
 for(Integer idx : changeBool)
 lettersRevealed[idx] = true;
 }else{
 GuessesRemaining--;
 appendMessage("Letter not found. You have " + GuessesRemaining + " guesses remaining.\n");
 System.out.println("Letter not found. You have " + GuessesRemaining + " guesses remaining.");
 }
 }
 
 // get input from the user
 private String userGuess(String message){
 appendMessage(message + "\n");
 System.out.println(message);
 String l = k.next().toLowerCase();
 
 if(l.length() == 0) {
 l = userGuess("Nothing has been typed. Please guess a letter:");
 }else if(l.length() > 1) {
 l = userGuess("More than one letter was typed. Please select only one letter:");
 }else if(lettersGuessed.contains(l.charAt(0))){
 l = userGuess("Letter already guessed. Please choose another letter:");
 }else if(!alphabet.contains(l.charAt(0))){
 l = userGuess("Not a letter. Please choose a letter:");
 }
 
 lettersGuessed.add(l.charAt(0));
 return l;
 }
 
 
 // GETTERS
 private String getText(){
 return textField.getText();
 }
 
 
 // SETTERS
 private void setText(final String t){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 textField.setText(t);
 }
 }
 );
 }
 
 
 // ActionListener -- TODO need the input from the the textField to go into userGuess method somehow
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 appendMessage(getText());
 setText(null);
 }
 }
 }

Here's an implementation of Hangman that I've written that uses a basic GUI. As I am new to Java, please let me know of any improvements I can make to my coding style. Thanks for your help.

 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.*;
 import java.util.*;
 import java.util.List;
 import javax.swing.*;
 
 
 public class Hangman {
 String[] wordList;
 String secretWord;
 Set<Character> alphabet;
 Set<Character> lettersGuessed; // letters the user has guessed
 boolean[] lettersRevealed; // determines if the letter should be revealed or not
 
 int GuessesRemaining;
 
 // GUI
 JFrame f;
 JTextField textField;
 JLabel guessesRemainingLabel;
 JLabel lettersGuessedLabel;
 JLabel secretWordLabel;
 
 
 public static void main(String[] args){
 Hangman h = new Hangman();
 h.createAlphabetSet();
 h.readFile("words.txt");
 h.buildGUI();
 h.setUpGame();
 h.drawSecretWord();
 }
 
 // buildGUI - builds the GUI
 private void buildGUI(){
 f = new JFrame("Hangman");
 
 // JLabels
  guessesRemainingLabel = new JLabel("Guesses remaining: " + String.valueOf(GuessesRemaining));
 lettersGuessedLabel = new JLabel("Already guessed: ");
 secretWordLabel = new JLabel();
 
 // Text field for user to type letters in
 textField = new JTextField();
 JButton checkButton = new JButton("Guess");
 
 // Add listeners to textField & checkButton
 TextListener textListener = new TextListener();
 checkButton.addActionListener(textListener);
 textField.addActionListener(textListener);
 
 // Panel for all the labels
 JPanel labelPanel = new JPanel();
 labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.PAGE_AXIS));
 labelPanel.add(guessesRemainingLabel);
 labelPanel.add(lettersGuessedLabel);
  labelPanel.add(secretWordLabel);
 
 // User panel
 JPanel userPanel = new JPanel(new BorderLayout());
 userPanel.add(BorderLayout.CENTER, textField);
 userPanel.add(BorderLayout.EAST, checkButton);
 labelPanel.add(userPanel);
 
 // Add everything to frame
 f.add(BorderLayout.CENTER, labelPanel);
 
 f.setSize(250, 100);
 f.setLocationRelativeTo(null);
 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 f.setVisible(true);
 }
 
 // checkIfWon - sees if the user has won the game
 private boolean checkIfWon(){
 for(boolean tof : lettersRevealed){
 if(!tof)
 return false;
 }
 return true;
 }
 
 // get input from the user
 private boolean checkUserGuess(String l){
 if(l.length() == 1 && !lettersGuessed.contains(l.charAt(0)) && alphabet.contains(l.charAt(0))) {
 setText(null);
 lettersGuessed.add(l.charAt(0));
 return true;
 }else {
 Toolkit.getDefaultToolkit().beep();
 }
 return false;
 }
 
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 
 // createAlphabetSet - Creates the alphabet set that's used to ensure that the user's guess not a number nor a special character
 private void createAlphabetSet(){
 alphabet = new HashSet<Character>(26);
 for(Character c = 'a'; c<='z'; c++){
 alphabet.add(c);
 }
 }
 
 // drawGuessesRemaining - Outputs the guesses remaining
 void drawGuessesRemaining(){
 final String guessesMessage = "Guesses remaining: " + String.valueOf(GuessesRemaining);
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 guessesRemainingLabel.setText(guessesMessage);
 guessesRemainingLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
 }
 }
 );
 }
 
 // drawLettersGuessed - Outputs the letters guessed
 void drawLettersGuessed(){
 StringBuilder lettersBuilder = new StringBuilder();
 for (Character el : lettersGuessed) {
 String s = el + " ";
 lettersBuilder.append(s);
 }
 
 final String letters = lettersBuilder.toString();
 SwingUtilities.invokeLater(
 new Runnable() {
 @Override
 public void run() {
 lettersGuessedLabel.setText("Already guessed: " + letters);
 }
 }
 );
 }
 
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 }
 
 final String w = word.toString();
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 secretWordLabel.setText(w);
 }
 }
 );
 }
 
 // loseSequence - when the the user runs out of guesses
  private void loseSequence(){
 for(int i=0; i<lettersRevealed.length; i++)
 lettersRevealed[i] = true;
 drawSecretWord();
 playAgain("Tough luck. The secret word was " + secretWord + ".\nWould you like to play another game of hangman?");
 }
 
 // playAgain - Allows the user to play another game of hangman
 private void playAgain(String message){
 int ans = JOptionPane.showConfirmDialog(f, message,
 "Play again?", JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE);
 
 if(ans == JOptionPane.YES_OPTION) {
 setUpGame();
 }else {
 System.exit(0);
 }
 }
 
 // readFile - read in wordList
 private String[] readFile(String loc){
 try {
 File f = new File(loc);
 assert f.exists() : "File doesn't exist";
 
 BufferedReader input = new BufferedReader(new FileReader(f));
 
 // read in the stuff into an arrayList here
 wordList = input.readLine().split(" ");
 
 // close the input stream
 input.close();
 }catch(IOException ioException){
 ioException.printStackTrace();
 }
 return wordList;
 }
 
 // setUpGame - sets up the variables appropriately
 private void setUpGame(){
 GuessesRemaining = 5;
 secretWord = chooseSecretWord(wordList);
 lettersRevealed = new boolean[secretWord.length()];
 Arrays.fill(lettersRevealed, false);
 lettersGuessed = new HashSet<Character>(26); // 26 letters in alphabet
 
 drawSecretWord();
 drawLettersGuessed();
 drawGuessesRemaining();
 }
 
 // updateSecretWord - updates which letters of the secret word have been revealed
 private void updateSecretWord(String l){
 List<Integer> changeBool = new ArrayList<Integer>();
 
 if(secretWord.contains(l)){
 // Searches through secretWord & notes down all letters that equal the user's guess
 for(int i=0; i<secretWord.length(); i++){
 if(secretWord.charAt(i) == l.charAt(0))
 changeBool.add(i);
 }
 
 // Changes the boolean value for those letters @ their corresponding indexes
 for(Integer idx : changeBool)
 lettersRevealed[idx] = true;
 }else{
 GuessesRemaining--;
 drawGuessesRemaining();
 }
 }
 
 // winSequence - when the user has correctly guessed the secret word
 private void winSequence(){
 playAgain("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!\n" +
 "Would you like to play another game of hangman?");
 }
 
 
 
 
 // GETTERS
 private String getText(){
 return textField.getText();
 }
 
 
 // SETTERS
 private void setText(final String t){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 textField.setText(t);
 }
 }
 );
 }
 
 
 // ActionListener
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 String guess = getText();
 
 if(checkUserGuess(guess)) {
 updateSecretWord(guess);
  drawSecretWord();
 
 if(lettersGuessed.size() != 0) // No letters have been guessed by the user at the beginning
 drawLettersGuessed();
 
 // Checks if the user has won or lost
 if (checkIfWon())
 winSequence();
 else if (GuessesRemaining == 0)
 loseSequence();
 }
 }
 }
 }
Post Closed as "Not suitable for this site" by Community Bot, Jamal
Source Link
Calculus5000
  • 787
  • 1
  • 8
  • 17

Implementation of Hangman in Java

Today I wrote an implementation of Hangman (code below) that was originally written to be used on the command-line. I'm in the process of getting it to work on some simple GUI, and I've almost got it to work on a GUI, however I'm having difficulty in determining how to get the user input from the JTextField into the appropriate parts of the code (like the userGuess() invoked in the play() method).

I understand that the action listener linked to the JTextField will run on the EDT & so isn't that a separate thread from the thread of that play() is in? Do I need to send the info from the EDT thread to the main thread? I know I can get the text using .getText() but I'd like for the code to wait for the user to make a guess (i.e. block), like how it waits in the command-line when Scanner(System.in) is used.

Also, please let me know of any improvements I can make to my coding style. Thanks for your help.

 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.io.*;
 import java.util.*;
 import java.util.List;
 import javax.swing.*;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 
 
 public class Hangman {
 String[] wordList;
 String secretWord;
 Set<Character> alphabet;
 Set<Character> lettersGuessed; // letters the user has guessed
 boolean[] lettersRevealed; // determines if the letter should be revealed or not
 
 Scanner k = new Scanner(System.in);
 
 boolean keepGoing;
 boolean keepPlaying; // allows the player to play another game of hangman
 int GuessesRemaining;
 
 // GUI
 Document doc;
 JTextField textField;
 
 
 public static void main(String[] args){
 Hangman h = new Hangman();
 h.readFile("words.txt");
 h.buildGUI();
 h.play();
 }
 
 // appendMessage - appends text to the text area
 private void appendMessage(final String message){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 try{
 doc.insertString(doc.getLength(), message, null);
 }catch(BadLocationException badLocationException){
 badLocationException.printStackTrace();
 }
 }
 }
 );
 }
 
 // buildGUI - builds the GUI
 private void buildGUI(){
 JFrame f = new JFrame("Hangman");
 
 // Text area
 JTextArea textArea = new JTextArea();
 doc = textArea.getDocument();
 textArea.setEditable(false);
 textArea.setLineWrap(true);
 textArea.setWrapStyleWord(true);
 
 JScrollPane jsp = new JScrollPane(textArea);
 
 // Text field for user to type letters in
 textField = new JTextField(10); // TODO fix the textField's size
 JButton checkButton = new JButton("Send");
 
 // Add listeners to textField & checkButton
 TextListener textListener = new TextListener();
 checkButton.addActionListener(textListener);
 textField.addActionListener(textListener);
 
 // Add everything to frame
 JPanel panel = new JPanel();
 panel.add(BorderLayout.WEST, textField);
 panel.add(BorderLayout.EAST, checkButton);
 
 f.add(BorderLayout.CENTER, jsp);
 f.add(BorderLayout.SOUTH, panel);
 
 f.setSize(300, 300);
 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
 f.setVisible(true);
 }
 
 // checkIfWon - sees if the user has won the game
 private boolean checkIfWon(){
 for(boolean tof : lettersRevealed){
 if(!tof)
 return false;
 }
 return true;
 }
 
 // chooseSecretWord - selects a word
 private String chooseSecretWord(String[] wordList){
 return wordList[(int)(Math.random() * wordList.length)];
 }
 
 // createAlphabetSet - Creates the alphabet set that's used to ensure that the user's guess not a number nor a special character
 private void createAlphabetSet(){
 alphabet = new HashSet<Character>(26);
 for(Character c = 'a'; c<='z'; c++){
 alphabet.add(c);
 }
 }
 
 // drawSecretWord - draws the secret word with dashes & etc for user to use to guess the word with
 private void drawSecretWord(){
 StringBuilder word = new StringBuilder();
 for(int i=0; i<lettersRevealed.length; i++){
 
 if(lettersRevealed[i]){
 String s = secretWord.charAt(i) + " ";
 word.append(s);
 }else{
 word.append("_ ");
 }
 }
 appendMessage(word + "\n");
 System.out.println(word);
 }
 
 // play - Initiates a game of hangman
 public void play(){
 keepPlaying = true;
 createAlphabetSet();
 
 while(keepPlaying) {
 setUpGame();
 appendMessage("Welcome to hangman! You have 5 guesses to guess the secret word.\n");
 System.out.println("Welcome to hangman! You have 5 guesses to guess the secret word.");
 
 // user's guess
 String guess;
 while (GuessesRemaining > 0 && keepGoing) {
 drawSecretWord();
 
 // Doesn't output this at the beginning
 if(lettersGuessed.size() != 0) {
 appendMessage("Letters already guessed: ");
 System.out.print("Letters already guessed: ");
 for (Character el : lettersGuessed) {
 appendMessage(el + " ");
 System.out.print(el + " ");
 }
 appendMessage("\n");
 System.out.println();
 }
 
 guess = userGuess("Guess a letter:");
 updateSecretWord(guess);
 
 appendMessage("\n");
 System.out.println();
 
 if (checkIfWon()) {
 keepGoing = false;
 appendMessage("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!\n");
 System.out.println("Well done! You guessed " + secretWord + " with " + GuessesRemaining + " guesses left!");
 }
 }
 
 // If player runs out of guesses
 if (GuessesRemaining == 0) {
 appendMessage("Tough luck. The secret word was " + secretWord + "\n");
 System.out.println("Tough luck. The secret word was " + secretWord);
 }
 
 playAgain("Would you like to play another game of hangman? (type yes or no)");
 }
 }
 
 // playAgain - Allows the user to play another game of hangman
 private void playAgain(String message){
 appendMessage(message + "\n");
 System.out.println(message);
 String ans = k.next().toLowerCase();
 
 if(ans.equals("yes")) {
 appendMessage("Okay! Let's play another game of hangman!\n\n\n");
 System.out.println("Okay! Let's play another game of hangman!\n\n");
 }else if(ans.equals("no")){
 keepPlaying = false;
 appendMessage("Fair enough. Bye!");
 System.out.println("Fair enough. Bye!");
 }else{
 playAgain("Invalid input. Please type in yes or no: ");
 }
 }
 
 // readFile - read in wordList
 private String[] readFile(String loc){
 try {
 File f = new File(loc);
 assert f.exists() : "File doesn't exist";
 
 BufferedReader input = new BufferedReader(new FileReader(f));
 
 // read in the stuff into an arrayList here
 wordList = input.readLine().split(" ");
 
 // close the input stream
 input.close();
 }catch(IOException ioException){
 ioException.printStackTrace();
 }
 return wordList;
 }
 
 // setUpGame - sets up the variables appropriately
 private void setUpGame(){
 keepGoing = true;
 GuessesRemaining = 5;
 secretWord = chooseSecretWord(wordList);
 lettersRevealed = new boolean[secretWord.length()];
 Arrays.fill(lettersRevealed, false);
 lettersGuessed = new HashSet<Character>(26); // 26 letters in alphabet
 }
 
 // updateSecretWord - updates which letters of the secret word have been revealed
 private void updateSecretWord(String l){
 List<Integer> changeBool = new ArrayList<Integer>();
 
 if(secretWord.contains(l)){
 // Searches through secretWord & notes down all letters that equal the user's guess
 for(int i=0; i<secretWord.length(); i++){
 if(secretWord.charAt(i) == l.charAt(0))
 changeBool.add(i);
 }
 
 // Changes the boolean value for those letters @ their corresponding indexes
 for(Integer idx : changeBool)
 lettersRevealed[idx] = true;
 }else{
 GuessesRemaining--;
 appendMessage("Letter not found. You have " + GuessesRemaining + " guesses remaining.\n");
 System.out.println("Letter not found. You have " + GuessesRemaining + " guesses remaining.");
 }
 }
 
 // get input from the user
 private String userGuess(String message){
 appendMessage(message + "\n");
 System.out.println(message);
 String l = k.next().toLowerCase();
 
 if(l.length() == 0) {
 l = userGuess("Nothing has been typed. Please guess a letter:");
 }else if(l.length() > 1) {
 l = userGuess("More than one letter was typed. Please select only one letter:");
 }else if(lettersGuessed.contains(l.charAt(0))){
 l = userGuess("Letter already guessed. Please choose another letter:");
 }else if(!alphabet.contains(l.charAt(0))){
 l = userGuess("Not a letter. Please choose a letter:");
 }
 
 lettersGuessed.add(l.charAt(0));
 return l;
 }
 
 
 // GETTERS
 private String getText(){
 return textField.getText();
 }
 
 
 // SETTERS
 private void setText(final String t){
 SwingUtilities.invokeLater(
 new Runnable(){
 @Override
 public void run(){
 textField.setText(t);
 }
 }
 );
 }
 
 
 // ActionListener -- TODO need the input from the the textField to go into userGuess method somehow
 private class TextListener implements ActionListener {
 @Override
 public void actionPerformed(ActionEvent ev){
 appendMessage(getText());
 setText(null);
 }
 }
 }
lang-java

AltStyle によって変換されたページ (->オリジナル) /