-1

我正在尝试从 Hangman 程序中编写代码。我不确定这个想法是否正确。我正在考虑在文本字段中使用破折号(_ _ _ _ _),当用户按下按钮时必须动态更改。例如,如果用户在下面的代码中按下按钮“A”,则破折号应更改为( A _ _ _ _ )。那就是用户猜对了字母A。

我仍然对如何实现这一点感到困惑。附加 eventListeners 将是我的下一部分。但是现在,我必须让基本的 GUI 工作,为此我需要一个关于如何实现整个事情的想法。

让这个工作的更好方法是什么?这是我现在的代码。

import javax.swing.*;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridLayout;
import java.awt.event.*;
import java.awt.image.BufferedImage;

public class HangmanGUI {

public HangmanGUI() {
    JFrame myframe= new JFrame();
    myframe.getContentPane().setLayout(new BorderLayout());
    JPanel myPanel = new JPanel();
    myPanel.setLayout(new GridLayout(2,15));
    myframe.setSize(600,600);

    for (char alphabet = 'A';alphabet<='Z';alphabet++){
        myPanel.add(new JButton(alphabet+""));
    }

    myframe.getContentPane().add(myPanel, BorderLayout.SOUTH);
    myframe.setTitle("Hangman Game");
    myframe.setVisible(true);
    myframe.setLocationRelativeTo(null);
    myframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

public static void main(String[] args){
    new HangmanGUI();
}
}
4

3 回答 3

4

您可以使用DocumentFilter允许您实时过滤来自用户的传入结果的 API。

这个例子有点棘手,因为它隐藏了插入符号,以便它允许文本以您想要的任何顺序出现。

例如,该示例Duck用作机密(算法不区分大小写)。如果用户键入c,则该字段将显示为__c_。当然,您可以简单地将传入的角色插入到下一个位置,但其中的乐趣在哪里。

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.Point;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeListener;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultCaret;
import javax.swing.text.DocumentFilter;
import javax.swing.text.JTextComponent;

public class HangManField {

    public static void main(String[] args) {
        new HangManField();
    }

    public HangManField() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private String secret = "Duck";
        private String guesses = secret;

        public TestPane() {

            setLayout(new GridBagLayout());

            Caret blank = new DefaultCaret() {

                @Override
                public void paint(Graphics g) {
                }

                @Override
                public boolean isVisible() {
                    return false;
                }

                @Override
                public boolean isSelectionVisible() {
                    return false;
                }

            };

            JTextField field = new JTextField("____");
            field.setCaretPosition(0);
            field.setCaret(blank);
            ((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {

                @Override
                public void insertString(DocumentFilter.FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException {

                    replace(fb, offset, offset, string, attr);

                }

                @Override
                public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                    System.out.println("rplace");
                    StringBuilder sb = new StringBuilder(guesses.toLowerCase());
                    for (int index = 0; index < text.length(); index++) {
                        String at = text.substring(index, index + 1).toLowerCase();
                        int subIndex = sb.indexOf(at);
                        if (subIndex > -1) {
                            super.replace(fb, subIndex, 1, at, attrs);
                            sb.delete(index, index);
                        }
                    }
                }

                @Override
                public void remove(DocumentFilter.FilterBypass fb, int offset, int length) throws BadLocationException {
                    StringBuilder sb = new StringBuilder(length);
                    while (sb.length() < length) {
                        sb.append("_");
                    }
                    replace(fb, offset, length, sb.toString(), null);
                }
            });

            add(field);
        }
    }

}

该算法不做的事情是当前支持多个重复字符,例如characters. 不过,完成这项工作并不需要太多时间;)

于 2013-10-15T23:48:20.297 回答
3

JFromattedTextFeild的,与MaskFormatter班级一起使用。MaskFormatter有一个setPlaceholderCharacter('_')功能可以帮助你。您可能还需要使用InputVerifier来验证用户输入的有效性。JFormattedTextFeild 的文档有示例来展示如何使用InputVerifier它。

于 2013-10-15T23:23:37.887 回答
1

我不推荐带有破折号的文本字段,但你可以这样做。试一试,看看它的外观,然后创造更好的东西 :-) 例如,您可以使用带有图像的面板或标签、风格化的按钮,或者只是每个带有一个字符的大标签。画出您希望游戏的样子,然后开始编码。这是代码之前的设计:-)

于 2013-10-15T23:23:55.213 回答