java - KeyListener 和 jframe 的问题

标签 java swing jframe keylistener

我在俄罗斯方 block 游戏中遇到了 JFrame 和 KeyListerner 的问题。我有两个框架 - 一个带有开始按钮,第二个带有 Board。在第二帧中,我想通过键盘控制形状,但是当我单击开始时,我不能那样做。当我停用第一帧时 - 一切正常。我知道我必须专注于第二帧,我尝试这样做,但没有效果。有人可以帮我吗? 第一帧:

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

        }
     }
}

最佳答案

你的代码太大了,我想深入挖掘,但你想做的是可能的。

无论哪种方式,我建议您移动到一个框架并可能使用 CardLayout 或另一个 GUI 项来隐藏和显示组件,因为让用户在游戏开始时更改屏幕是一个奇怪的 UI。将所有内容都放在一个框架中会更加用户友好。这可能会解决您当前的问题。

关于java - KeyListener 和 jframe 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6214521/

相关文章:

JAVA时间动画

java - Eclipse 或 Javac 错误; lambda 类型推断

java - JSON字符串中double为什么要转成int

java - 如何通过 Java 中的 Socket 编程将 post 数据(包含 2 个参数)发送到 https 服务器

java - 带有提供信息的列表的 JFrame

java - 是否可以在 JFrame 边框上添加菜单?

java - 如何让JFrame背景图片透明?

java - 如何从按下按钮时调用的方法获取返回值?

java - 如何让JPanel填满整个JFrame?

java - 如何每 2 秒更新 TextArea(Jframe) 中的变量?