【问题标题】:Java: Adding a Key Listener to a JFrameJava:向 JFrame 添加键侦听器
【发布时间】:2014-11-05 06:46:30
【问题描述】:

我正在尝试使用 Java 进行图形编程,并且正在尝试一个小练习,我想让汽车在一个框架中来回移动。然后,如果我按向上或向下箭头键,我想让它走得更快或更慢。但是,我似乎无法正确添加关键侦听器。为了测试我的代码,我只是想在命令提示符下打印一条消息。任何帮助将不胜感激!

代码按原样编译和运行。我得到一辆车在框架中来回移动。唯一不起作用的是关键侦听器。

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

public class Racing extends JFrame
{
    public static class Car extends JComponent implements ActionListener
    {
        int x=0;
        int y=0;
        int delta = 10;
        Timer timer;
        int z = 300;

        public Car()
        {
            timer = new Timer(20,this);
            timer.start();

            addKeyListener(new KeyAdapter()
            {
                @Override
                public void keyPressed(KeyEvent e)
                {           
                    if(e.getKeyCode() == KeyEvent.VK_UP)
                        System.out.println("The up key was pressed!");
                }
            });
        }

        public void paint(Graphics g)
        {
            super.paintComponent(g);

            y = getHeight();
            z = getWidth();

            g.setColor(Color.BLUE);
            g.fillRect(0, 0, z, y);

            Polygon polygon = new Polygon();
            polygon.addPoint(x + 10, y - 20);
            polygon.addPoint(x + 20, y - 30);
            polygon.addPoint(x + 30, y - 30);
            polygon.addPoint(x + 40, y - 20);

            g.setColor(Color.BLACK);
            g.fillOval(x + 10, y - 11, 10, 10);
            g.fillOval(x + 30, y - 11, 10, 10);
            g.setColor(Color.GREEN);
            g.fillRect(x, y - 21, 50, 10);
            g.setColor(Color.RED);
            g.fillPolygon(polygon);
            g.setColor(Color.BLUE);
        }

    public void actionPerformed(ActionEvent e) {
        x += delta;
        if (x > z-40) {
            delta *= -1;
            x = (z-40);
        } else if (x < 0) {
            delta *= -1;
            x = 0;
        }

        repaint();
    }

    }

    public static void main(String[] args)
    {
       JFrame frame = new JFrame("Racing");
       frame.setPreferredSize(new Dimension(600,300));
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.pack();
       frame.add(new Car());
       frame.setVisible(true);
       frame.setFocusable(true);
    }
}

【问题讨论】:

    标签: java swing jframe keylistener


    【解决方案1】:

    简短的回答是不要,涉及的问题太多了。

    改为使用键绑定 API。更多详情请见How to Use Key Bindings

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Polygon;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import javax.swing.AbstractAction;
    import javax.swing.ActionMap;
    import javax.swing.InputMap;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.KeyStroke;
    import javax.swing.Timer;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Racing extends JFrame {
    
        public static class Car extends JComponent implements ActionListener {
    
            int x = 0;
            int y = 0;
            int delta = 10;
            Timer timer;
            int z = 300;
    
            public Car() {
                timer = new Timer(20, this);
                timer.start();
    
                InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
                im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "goingUp");
    
                ActionMap am = getActionMap();
                am.put("goingUp", new AbstractAction() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        System.out.println("The up key was pressed!");
                    }
                });
            }
    
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
    
                y = getHeight();
                z = getWidth();
    
                g.setColor(Color.BLUE);
                g.fillRect(0, 0, z, y);
    
                Polygon polygon = new Polygon();
                polygon.addPoint(x + 10, y - 20);
                polygon.addPoint(x + 20, y - 30);
                polygon.addPoint(x + 30, y - 30);
                polygon.addPoint(x + 40, y - 20);
    
                g.setColor(Color.BLACK);
                g.fillOval(x + 10, y - 11, 10, 10);
                g.fillOval(x + 30, y - 11, 10, 10);
                g.setColor(Color.GREEN);
                g.fillRect(x, y - 21, 50, 10);
                g.setColor(Color.RED);
                g.fillPolygon(polygon);
                g.setColor(Color.BLUE);
            }
    
            public void actionPerformed(ActionEvent e) {
                x += delta;
                if (x > z - 40) {
                    delta *= -1;
                    x = (z - 40);
                } else if (x < 0) {
                    delta *= -1;
                    x = 0;
                }
    
                repaint();
            }
    
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Racing");
                    frame.setPreferredSize(new Dimension(600, 300));
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.add(new Car());
                    frame.setVisible(true);
                    frame.setFocusable(true);
                }
            });
        }
    }
    

    另外,不要从paint 调用super.paintComponent,你基本上已经破坏了整个油漆链。相反,覆盖paintComponent 方法本身...

    【讨论】:

    • 谢谢!这就是我试图思考的方向。我买了一本 Java 编程书,里面有一些图形信息,但它在这个特定方面为我指明了不同的方向。打破油漆链有什么后果?
    • 你最终可能会得到奇怪的绘画文物或根本没有画过的东西
    猜你喜欢
    • 1970-01-01
    • 2017-04-06
    • 1970-01-01
    • 2011-11-19
    • 2014-01-30
    • 2011-12-18
    • 2010-11-26
    • 2014-02-08
    • 1970-01-01
    相关资源
    最近更新 更多