pretty much completed hangman, but "new" button is not working
I have almost completed my hangman project. However, I have a JButton called bNew and I attached an ActionListener to it that resets all of the variables to 0, redoes all of the JPanels, and redraws everything. For some reason though the only thing that changes is one of the JLabels and everything else remains the same. The previous word remains shown, and the alphabet remains colored (I make each chosen letter green). Also the KeyListener doesn't work for games after the first either. I can't figure out why this is happening because I am renewing the variables/revalidating the JPanel.
Here's my code for the client. I believe the probem lies in the ActionListener for the bNew button, or in the createBoard method, or both.
Code:
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Hangman {
public static void main(String[] args) {
Hangman hangman = new Hangman();
}
JFrame frame = new JFrame();
JLabel winLabel;
JButton bNew;
JPanel south1;
JPanel south2;
JPanel south3;
JPanel south4;
JPanel south;
JLabel[] wordArray;
//JLabel[] abcArray;
Map<String, JLabel> abcMap;
Font font;
HangmanPanel hPanel;
boolean gameOver = false;
String gameWord;
private int tries = 0;
private int wrong = 0;
public Hangman() {
hPanel = new HangmanPanel();
hPanel.setPreferredSize(new Dimension(400, 350));
abcMap = new HashMap<String, JLabel>();
font = new Font("Comic Sans", Font.BOLD, 18);
winLabel = new JLabel("");
bNew = new JButton("New");
bNew.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
tries = 0;
wrong = 0;
gameOver = false;
hPanel.paintMan(0);
gameWord = getWord();
int length = gameWord.length();
wordArray = new JLabel[length];
abcMap = new HashMap<String, JLabel>();
south1 = new JPanel(new FlowLayout());
south3 = new JPanel(new FlowLayout());
createBoard(gameWord, length);
}
});
south1 = new JPanel(new FlowLayout());
south1.setForeground(Color.WHITE);
south1.setBackground(Color.WHITE);
south2 = new JPanel(new FlowLayout());
south2.setBackground(Color.WHITE);
south2.add(winLabel);
south3 = new JPanel(new FlowLayout());
south3.setBackground(Color.WHITE);
south4 = new JPanel(new FlowLayout());
south4.setBackground(Color.GRAY);
south4.add(bNew);
south = new JPanel(new GridLayout(4, 1));
south.add(south1);
south.add(south2);
south.add(south3);
south.add(south4);
frame.setLayout(new BorderLayout());
frame.setTitle("Hangman");
frame.setSize(new Dimension(400, 450));
frame.setLocationRelativeTo(null);
frame.add(hPanel, BorderLayout.CENTER);
frame.add(south, BorderLayout.SOUTH);
frame.setFocusable(true);
frame.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
String key = "" + e.getKeyChar();
if(gameOver == true) {
}
else if(abcMap.containsKey(key) && abcMap.get(key).getForeground() != Color.GREEN) {
checkKey(key);
south.revalidate();
}
else {
winLabel.setText("Invalid choice.");
}
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
});
frame.pack();
frame.setVisible(true);
gameWord = getWord();
int length = gameWord.length();
wordArray = new JLabel[length];
createBoard(gameWord, length);
}
private void checkKey(String key) {
int count = 0;
ArrayList<Integer> wordIndex = new ArrayList<Integer>();
wordIndex = search(key);
abcMap.get(key).setForeground(Color.GREEN);
if(wordIndex.size() > 0) {
winLabel.setText("Great job! " + key + " is one of the letters!");
}
else {
wrong++;
hPanel.paintMan(wrong);
winLabel.setText("Uh oh...");
}
while(count < wordIndex.size()) {
wordArray[wordIndex.get(count)].setForeground(Color.BLACK);
count++;
}
tries++;
if(tries - wrong == gameWord.length()) {
winLabel.setText("You won in " + tries + " tries!");
gameOver = true;
}
}
private ArrayList<Integer> search(String key) {
ArrayList<Integer> aList = new ArrayList<Integer>();
for(int i = 0; i < wordArray.length; i++) {
if(wordArray[i].getText().equals(key)) {
aList.add(i);
}
}
winLabel.setText("" + aList);
return aList;
}
private void createBoard(String gameWord, int length) {
winLabel.setText("Press letter on keypad to guess.");
winLabel.setFont(font);
for(int x = 0; x < length; x++) {
wordArray[x] = new JLabel("" + gameWord.charAt(x));
wordArray[x].setFont(font);
wordArray[x].setForeground(Color.WHITE);
}
for(int x = 0; x < 26; x++) {
abcMap.put("" + (char)(x + 97), new JLabel("" + (char)(x + 97)));
}
for(int x = 0; x < length; x++) {
south1.add(wordArray[x]);
}
for(int x = 0; x < 26; x++) {
abcMap.get("" + (char)(x + 97)).setFont(font);
south3.add(abcMap.get("" + (char)(x + 97)));
}
south.revalidate();
}
private String getWord() {
return JOptionPane.showInputDialog(frame, "Please enter word.");
}
}
Here's the code for the hangman panel:
Code:
import javax.swing.*;
import java.awt.*;
public class HangmanPanel extends JPanel {
private int count;
public void paintComponent(Graphics g) {
super.paintComponent(g);
setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D)g;
g2.setStroke(new BasicStroke(3));
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawLine(275, 40, 275, 275);
g2.drawLine(275, 275, 235, 315);
g2.drawLine(275, 275, 315, 315);
g2.drawLine(275, 40, 175, 40);
g2.drawLine(175, 40, 175, 80);
if(count >= 1) {
g2.fillOval(145, 80, 60, 60);
}
if (count >= 2) {
g2.drawLine(175, 100, 175, 240);
}
if (count >= 3) {
g2.drawLine(175, 190, 145, 160);
}
if (count >= 4) {
g2.drawLine(175, 190, 205, 160);
}
if (count >= 5) {
g2.drawLine(175, 240, 145, 270);
}
if (count >= 6) {
g2.drawLine(175, 240, 205, 270);
}
}
public void paintMan(int count) {
this.count = count;
repaint();
}
}
Also - if yall have any general tips on how I can improve my coding, that'd be greatly appreciated.