简体   繁体   English

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

[英]How to constantly update a canvas with a string?

I'm attempting to make a simple game that displays the word that the user types as they type it.我正在尝试制作一个简单的游戏来显示用户在键入时键入的单词。 However, I'm unsure how I could recall or update the write() method in order to show the string currentWord as the user types it, each time a new character is added or deleted.但是,我不确定如何调用或更新write()方法以便在用户键入字符串时显示字符串currentWord ,每次添加或删除新字符时。

I'm not sure if this is the right way to go about this or not:我不确定这是否是 go 的正确方式:

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

You're looking for Canvas#repaint to trigger a new paint cycle.您正在寻找Canvas#repaint来触发新的绘制周期。

First, I'd isolate the keyboard input handling to the CopyOfGamePanel class itself, so it can do the update automatically.首先,我将键盘输入处理隔离到CopyOfGamePanel class 本身,以便它可以自动进行更新。 If you need input to go through some other workflow (for some strange reasons), then CopyOfGamePanel will need to be notified (probably via some kind of observer/listener callback) with the information it needs and repaint itself.如果您需要通过其他一些工作流程向 go 输入(出于某些奇怪的原因),则需要通知CopyOfGamePanel (可能通过某种观察者/侦听器回调)它需要的信息并重新绘制自身。

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

}

Questions pop up as to why:为什么会弹出问题:

  • You need to use Canvas for this, this is quite a "low level" component, so unless you're actually making use of BufferStrategy it seems like a waste (and a source of possible issues)您需要为此使用Canvas ,这是一个相当“低级”的组件,因此除非您实际使用BufferStrategy ,否则它似乎是一种浪费(并且可能是问题的根源)
  • You're not using a JTextField (or if you're hell bent on AWT, TextField ) to manage user input您没有使用JTextField (或者如果您热衷于 AWT,则使用TextField )来管理用户输入
  • You're not using KeyListener , no offence, but using KeyboardFocusManager like this is a lot like trying to crack a peanut with C4, sure, it'll probably work, but it's also likely to create a mess.你没有使用KeyListener ,没有冒犯,但像这样使用KeyboardFocusManager很像试图用 C4 敲花生,当然,它可能会起作用,但也可能会造成混乱。

I think you might want to take a look at:我想你可能想看看:

If you're just starting out with this kind of stuff, it might even be better to look at JavaFX如果你刚开始接触这类东西,看看 JavaFX 可能会更好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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