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.
I'm not sure if this is the right way to go about this or not:
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");
}
}
}
CodePudding user response:
You're looking for Canvas#repaint
to trigger a new paint cycle.
First, I'd isolate the keyboard input handling to the CopyOfGamePanel
class itself, so it can do the update automatically. 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.
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 ofBufferStrategy
it seems like a waste (and a source of possible issues) - You're not using a
JTextField
(or if you're hell bent on AWT,TextField
) to manage user input - You're not using
KeyListener
, no offence, but usingKeyboardFocusManager
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.
I think you might want to take a look at:
- Creating a GUI With Swing
- How to Use Text Fields
- How to Write a Key Listener
- Painting in AWT and Swing and Performing Custom Painting
If you're just starting out with this kind of stuff, it might even be better to look at JavaFX