问题
Below is a code from "Simon" in which I have running showing the correct segments that are supposed to be shown but I am have trouble with my keyPress and it will not light up using the arrow keys when I use it. Not really a great coder and I really need some help with this.
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Arc2D;
import javax.swing.Timer;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Simon extends JFrame implements KeyListener {
// public DrawStuff game;
public static Simon simon;
Graphics2D g2;
Graphics2D g3;
Graphics2D g4;
Graphics2D g5;
public JFrame frame = new JFrame();
public JPanel panel = new JPanel();
private ActionListener timerAction;
public Simon() {
frame = new JFrame();
panel = new JPanel();
// Sets up JFrame
frame.setTitle("Simon Says");
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawStuff game = new DrawStuff();
panel.setLayout(new BorderLayout());
panel.add(game, BorderLayout.CENTER);
frame.add(panel);
frame.addKeyListener(this);
// game.setFocusable(true);
// game.requestFocus();
frame.setVisible(true);
}
public class DrawStuff extends JPanel {
public void paint(Graphics g) {
g2 = (Graphics2D) g;
g3 = (Graphics2D) g;
g4 = (Graphics2D) g;
g5 = (Graphics2D) g;
// assume d == 145 && e == 90
g2.setPaint(Color.BLUE.darker());
g2.fill(new Arc2D.Double(45, 45, 400, 400, 145, 90, Arc2D.PIE));
g3.setPaint(Color.RED.darker());
g3.fill(new Arc2D.Double(45, 45, 400, 400, 235, 90, Arc2D.PIE));
g4.setPaint(Color.GREEN.darker());
g4.fill(new Arc2D.Double(45, 45, 400, 400, 325, 90, Arc2D.PIE));
g5.setPaint(Color.YELLOW.darker());
g5.fill(new Arc2D.Double(45, 45, 400, 400, 55, 90, Arc2D.PIE));
}
}
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) {
g5.setPaint(Color.YELLOW);
//Color YELLOW = Color.WHITE;
}
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
g2.setPaint(Color.BLUE.darker());
//Color BLUE = Color.WHITE;
}
if (e.getKeyCode() == KeyEvent.VK_DOWN) {
g3.setPaint(Color.RED.darker());
//Color RED = Color.WHITE;
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
g4.setPaint(Color.GREEN.darker());
//Color GREEN = Color.WHITE;
}
panel.repaint();
}
public void keyReleased(KeyEvent e) {
/**
* if (e.getKeyCode() == KeyEvent.VK_UP) { Color YELLOW = Color.YELLOW;
* repaint(); }
*
* if (e.getKeyCode() == KeyEvent.VK_LEFT) { Color BLUE = Color.BLUE;
* repaint(); }
*
* if (e.getKeyCode() == KeyEvent.VK_DOWN) { Color RED = Color.RED;
* repaint(); }
*
* if (e.getKeyCode() == KeyEvent.VK_RIGHT) { Color GREEN = Color.GREEN;
* repaint(); }
**/
}
@Override
public void keyTyped(KeyEvent e) {
}
// TODO Auto-generated method sub
public static void main(String[] args) {
simon = new Simon();
}
}
回答1:
You're doing a bit of guessing here, and that's not going to work. Instead, I recommend that you:
- First and foremost, use Key Bindings, not a KeyListener as Key Bindings allow you to get around the KeyListener focus issue without using a kludge. You can find the Key Binding tutorial here: Key Binding Tutorial.
- Next, never try to extract a Graphics object from a painting method and use it outside of the painting method, unless within a method that is directly called by the painting method. That Graphics object that you've extracted and are trying to use within your MouseListener are not long-lived objects, and might even be null when you try to use them.
- Instead, change the state of your class's variables within your MouseListener and then use the state of those variables within your painting method to tell it what to paint. Look at the Performing Custom Painting Tutorial for more on how to draw with Swing.
- Make sure that when a proper key is pressed that you draw that one pie slice darker, and all the other pie slices normal.
Other issues:
- your class extends JFrame and yet you create another JFrame. Don't do this, either have and use one JFrame or the other, but don't have both as that will only confuse you later.
- Your drawing JPanel should have its
paintComponent
method overridden not itspaint
method. - You need to call the super's painting method within your override. So if you're overriding paintComponent like I have suggested, call
super.paintComponent(g);
on the first line of your override, as this will allow the JPanel to do its house-keeping painting, including erasing old dirty images.
For an example of just what I'm talking about, please see this answer of mine to a similar question. This will create this GUI:
来源:https://stackoverflow.com/questions/33027235/how-to-make-keypress-work-with-keylistener