简体   繁体   中英

How to get textfield that updates from listener in Java Swing for Hangman game?

I am trying to write a code from Hangman program. I am not sure if this idea is correct. I was thinking of having dashes (_ _ _ _ _) in textfield which must dynamically change when user presses buttons. for example, if the user presses button "A" in the below code, the the dashes should change to ( A _ _ _ _ ). That is the user has guessed the letter A correct.

I am still confused as how to implement this. Attaching eventListeners would be my next part. But for now, I have to get the basic GUI working, for which I need to an idea as how to implement entire thing.

what is the better way to get this working? here is my code as of now.

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();
}
}

You could make use of the DocumentFilter API which would allow you to filter the incoming results from the user in real time.

This example is a little tricky, in that it hides the caret, so that it will allow the text to appear in any order you want.

For example, the example uses Duck as the secret (the algorithm is case insensitive). If the user types c then the field will appear as __c_ . Of course, you could just simply insert the incoming character in the what ever position was next, but where's the fun in that.

在此处输入图片说明

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);
        }
    }

}

Something this algorithm doesn't do, is currently support multiple, recurring characters, like characters . It wouldn't take a lot for you to make this work though ;)

Yes use JFromattedTextFeild with a MaskFormatter class. MaskFormatter has a setPlaceholderCharacter('_') function to help you with. You may also need to use the InputVerifier to verify user input's validity. JFormattedTextFeild's documentation has example to show how to use an InputVerifier with it.

I wouldn't recommend text field with dashes, but you can do it like that. Give it a try, see how it looks and then create something better :-) You can, for example, use panels or labels with images, stylized buttons, or just large labels with a character each. Draw a picture of what you would like your game to look like, and then start coding. It's design before code :-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM