我现在有一个计时器,在我的JPanel上,还有一个计数器,它显示计时器递减计数。这都是游戏的一部分-用户必须回答问题,因此当用户按下向上箭头时,他应该再有5秒的时间来回答问题。为此,我正在使用添加到JPanel的keyListener。但是我有一个非常奇怪的错误,除非同时按下TAB键和UP箭头,否则JPanel不会生成KeyEvent。如果我仅按UP箭头,则不会生成KeyEvent,并且时间限制不会增加。
我查找了多种资源,但与我的资源无关。我已经在应有的位置设置了requestFocusInWindow,但没有解决方案。顺便说一下,这是一个项目,所以不允许我使用KeyBindings。
游戏面板代码-
// import everything needed
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
// imports for anti-aliasing from Stack Overflow
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.Timer;
// This panel is the panel which has the game. It is mainly based off of graphics.
// It creates a clown which is juggling balls, and also the background is drawn
// and it is all animated. It also has a TextArea-which displays the question
// and a TextField- which is for the user to typeintheir answer
public class GamePanel extends JPanel implements ActionListener, KeyListener
{
protected TimerHandler th;
private boolean upPressed;
private CardPanel cp; // instance of CardPanel from the class 'StartPanel'
// to use to switch between cards
private CardLayout cards; // instance of cardLayout
private Timer timer; // Timer for animation
private int counter; // counter for animating arms
private Color colors[]; // array for holding different colors
private int colorCounter; // counter for animating balls
private Scanner questionReader; // scanner that reads from the easyequations.txt file
private Scanner answerReader; // scanner that reads from the easysolutions.txt file
private String questions[]; // array that contains all the questions
// from the easyequations.txt file
private String answers[]; // array that contains all answers from the
// easysolutions.txt file
private String ans; // string that will contain each answers every time the while
// loop is run and used to check if the user
// entered answer is the correct answer
private int random; // int variable that will be defined by Math.random(),
// so every time game is run, a random
// question from the text file is displayed in the
// question text area
private JTextArea questionArea; // the text area which will display a random question each time
private int score; // score counter- each time a question is answered correct
// the score increases
private Timer timeLimit; // timer that keep track of time user has left to
// answer question
protected double timeCounter; // a number that is printed to panel to print the time left
private boolean textEntered;// boolean to check if any sort of text is typed
// in the answer text field
private boolean timeAlmostUp;
private boolean oneWrong;
private boolean timeUp; // boolean to check if user entered answer before time limit
// was over
private int numWrong; // int that tracks how many times the user gets a question gets a question
// wrong.
private Color fourColors[]; // array for four balls
private Color threeColors[]; // array for three balls
private Color twoColors[]; // array for two balls
private int fourCounter;
private int threeCounter;
private int twoCounter;
// this panel is also the holder panel- it holds the question TextArea and
// the TextField which the answer is supposed to be typed into
public GamePanel(CardPanel cpIn, CardLayout cardsIn)
{
score = 0;
random = (int) (Math.random() * 25);
ans = new String(" ");
cards = cardsIn;
cp = cpIn;
answers = new String[25];
timeCounter = 10;
questions = new String[25];
QuestionTA qta = new QuestionTA(); // panel that creates the TextArea for
// user to type answer
qta.setBounds(300, 35, 400, 100);
add(qta);
AnswerTF atf = new AnswerTF(); // panel that creates the TextField
//for entering the answer
atf.setBounds(450, 150, 100, 30);
add(atf);
th = new TimerHandler();
th.setBounds(700, 200, 230, 200);
add(th);
timeLimit = new Timer(1000, th);
BackButtonPanel bbp = new BackButtonPanel(); // panel that creates a
// JButton to allow user
// to go back to home screen
bbp.setBounds(6, 0, 90, 50);
add(bbp);
setLayout(null); // this panel is a null layout
Color color = new Color(206, 228, 244);
setBackground(color);
timer = new Timer(225, this);
counter = 2;
colorCounter = 5;
numWrong = 0;
fourColors = new Color[4];
threeColors = new Color[3];
twoColors = new Color[2];
fourCounter = 4;
threeCounter = 3;
twoCounter = 2;
setFocusable(true);
requestFocus();
addKeyListener(this);
}
public void actionPerformed(ActionEvent evt)
{
timeLimit.setInitialDelay(1000);
timeCounter -= 0.225;
if(textEntered)
timeAlmostUp = false;
if (timeCounter <=5 && !textEntered)
timeAlmostUp = true;
if (timeCounter<=1)
{
timeCounter =0;
timeAlmostUp = false;
timeUp = true;
repaint();
}
if (numWrong > 0)
{
repaint();
}
repaint();
}
public void keyTyped(KeyEvent e)
{
System.out.println("up");
}
public void keyPressed(KeyEvent evt)
{
requestFocusInWindow();
int code = evt.getKeyCode();
System.out.println("up");
if(code == KeyEvent.VK_UP)
{
timeCounter+=7;
th.repaint();
}
}
public void keyReleased(KeyEvent e)
{
System.out.println("up");
}
包含JPanel的框架-
// Prasanth Dendukuri
// 4-23-19
// StartPanel.java
//import everything needed
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
//This class is the Main Menu, the first screen that the user will be taken
//to when he starts the game. Based on the button the user presses, he will
//be taken to the appropriate screen, ex: the 'how to play button' will take the
//user to the instructions screen, etc
// Creates the JFrame, which will hold the panel. The panel that is added to the
// JFrame is "CardPanel", which is the panel that creates all the cards of each panel
// for card layout.
public class StartPanel
{
public static void main(String[] args)
{
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Start");
frame.requestFocus();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(1000,700);
frame.setLocation(60,0);
frame.setResizable(true);
CardPanel cp = new CardPanel();
frame.getContentPane().add(cp);
frame.setVisible(true);
cp.requestFocus();
}
}
// this class creates all the cards for each panel created so far and
// adds it to card layout, so the user can navigate through our game.
class CardPanel extends JPanel
{
private CardLayout cards; // instance of card layout
private CardPanel cp; //instance of this panel so other classes can use them
// for card layout, which includes the nested classes
// in this file
private StartHolderPanel ghp; // instance of clas 'StartHolderPanel' which is to be used when creating
// a card for that class
private InstructionPanel instructCard;// instance of clas 'InstructionPanel'
//which is to be used when creating a card for that class
private GamePanel gameCard; // instance of clas 'GamePanel' which is to be used when
// creating a card for that class
private GamePanelMedium gameMediumCard;
private SelectDiff sp;// instance of class 'HolderPanel' which is to be used when creating
// a card for that class
// constructor - initialize all field variables and add cards to card layout
public CardPanel()
{
cards = new CardLayout();
setLayout(cards);
cp = this;
ghp = new StartHolderPanel(this, cards);
add(ghp,"home");
instructCard = new InstructionPanel(this, cards);
add(instructCard, "first");
gameCard = new GamePanel(this, cards);
gameCard.setFocusable(true);
gameCard.requestFocusInWindow();
add(gameCard, "second");
gameMediumCard = new GamePanelMedium(this, cards);
add(gameMediumCard, "medium");
sp = new SelectDiff(this, cards);
add(sp, "third");
}
// this class is the holder panel. It holds all the panels in the file
// and adds it to this class
class StartHolderPanel extends JPanel
{
public StartHolderPanel(CardPanel cp, CardLayout cards)
{
setLayout(new GridLayout(4,1,0,0));
TitlePanel tp = new TitlePanel();
add(tp);
PlayButtonPanel pbp = new PlayButtonPanel();
add(pbp);
HowToPlayPanel htpp = new HowToPlayPanel();
add(htpp);
HighScoresPanel hsp = new HighScoresPanel();
add(hsp);
}
}
// this class creates a JLabel which is the title of the Panel
class TitlePanel extends JPanel
{
public TitlePanel()
{
setBackground(new Color(254,195,195));
Font font = new Font("Serif", Font.BOLD, 50);
JLabel title = new JLabel("Equation Juggler!");
title.setFont(font);
add(title);
}
}
// this class creates a JButton called 'Play' and adds it to the panel. If the button is clicked
// the user is taken to the Game screen.
class PlayButtonPanel extends JPanel implements ActionListener
{
public PlayButtonPanel()
{
setBackground(new Color(254,195,195));
JButton play = new JButton("Play");
play.setOpaque(true);
play.setBackground(new Color(206,228,244));
play.setPreferredSize(new Dimension(300,200));
play.addActionListener(this);
add(play);
System.out.println("hi");
}
// this method checks if the 'play' JButton was pressed, and if it was, takes
// the user to the game panel, using card layout.
public void actionPerformed(ActionEvent evt)
{
if(evt.getActionCommand().equals("Play"))
{
cards.show(cp, "third");
}
}
}
// This class creates a JButton, 'How tp Play' and adds it to the panel.
class HowToPlayPanel extends JPanel implements ActionListener
{
public HowToPlayPanel()
{
setBackground(new Color(254,195,195));
JButton howToPlay = new JButton("How to Play");
howToPlay.setOpaque(true);
howToPlay.setBackground(new Color(206,228,244));
howToPlay.setPreferredSize(new Dimension(300,200));
howToPlay.addActionListener(this);
add(howToPlay);
}
// This method checks if the 'How to Play' Jbutton was pressed. If it was pressed, the
// user is taken to the Instructions Panel, using card layout.
public void actionPerformed(ActionEvent e)
{
if(e.getActionCommand().equals("How to Play"))
{
cards.show(cp, "first");
}
}
}
// This class creates the JButton, 'High Scores' and adds it to the panel.
// There is no High Scores JPanel yet.
class HighScoresPanel extends JPanel implements ActionListener
{
public HighScoresPanel()
{
setBackground(new Color(254,195,195));
JButton highScores = new JButton("High Scores");
highScores.setOpaque(true);
highScores.setBackground(new Color(206,228,244));
highScores.setPreferredSize(new Dimension(300,200));
add(highScores);
}
public void actionPerformed(ActionEvent e)
{
}
}
}
我必须在与向上箭头同时按下TAB键以实现所需的结果-这将timeCounter变量增加7,但是要立即发生,我必须同时按下TAB作为UP。我想我对为什么存在此错误有一个想法,但我不确定-所以我有一个在另一个面板中创建的JTextField,但是创建TextField的面板保存在此面板中-GamePanel-我要转到的面板给你看因此,每当我按下Tab键时,我都认为TextField的焦点从TextField移到面板上-然后,如果我在同时按下TAB和UPtimeCounter递增时,这就是我的想法。
我希望它正常工作,我只需要按UP箭头即可得到想要的结果。仅当我在其他任何键之前先按TAB键时,才会触发KeyPressed,这是一个奇怪的错误。随时问我更多代码,例如此面板所包含的框架。在此先感谢
编辑:我根据一个建议删除了paintComponent-但请让我显示paintComponent(),因为它与actionListener和booleans有关。