java - Hangman GUI 小程序 java

标签 java swing jbutton japplet

这里有大麻烦。

  1. errorLabel 无法显示 errorCounter,而是显示 javax.swing.JLabel[.670...
  2. 点击新游戏,键盘会重置,但wordLabel不会重置(为游戏添加新单词),如何删除旧的wordLabel并替换为新的?

这是我的代码:

import java.net.*;
import java.io.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.applet.Applet;
import java.util.*;

public class Hangman extends JApplet implements ActionListener
{
private    static final long serialVersionUID = 2005L;
private    Container    window;
private    JButton      restart;
private    JLabel       errorLabel;
private    WordList     aWordList;
private    int          errorsCounter;
private    JLabel[]     letterLabel;
private    ArrayList<JButton>    letterButton;
private    JPanel       keyboard;
private    JPanel       wordPanel;
private    int          noWordsCorrect;
private    boolean      gameOver;

public void init()
{
    window = new DoubleBufferedPanel();
    setContentPane(window);
    readWordList("words.txt");
    createAppearance();
    createGUI();
    //createAlphabets();
    // JOptionPane.showMessageDialog(this, "" + aWordList.size());
}

public void createAppearance(){
    window.setLayout(null);
}

public void createGUI()
{
    errorsCounter = 6;
    gameOver = false;
    window.removeAll();
    createAlphabets();
    findWord();
    restart = new JButton("New Game");
    restart.setLocation(50, 50);
    restart.setSize(100, 50);
    restart.addActionListener(this);
    window.add(restart);

    errorLabel = new JLabel("6 errors to go");
    errorLabel.setSize(150, 50);
    errorLabel.setLocation(670, 70);
    window.add(errorLabel);
    //testLabel = new JLabel("word");
    //testLabel.setSize(400, 30);
    //testLabel.setLocation(50, 120);
    //window.add(testLabel);

    //createAlphabets();
    //findWord();
}

public void readWordList(String fileName){
    try {
        aWordList = new WordList(new URL(getCodeBase(), fileName), 7, 13);
    }
    catch (Exception ex) {
        JOptionPane.showMessageDialog(this, ex.toString());
    }
}

public void reset(){
    for(JButton b : letterButton){
        b.setVisible(true);
    }

    if(letterLabel != null)
    {
        for(JLabel lbl : letterLabel)
        {
            wordPanel.remove(lbl);
        }
        wordPanel.invalidate();//signal java got to fix n redo layout 
        wordPanel.validate();
    }

}

public void actionPerformed(ActionEvent e){

    if(e.getSource() == restart)
    {
        reset();
        String t = aWordList.getRandomWord();
        wordPanel.setLayout(new GridLayout(1, t.length()));
        JOptionPane.showMessageDialog(null, t);
        letterLabel = new JLabel[t.length()];

        for(int i = 0; i <= t.length(); i++)
        {
            letterLabel[i] = new JLabel(t.substring(i , i + 1));
            letterLabel[i].setVisible(false);
            wordPanel.add(letterLabel[i]);
        }

    }
    else if(e.getSource() instanceof JButton)
    {
        JButton letter = (JButton) e.getSource();
        for(int i = 0; i <= letterLabel.length; i++)
        {
            if((letterLabel[i].getText()).equals(letter.getText()))
            {
                letterLabel[i].setVisible(true);
                letter.setVisible(false);
                noWordsCorrect++;
            }
            else
            {

                letter.setVisible(false);
                errorsCounter--;
                errorLabel.setText("" + errorsCounter + " error to go");
            }

        }

    }
    else if(noWordsCorrect >= letterLabel.length)
    {
        JOptionPane.showMessageDialog(null, "Congratz you win!");
        //createGUI();
        gameOver = true;
    }

    else if(errorsCounter == 0)
    {
        JOptionPane.showMessageDialog(null, "OMG you lost!");
        gameOver = true;
    }
    repaint();
}

public void createAlphabets(){
    keyboard = new JPanel(new GridLayout(2,13));
    keyboard.setSize(750,150);
    keyboard.setBorder(BorderFactory.createLineBorder (Color.blue, 2));
    keyboard.setLocation(200,200);

    letterButton = new ArrayList<JButton>();
    for(char c = 'a'; c <= 'z'; c++)
    {
        JButton s = new JButton("" + c);
        s.addActionListener(this);
        keyboard.add(s);
        letterButton.add(s);
    }

    window.add(keyboard);
    //setVisible(true);
}

public void findWord(){
    wordPanel = new JPanel(new GridLayout(1, 13));
    wordPanel.setSize(250,150);
    wordPanel.setBorder(BorderFactory.createLineBorder (Color.red, 2));
    wordPanel.setLocation(200,50);
    window.add(wordPanel);
}
// JOptionPane.showMessageDialog(this, "[" + t + "]");
//testLabel.setText(t);

class DoubleBufferedPanel extends JPanel {
    private static final long    serialVersionUID = 44L;

    public void paint(Graphics g){
        super.paint(g);
    }
}

}

最佳答案

有很多问题,但您遇到的主要问题似乎与 for 循环有关......

这个...

for (int i = 0; i <= t.length(); i++) {

还有这个...

for (int i = 0; i <= letterLabel.length; i++) {

都会中断并抛出 ArrayIndexOutOfBoundsException 异常。

记住,Java 中的所有数组都是从 0 开始的。也就是说,长度为 5 的数组的元素位于 0-4

您的 reset 方法应该是自包含的,并且能够重建 letterLabel 数组。还应该从 init 方法调用此方法以使游戏启动并运行。

你的“猜测检查”算法是错误的......

for (int i = 0; i < letterLabel.length; i++) {
    if ((letterLabel[i].getText()).equals(letter.getText())) {
        letterLabel[i].setVisible(true);
        letter.setVisible(false);
        noWordsCorrect++;
    } else {
        letter.setVisible(false);
        errorsCounter--;
        System.out.println("errorsCounter = " + errorsCounter);
        errorLabel.setText("" + errorsCounter + " error to go");
    }
}

这基本上会减少原始文本中每个字符的猜测次数。因此,如果原始文本是“testin”并且我选择a,我将不再有任何猜测。只有在原文中根本找不到匹配项时才应减少猜测......

关于java - Hangman GUI 小程序 java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16658211/

相关文章:

java - 我的图像文件必须位于哪里才能使以下代码正常工作?

java - OnclickListener 尝试将多个变量保存到常量文件时崩溃

java - 如何在 Redis 中对复杂对象进行建模

java - Hibernate criteria , rowcount() 仅适用于firstResult = 0

java - JList 的 ListCellRenderer 未打印 DefaultListModel 的正确索引

java - 即使编写代码后,JLabel 也不会变得不透明?

java - 为什么这些图像不显示?

java - 对一组 jButton 实现 ActionListener 时出现问题

java - 缺少目标 JNDI 名称

java - 如何让右侧JPanel始终显示