如何用字符串不断更新 canvas?

How to constantly update a canvas with a string?

我正在尝试制作一个简单的游戏来显示用户键入的单词。 但是,我不确定如何调用或更新 write() 方法以便在用户键入时显示字符串 currentWord,每次添加或删除一个新字符。

我不确定这样做是否正确:

import java.awt.*;

import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.JFrame;
import javax.swing.JButton;

import java.util.*;

public class CopyOfGamePanel extends Canvas {

    public static String currentWord = "BEGIN";

    public static void main(String[] args) {
        String[] acceptable = {
            "pressed A",
            "pressed B",
            "pressed C",
            "pressed D",
            "pressed E",
            "pressed F",
            "pressed G",
            "pressed H",
            "pressed I",
            "pressed J",
            "pressed K",
            "pressed L",
            "pressed M",
            "pressed N",
            "pressed O",
            "pressed P",
            "pressed Q",
            "pressed R",
            "pressed S",
            "pressed T",
            "pressed U",
            "pressed V",
            "pressed W",
            "pressed X",
            "pressed Y",
            "pressed Z"
        };

        JFrame frame = new JFrame();
        frame.setResizable(false);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setFocusable(true);

        Canvas canvas = new CopyOfGamePanel();
        canvas.setSize(500, 700);
        canvas.setBackground(Color.white);
        frame.getContentPane().add(canvas);

        frame.pack();
        frame.setVisible(true);

        java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new java.awt.KeyEventDispatcher() {
            public boolean dispatchKeyEvent(java.awt.event.KeyEvent event) {
                String key = javax.swing.KeyStroke.getKeyStrokeForEvent(event).toString();
                if (key.equals("pressed BACK_SPACE"))
                    deleteLetter();
                if (Arrays.asList(acceptable).contains(key)) {
                    addLetter(key);
                    frame.pack();
                }
                //System.out.println(key);
                return true;
            }
        });
    }
    public void paint(Graphics g) {
        backgroundGUI(g);
        write(g);
    }

    public void backgroundGUI(Graphics g) {

        g.drawLine(0, 300, 500, 300);

    }
    public void write(Graphics g) {

        g.drawString(currentWord, 50, 290);

    }


    public static void addLetter(String key) {
        char letter = key.charAt(8);

        currentWord = currentWord + letter;
        System.out.println("Current Word: " + currentWord);

    }
    public static void deleteLetter() {
        System.out.println("Delete a letter");
        if (currentWord.length() > 0) {
            currentWord = currentWord.substring(0, currentWord.length() - 1);
            System.out.println("Current Word: " + currentWord);
        } else {
            System.out.println("There are no more letters to delete");
        }
    }
}

您正在寻找 Canvas#repaint 来触发新的绘制周期。

首先,我会将键盘输入处理隔离到 CopyOfGamePanel class 本身,这样它就可以自动进行更新。如果您需要输入以通过其他一些工作流程(出于某些奇怪的原因),那么 CopyOfGamePanel 将需要被通知(可能通过某种 observer/listener 回调)它需要的信息并重新绘制自己。

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.util.Arrays;
import javax.swing.JFrame;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new CopyOfGamePanel());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class CopyOfGamePanel extends Canvas {

        public static String currentWord = "BEGIN";
        private String[] acceptable = {"pressed A", "pressed B", "pressed C", "pressed D", "pressed E", "pressed F", "pressed G",
            "pressed H", "pressed I", "pressed J", "pressed K", "pressed L", "pressed M", "pressed N", "pressed O",
            "pressed P", "pressed Q", "pressed R", "pressed S", "pressed T", "pressed U", "pressed V", "pressed W",
            "pressed X", "pressed Y", "pressed Z"};

        public CopyOfGamePanel() {
            setBackground(Color.WHITE);
            java.awt.KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(new java.awt.KeyEventDispatcher() {
                public boolean dispatchKeyEvent(java.awt.event.KeyEvent event) {
                    String key = javax.swing.KeyStroke.getKeyStrokeForEvent(event).toString();
                    if (key.equals("pressed BACK_SPACE")) {
                        deleteLetter();
                    }
                    if (Arrays.asList(acceptable).contains(key)) {
                        addLetter(key);
                    }
                    return true;
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(500, 700);
        }

        public void paint(Graphics g) {
            backgroundGUI(g);
            write(g);
        }

        public void backgroundGUI(Graphics g) {
            g.drawLine(0, 300, 500, 300);
        }

        public void write(Graphics g) {
            g.drawString(currentWord, 50, 290);
        }

        public void addLetter(String key) {
            char letter = key.charAt(8);

            currentWord = currentWord + letter;
            System.out.println("Current Word: " + currentWord);
            repaint();
        }

        public void deleteLetter() {
            System.out.println("Delete a letter");
            if (currentWord.length() > 0) {
                currentWord = currentWord.substring(0, currentWord.length() - 1);
                System.out.println("Current Word: " + currentWord);
            } else {
                System.out.println("There are no more letters to delete");
            }
            repaint();
        }
    }

}

关于原因的问题弹出:

  • 你需要为此使用 Canvas,这是一个相当“低级”的组件,所以除非你真的在使用 BufferStrategy,否则它似乎是一种浪费(也是一种来源可能的问题)
  • 您没有使用 JTextField(或者如果您热衷于 AWT,TextField)来管理用户输入
  • 您没有使用 KeyListener,没有冒犯,但像这样使用 KeyboardFocusManager 很像试图用 C4 敲花生,当然,它可能会起作用,但它也可能造成混乱。

我想你可能想看看:

如果您刚开始接触这类东西,那么看看 JavaFX 可能会更好