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

后端 未结 3 1099
囚心锁ツ
囚心锁ツ 2021-01-29 06:49

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 w

相关标签:
3条回答
  • 2021-01-29 06:56

    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.

    0 讨论(0)
  • 2021-01-29 06:58

    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 :-)

    0 讨论(0)
  • 2021-01-29 07:02

    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.

    enter image description here

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

    0 讨论(0)
提交回复
热议问题