У меня проблема с JFrame и KeyListerner в игре Tetris.У меня есть два кадра - один с кнопкой пуска и второй с доской.Во втором кадре я хочу управлять фигурами с клавиатуры, но когда я нажимаю «Пуск», я не могу этого сделать.Когда я деактивирую первый кадр - все ок.Я знаю, что должен сосредоточиться на втором кадре, и я попытался сделать это, но безрезультатно.Может ли кто-нибудь помочь мне?Первый кадр:
package tetris;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Font;
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;
public class Tetris implements ActionListener {
public Tetris() {
initComponents();
}
Component contentPane;
JLabel statusbar = new JLabel(" 0");
JLabel name = new JLabel("Tetris");
JButton startbut = new JButton("Start");
JFrame window = new JFrame();
JPanel panelStart = new JPanel();
JPanel game = new JPanel();
int nameSize=24;
Font fontName = new Font("Dialog", Font.BOLD, nameSize);
BorderLayout borderLayout = new BorderLayout();
Board board = new Board(this);
public void initComponents() {
window.setBounds(500,200,200,400);
window.setTitle("Tetris");
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
window.add(panelStart);
window.add(game);
panelStart.setLayout (null);
panelStart.setVisible(true);
window.setContentPane(panelStart);
name.setSize(70,25);
name.setLocation(53,10);
name.setFont(fontName);
panelStart.add(name);
startbut.setSize(70,25);
startbut.setLocation(50,80);
panelStart.add(startbut);
startbut.addActionListener(this);
}
public void initGame() {
game.setLayout (borderLayout);
panelStart.setVisible(false);
window.remove(panelStart);
game.setVisible(true);
window.setContentPane(game);
game.setFocusable(true);
statusbar = new JLabel(" 0");
game.add(statusbar, BorderLayout.SOUTH);
game.add(board);
board.start();
}
public JLabel getStatusBar() {
return statusbar;
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource() == startbut)
{
initGame();
}
}
}
Код платы:
package tetris;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;
import tetris.Shape.Tetrominoes;
public class Board extends JPanel implements ActionListener {
final int BoardWidth = 10;
final int BoardHeight = 22;
Timer timer;
boolean isFallingFinished = false;
boolean isStarted = false;
boolean isPaused = false;
int numLinesRemoved = 0;
int curX = 0;
int curY = 0;
JLabel statusbar;
Shape curPiece;
Tetrominoes[] board;
public Board(Tetris parent) {
// setFocusable(true);
curPiece = new Shape();
timer = new Timer(400, this);
timer.start();
statusbar = parent.getStatusBar();
board = new Tetrominoes[BoardWidth * BoardHeight];
KeyListener keyListener = new TAdapter();
addKeyListener(keyListener);
repaint();
clearBoard();
}
public void actionPerformed(ActionEvent e) {
if (isFallingFinished) {
isFallingFinished = false;
newPiece();
} else {
oneLineDown();
}
}
int squareWidth() { return (int) getSize().getWidth() / BoardWidth; }
int squareHeight() { return (int) getSize().getHeight() / BoardHeight; }
Tetrominoes shapeAt(int x, int y) { return board[(y * BoardWidth) + x]; }
public void start()
{
if (isPaused)
return;
isStarted = true;
isFallingFinished = false;
numLinesRemoved = 0;
clearBoard();
newPiece();
timer.start();
}
private void pause()
{
if (!isStarted)
return;
isPaused = !isPaused;
if (isPaused) {
timer.stop();
statusbar.setText("paused");
} else {
timer.start();
statusbar.setText(String.valueOf(numLinesRemoved));
}
repaint();
}
public void paint(Graphics g)
{
super.paint(g);
Dimension size = getSize();
int boardTop = (int) size.getHeight() - BoardHeight * squareHeight();
for (int i = 0; i < BoardHeight; ++i) {
for (int j = 0; j < BoardWidth; ++j) {
Tetrominoes shape = shapeAt(j, BoardHeight - i - 1);
if (shape != Tetrominoes.NoShape)
drawSquare(g, 0 + j * squareWidth(),
boardTop + i * squareHeight(), shape);
}
}
if (curPiece.getShape() != Tetrominoes.NoShape) {
for (int i = 0; i < 4; ++i) {
int x = curX + curPiece.x(i);
int y = curY - curPiece.y(i);
drawSquare(g, 0 + x * squareWidth(),
boardTop + (BoardHeight - y - 1) * squareHeight(),
curPiece.getShape());
}
}
}
private void dropDown()
{
int newY = curY;
while (newY > 0) {
if (!tryMove(curPiece, curX, newY - 1))
break;
--newY;
}
pieceDropped();
}
private void oneLineDown()
{
if (!tryMove(curPiece, curX, curY - 1))
pieceDropped();
}
private void clearBoard()
{
for (int i = 0; i < BoardHeight * BoardWidth; ++i)
board[i] = Tetrominoes.NoShape;
}
private void pieceDropped()
{
for (int i = 0; i < 4; ++i) {
int x = curX + curPiece.x(i);
int y = curY - curPiece.y(i);
board[(y * BoardWidth) + x] = curPiece.getShape();
}
removeFullLines();
if (!isFallingFinished)
newPiece();
}
private void newPiece()
{
curPiece.setRandomShape();
curX = BoardWidth / 2 + 1;
curY = BoardHeight - 1 + curPiece.minY();
if (!tryMove(curPiece, curX, curY)) {
curPiece.setShape(Tetrominoes.NoShape);
timer.stop();
isStarted = false;
statusbar.setText("game over");
}
}
private boolean tryMove(Shape newPiece, int newX, int newY)
{
for (int i = 0; i < 4; ++i) {
int x = newX + newPiece.x(i);
int y = newY - newPiece.y(i);
if (x < 0 || x >= BoardWidth || y < 0 || y >= BoardHeight)
return false;
if (shapeAt(x, y) != Tetrominoes.NoShape)
return false;
}
curPiece = newPiece;
curX = newX;
curY = newY;
repaint();
return true;
}
private void removeFullLines()
{
int numFullLines = 0;
for (int i = BoardHeight - 1; i >= 0; --i) {
boolean lineIsFull = true;
for (int j = 0; j < BoardWidth; ++j) {
if (shapeAt(j, i) == Tetrominoes.NoShape) {
lineIsFull = false;
break;
}
}
if (lineIsFull) {
++numFullLines;
for (int k = i; k < BoardHeight - 1; ++k) {
for (int j = 0; j < BoardWidth; ++j)
board[(k * BoardWidth) + j] = shapeAt(j, k + 1);
}
}
}
if (numFullLines > 0) {
numLinesRemoved += numFullLines;
statusbar.setText(String.valueOf(numLinesRemoved));
isFallingFinished = true;
curPiece.setShape(Tetrominoes.NoShape);
repaint();
}
}
private void drawSquare(Graphics g, int x, int y, Tetrominoes shape)
{
Color colors[] = { new Color(0, 0, 0), new Color(204, 102, 102),
new Color(102, 204, 102), new Color(102, 102, 204),
new Color(204, 204, 102), new Color(204, 102, 204),
new Color(102, 204, 204), new Color(218, 170, 0)
};
Color color = colors[shape.ordinal()];
g.setColor(color);
g.fillRect(x + 1, y + 1, squareWidth() - 2, squareHeight() - 2);
g.setColor(color.brighter());
g.drawLine(x, y + squareHeight() - 1, x, y);
g.drawLine(x, y, x + squareWidth() - 1, y);
g.setColor(color.darker());
g.drawLine(x + 1, y + squareHeight() - 1,
x + squareWidth() - 1, y + squareHeight() - 1);
g.drawLine(x + squareWidth() - 1, y + squareHeight() - 1,
x + squareWidth() - 1, y + 1);
}
public boolean isFocusable() {
return true;
}
public class TAdapter implements KeyListener {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
if (!isStarted || curPiece.getShape() == Tetrominoes.NoShape) {
return;
}
int keycode = e.getKeyCode();
if (keycode == 'p' || keycode == 'P') {
pause();
return;
}
if (isPaused)
return;
switch (keycode) {
case KeyEvent.VK_LEFT:
tryMove(curPiece, curX - 1, curY);
break;
case KeyEvent.VK_RIGHT:
tryMove(curPiece, curX + 1, curY);
break;
case KeyEvent.VK_DOWN:
tryMove(curPiece.rotateRight(), curX, curY);
break;
case KeyEvent.VK_UP:
tryMove(curPiece.rotateLeft(), curX, curY);
break;
case KeyEvent.VK_SPACE:
dropDown();
break;
case 'd':
oneLineDown();
break;
case 'D':
oneLineDown();
break;
}
}
@Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}
}