Java Keylistener对JPanel无响应

时间:2018-12-07 23:34:52

标签: java

当我的JPanel与其他组件(例如JLabel,JButton等)一起位于JCanvas文件下时,我正在尝试在JPanel中实现keylistener。但是,敲击键后,keylistener没有响应。我添加了关键侦听器,并将JPanel设置为可聚焦。我应该怎么做才能解决这个问题? 代码如下所示:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener;  
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;

import javax.swing.JPanel; 
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
public class Main extends JFrame implements ActionListener{
private static final long serialVersionUID = 1L;
protected static final String FRAME_TITLE = "Coco's Drone";
protected static final int TIMER_DELAY=100;//ms
protected static final int FRAME_WIDTH=1000;
protected static final int FRAME_HEIGHT=650;
protected static final int CANVAS_WIDTH=1000;
protected static final int CANVAS_HEIGHT=450;
protected static final String IMAGE_TITLE= "Rocket.png"; //Change the image route
protected Graphics g = getGraphics();
protected static Boolean initial=true;
protected GraphicCanvas canvas;
protected JLabel instruction,instruction_text,score,title;
protected JButton start;
protected Timer timer;
protected Fuels fuel;
protected Live rocket;
static Random rand = new Random();
public static int[] height_1= {0,0,0,0,0,0,0,0,0,0};
public static int[] height_2= {0,0,0,0,0,0,0,0,0,0};
public static int x=20;
public static int y=0;
public static int scores=100;
public static int rotation=0;
public static int v=0;
static int lives=3;
public Main() {
    super();
    initGraphics();
    initTimer();
    //initHandlers();
}
protected void initGraphics() {
    setTitle(FRAME_TITLE);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLayout(new BorderLayout());
    JPanel panel=new JPanel();
    panel.setPreferredSize(new Dimension(1000, 200));
    add(panel,BorderLayout.NORTH);
    panel.setLayout(new BorderLayout());
    //West title panel
    JPanel panelW=new JPanel();
    panelW.setBackground(Color.gray);
    panelW.setPreferredSize(new Dimension(300, 150));
    panelW.setBorder( new EmptyBorder( 10, 10, 0, 0 ) );
    panelW.setLayout(new GridLayout(3,1));
    panel.add(panelW,BorderLayout.WEST);
    score=new JLabel("Score: 100    ");
    score.setFont(new Font("Serif", Font.ITALIC,20));
    panelW.add(score);
    rocket=new Live();
    panelW.add(rocket);
    fuel=new Fuels();
    panelW.add(fuel);
    //South title panel
    start=new JButton("START");
    start.setPreferredSize(new Dimension(40, 40));
    start.setBackground(Color.gray);
    start.setOpaque(true);
    start.setFont(new Font("Serif", Font.BOLD, 20));
    start.addActionListener(this);
    panel.add(start,BorderLayout.SOUTH);
    //East title panel
    instruction=new JLabel("<html>INSTRUCTION: Please use arrow keys to control the drone. You must land safely on the red block before funning out of fuel. Good luck!</html>");
    instruction.setOpaque(true);
    instruction.setBackground(Color.gray);
    instruction.setFont(new Font("Serif", Font.ITALIC, 20));
    instruction.setPreferredSize(new Dimension(300, 100));
    panel.add(instruction,BorderLayout.EAST);
    //Center title panel
    title=new JLabel("DRONE PILOT");
    title.setHorizontalAlignment(JLabel.CENTER);
    title.setForeground(Color.white);
    title.setOpaque(true);
    title.setBackground(Color.gray);
    panel.add(title,BorderLayout.CENTER);
    title.setFont(new Font("Serif", Font.BOLD, 50));
    title.setVerticalAlignment(JLabel.CENTER);
    title.setHorizontalAlignment(JLabel.CENTER);
    canvas=new GraphicCanvas();
    canvas.setPreferredSize(new Dimension(1000, 450));
    canvas.addKeyListener(new KeyHandler());
    canvas.setFocusable(true);
    canvas.requestFocusInWindow();
    add(canvas,BorderLayout.CENTER);
    pack();
}
protected void initTimer() {
    timer=new Timer(TIMER_DELAY, new TimerHandler());
}

protected void initHandlers() {
    canvas.addKeyListener(new KeyHandler());
}

@Override
public void actionPerformed(ActionEvent e) {
    timer.start();  
}

public static void initCharacters(Graphics g) {
    BufferedImage live=new BufferedImage(60, 60,BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d=(Graphics2D)g; // Create a Java2D version of g.
    try {
        live=ImageIO.read(new File(IMAGE_TITLE));

    }
    catch(IOException e) {
        System.out.println("no file.");
    }
    GraphicCanvas.boundary();
    int w = live.getWidth(), h = live.getHeight();
    double sin = Math.abs(Math.sin(Math.toRadians(rotation))), cos = Math.abs(Math.cos(Math.toRadians(rotation)));
    int neww = (int)Math.floor(w*cos+h*sin), newh = (int)Math.floor(h*cos+w*sin);
    //g2d.drawImage(live,x,y,60,60,this);
    g2d.rotate(Math.toRadians(rotation), w/2 , h/2 );
    g2d.translate((neww-w)/2, (newh-h)/2);
    g2d.drawImage(live,x,y,60,60,null);
}

protected static class GraphicCanvas extends JPanel{
    public void level(Graphics g) {
        int height_u,height_b;
        g.setColor(Color.gray);
        if(initial==true) {
            for(int i=0;i<10;i++) {
                height_1[i]=rand.nextInt(5)*20+50;
                height_2[i]=rand.nextInt(5)*20+50;
            }
            y=390-height_2[0];
        }
        for(int i=0;i<10;i++) {
            height_u=height_1[i];
            height_b=height_2[i];
            g.fillRect(i*100, 0, 100, height_u);
            if(i==9) {
                g.setColor(Color.red);
            }
            g.fillRect(i*100, 450-height_b, 100, height_b);
        }
    }
    public static void boundary() {
        for(int i=0;i<10;i++) {
            if((x>i*100-60)&&x<=((i+1)*100-60)) {
                if(y<height_1[i]) {
                    y+=1;
                    scores-=1;
                }//upper boundary
                if(y>(390-height_2[i])) {
                    y-=1;
                    scores-=1;
                }//lower boundary
            }
        }
    }
    @Override
    public boolean isFocusable() {
        return true;
    }
    @Override
    public void paintComponent(Graphics g) {
        level(g);
        if(initial==false) {
            initCharacters(g);
        }
    }
}
protected class KeyHandler implements KeyListener{
    @Override
    public void keyPressed(KeyEvent e) {
        System.out.println("check keypress");
        switch(e.getKeyCode()) {
        case KeyEvent.VK_RIGHT:
            turnRight();
            movement();
            break;
        case KeyEvent.VK_LEFT:
            turnLeft();
            movement();
            break;
        case KeyEvent.VK_UP:
            forward();
            movement();
            break;
        }
    }
    @Override
    public void keyReleased(KeyEvent e) {System.out.println("check keyrelease");}
    @Override
    public void keyTyped(KeyEvent e) {System.out.println("check keytype");}
    public void restart() {
        if(Fuel.x==0) {
            x=20;
            y=390-height_2[0];
            rotation=0;
            stop();
        }
    }
    public void turnRight() {
        rotation-=1;
    }
    public void turnLeft() {
        rotation+=1;
    }
    public void stop() {
        v=0;
    }
    public void forward() {
        v+=1;
    }
    public void movement() {
        x+=v*Math.cos(Math.toRadians(rotation));
        y-=v*Math.sin(Math.toRadians(rotation))-4.9*0.1;
    }
}
protected class TimerHandler implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
        canvas.repaint();
        fuel.repaint();
        rocket.repaint();
        initial=false;
        score.setText("Score: "+scores);
    }
}
protected class Fuels extends JComponent{
    int fuel_x;
    public void paintComponent(Graphics g) {
        if(fuel_x==0 && lives >0) {
            lives-=1;
            fuel_x=300;
        }
        fuel_x-=1;
        g.setColor(Color.red);
        g.fillRect(0,10,fuel_x,30);
    }
}
protected class Live extends JComponent{
    BufferedImage live=new BufferedImage(40, 40,BufferedImage.TYPE_INT_ARGB);;
    public Live() {
        try {
            live=ImageIO.read(new File(IMAGE_TITLE));

        }
        catch(IOException e) {
            System.out.println("no file.");
        }
    }
    public void paintComponent(Graphics g) {
        if(lives==2) {
            g.drawImage(live,0,0,40,40,this);
            g.drawImage(live,50,0,40,40,this);
        }
        else if(lives==1) {
            g.drawImage(live,0,0,40,40,this);
        }
        else if(lives<=0){

        }
        else {
            g.drawImage(live,0,0,40,40,this);
            g.drawImage(live,50,0,40,40,this);
            g.drawImage(live,100,0,40,40,this);
        }
    }
}
public static void main(String[] args) {
    Main gui = new Main();
    gui.setVisible(true);   
}

0 个答案:

没有答案