在JPanel对象或JFrame对象

时间:2016-03-07 02:45:45

标签: java swing jframe jpanel keylistener

所有

我最近对事件处理的工作原理感到困惑。对某人有好处可以给我一些提示,谢谢!

以下是我的理解,为了进行事件处理,有3个步骤: (1)实现监听器(Action,Key,...) (2)提供事件处理程序(actionperformed ...) (3)用源注册听众(这实际上是我困惑的一步)

我看到有人在JPanel对象上执行addKeyListener,而有人在JFrame对象上执行操作。就个人而言,我尝试了两种,有时事件可以处理,有时不能,依赖于哪个JPanel obj。或JFrame obj,我选择addkeylistener。

那么,在什么样的情况下我们可以确定应该使用JPanel还是JPanel,而任何其他对象都会遇到类似的问题?

谢谢!

以下是我尝试制作蛇游戏的练习代码。它还没有完成,但它有我描述的问题,调用addKeyListener将在JFrame上工作,但在JPanel上失败。

Snake.java

package com.snake;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Random;


public class Snake implements ActionListener, KeyListener {

    public static Snake snake;
    public Dimension dimension;
    public JFrame jFrame;
    public RenderPanel renderPanel;
    public ArrayList<Point> snakeParts = new ArrayList<>();
    public static final int UP = 0, DOWN = 1, LEFT = 2, RIGHT = 3, SCALE = 10;
    public int ticks = 0, direction = DOWN, score, tailLength;
    public Point head, cherry;
    public Random random;
    public boolean hitEdge, putNewCherry;
    public Timer timer;


    public Snake() {
        dimension = Toolkit.getDefaultToolkit().getScreenSize();
        jFrame = new JFrame("Snake");
        jFrame.setVisible(true);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setSize(500, 500);
        jFrame.setLocation((dimension.width - jFrame.getWidth()) / 2, (dimension.height - jFrame.getHeight()) / 2);
        jFrame.add(renderPanel = new RenderPanel());
        jFrame.addKeyListener(this);                                                    // Add Keylistener (1)
        jFrame.setFocusable(true);
        random = new Random();
        cherry = new Point(random.nextInt(jFrame.getWidth()) + 0, random.nextInt(jFrame.getHeight() + 0));
        head = new Point(0, 0);                     // head needs to be instantiated
        hitEdge = false;
        putNewCherry = true;
        timer = new Timer(20, this);
        timer.start();
    }

    // ---------------------------------------------------------------------------- Control the snake by pressing "I, J, K, L"
    @Override
    public void keyTyped(KeyEvent e) {
//        System.out.println("keyPressed="+KeyEvent.getKeyText(e.getKeyCode()));
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int i = e.getKeyCode();

        if (i == KeyEvent.VK_I && direction != DOWN) {
            direction = UP;
            System.out.println("UP");
        }
        if (i == KeyEvent.VK_K && direction != UP) {
            direction = DOWN;
            System.out.println("DOWN");
        }
        if (i == KeyEvent.VK_J && direction != RIGHT) {
            direction = LEFT;
            System.out.println("LEFT");
        }
        if (i == KeyEvent.VK_L && direction != LEFT) {
            direction = RIGHT;
            System.out.println("RIGHT");
        }
    }

    @Override
    public void keyReleased(KeyEvent e) {
    }


    // ---------------------------------------------------------------------------- Make the snake moving
    @Override
    public void actionPerformed(ActionEvent e) {
        renderPanel.repaint();
        ticks++;

        // ---------------------------------------------------------------------------- Determine the direction
        if (ticks % 10 == 0 && head != null && hitEdge != true) {
//            snakeParts.add(new Point(head.x, head.y));
            if (direction == UP) {
                if (head.y - 1 > 0) {
//                    head = new Point(head.x, head.y - 1);                         // Option (1)
                    snakeParts.add(new Point(head.x, head.y--));                    // OPtion (2), can be replaced by (1)
                } else {
                    hitEdge = true;
                }
            }
            if (direction == DOWN) {
                if (head.y + 1 < dimension.height / SCALE) {
//                    head = new Point(head.x, head.y + 1);                         // Option (1)
                    snakeParts.add(new Point(head.x, head.y++));                    // OPtion (2), can be replaced by (1)
                } else {
                    hitEdge = true;
                }
            }
            if (direction == LEFT) {
                if (head.x - 1 > 0) {
//                    head = new Point(head.x - 1, head.y);                         // Option (1)
                    snakeParts.add(new Point(head.x--, head.y));                    // OPtion (2), can be replaced by (1)
                } else {
                    hitEdge = true;
                }
            }
            if (direction == RIGHT) {
                if (head.x + 1 < dimension.width / SCALE) {
//                    head = new Point(head.x + 1, head.y);                         // Option (1)
                    snakeParts.add(new Point(head.x++, head.y));                    // OPtion (2), can be replaced by (1)
                } else {
                    hitEdge = true;
                }
            }

//            snakeParts.add(new Point(head.x, head.y));                            // Option (1)

            //  ---------------------------------------------------------------------------- Remove the tail part each time to maintain the whole body length as the same
            snakeParts.remove(0);

            // Each a cherry, gain longer length, get score
            if (cherry != null && head.equals(cherry)) {
                score += 100;
                tailLength++;
                // Reset the cherry's location == put a new cherry.
                cherry.setLocation(random.nextInt(jFrame.getWidth()) + 0, random.nextInt(jFrame.getHeight() + 0));
            }

            //  ----------------------------------------------------------------------------
        }


    }
}

RenderPanel.java

import javax.swing.*;
import java.awt.*;

public class RenderPanel extends JPanel {


//    public static int cherryX, cherryY;

//    // Instantiate the RenderPanel to register the Snake as KeyListerner
//    public RenderPanel(){
//        addKeyListener(Snake.snake);                                              // Add Keylistener (1) ???
//        setFocusable(true);
//        System.out.println("Call RenderPanel");
//    }
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        // Paint the background
        g.setColor(color.BLACK);
        g.fillRect(0, 0, 500, 500);

        // Pain the snake body
        Snake snake = Snake.snake;
        g.setColor(color.WHITE);        // Assign the new color to the snake's body
        for (Point snakePart : snake.snakeParts) {          // Loop to paint each part of the snake body
            g.fillRect(snakePart.x * snake.SCALE, snakePart.y * snake.SCALE, snake.SCALE, snake.SCALE);
        }
        g.fillRect(snake.head.x * snake.SCALE, snake.head.y * snake.SCALE, snake.SCALE, snake.SCALE);

        g.setColor(color.RED);
        g.fillRect(snake.cherry.x, snake.cherry.y, snake.SCALE, snake.SCALE);

    }
}

Main.java

public class Main {

    public static void main(String[] args) {
        Snake.snake = new Snake();
    }
}

0 个答案:

没有答案
相关问题