【问题标题】:ActionPerformed not working in custom componentActionPerformed 在自定义组件中不起作用
【发布时间】:2016-05-23 19:48:13
【问题描述】:

我正在尝试编写一个代码来创建一个我称之为 gun 的东西,我希望能够将它向右或向左移动。我实现了KeyListenerActionListener 方法,但actionPerformed 不起作用。但是,keyPressed 方法确实有效。有什么我错过的想法吗?

public class Gun extends JPanel implements KeyListener, ActionListener {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private static final int GUN_WIDTH = 100;
    private static final int GUN_HEIGHT = 30;
    private static final int GUN_UPPER_HEIGHT = 20;
    private static final int GUN_UPPER_WIDTH = GUN_WIDTH / 4;
    int x, y;
    int velX;

    public Gun() {
        x = 250 - GUN_WIDTH / 2;
        y = 500 - GUN_HEIGHT;
        velX = 0;
        addKeyListener(this);
        setFocusable(true);
        setFocusTraversalKeysEnabled(false);
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;

        int upperX = x + GUN_WIDTH / 2 - GUN_UPPER_WIDTH / 2;
        int upperY = y - GUN_UPPER_HEIGHT;

        g2d.setColor(Color.BLACK);
        g2d.fillRect(x, y, GUN_WIDTH, GUN_HEIGHT);
        g2d.fillRect(upperX, upperY, GUN_UPPER_WIDTH, GUN_UPPER_HEIGHT);
    }

    public void left() {
        velX = -1;
    }

    public void right() {
        velX = 1;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        int key = e.getKeyCode();
        if (key == KeyEvent.VK_LEFT) {
            left();
            System.out.println("LEFT");
        }
        if (key == KeyEvent.VK_RIGHT) {
            right();
            System.out.println("RIGHT");
        }
    }

    @Override
    public void keyReleased(KeyEvent arg0) {
    }

    @Override
    public void keyTyped(KeyEvent arg0) {
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        x += velX;
        repaint();
    }

    public static void main(String[] args) {
        Gun gun = new Gun();
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setTitle("Game");
        frame.setLayout(new FlowLayout());

        gun.setPreferredSize(new Dimension(500, 500));

        frame.add(gun);
        frame.setVisible(true);
        frame.pack();
    }

}

【问题讨论】:

  • 我看到你使用了addKeyListener(this),但你在某处对addActionListener 也这样做了吗?
  • 考虑使用Key Bindings 而不是KeyListener
  • @Zircon 我知道这是有问题的。然而,这里又出现了另一个问题。当我尝试将 'addActionListener(this)' 放入构造函数时,我不能,因为 Eclipse 不允许我这样做,它的行为就像这个方法甚至不存在一样。任何想法为什么?

标签: java swing actionlistener


【解决方案1】:

要让 actionPerformed 方法运行,您需要为该对象添加一个 ActionListener。由于您没有添加 actionListener,因此您永远不会运行 actionPerformed 方法。

查看有关动作侦听器的 Java 教程:https://docs.oracle.com/javase/tutorial/uiswing/events/actionlistener.html

【讨论】:

    【解决方案2】:

    要运行actionPerformed方法,需要在对应的对象中添加ActionListener。但是 JPanel 类没有名为 addActionListener 的方法。

    查看您的代码,您似乎不需要实现 ActionListener 接口。然后你可以摆脱 actionPerformed 方法。您所要做的就是复制 actionPerformed 方法中的代码并将它们粘贴到 keyPressed 方法的 if 条件中。以下是按预期工作的代码:

    package edu.uno.ai.planning.bfs;
    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.KeyEvent;
    import java.awt.event.KeyListener;
    
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class Gun extends JPanel implements KeyListener{
    
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private static final int GUN_WIDTH = 100;
        private static final int GUN_HEIGHT = 30;
        private static final int GUN_UPPER_HEIGHT = 20;
        private static final int GUN_UPPER_WIDTH = GUN_WIDTH / 4;
        int x, y;
        int velX;
    
        public Gun() {
            x = 250 - GUN_WIDTH / 2;
            y = 500 - GUN_HEIGHT;
            velX = 0;
            addKeyListener(this);
    
            setFocusable(true);
            setFocusTraversalKeysEnabled(false);
        }
    
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
    
            int upperX = x + GUN_WIDTH / 2 - GUN_UPPER_WIDTH / 2;
            int upperY = y - GUN_UPPER_HEIGHT;
    
            g2d.setColor(Color.BLACK);
            g2d.fillRect(x, y, GUN_WIDTH, GUN_HEIGHT);
            g2d.fillRect(upperX, upperY, GUN_UPPER_WIDTH, GUN_UPPER_HEIGHT);
        }
    
        public void left() {
            velX = -1;
        }
    
        public void right() {
            velX = 1;
        }
    
        @Override
        public void keyPressed(KeyEvent e) {
            // TODO Auto-generated method stub
            int key = e.getKeyCode();
            if (key == KeyEvent.VK_LEFT) {
                left();
                System.out.println("LEFT");
                x += velX;
                repaint();
            }
            if (key == KeyEvent.VK_RIGHT) {
                right();
                System.out.println("RIGHT");
                x += velX;
                repaint();
            }
        }
    
        @Override
        public void keyReleased(KeyEvent arg0) {
        }
    
        @Override
        public void keyTyped(KeyEvent arg0) {
        }
    
        public static void main(String[] args) {
            Gun gun = new Gun();
            JFrame frame = new JFrame();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setTitle("Game");
            frame.setLayout(new FlowLayout());
    
            gun.setPreferredSize(new Dimension(500, 500));
    
            frame.add(gun);
            frame.setVisible(true);
            frame.pack();
        }
    
    }
    

    【讨论】:

    • 刚刚做到了!但是多次使用同一段代码不是一个坏习惯吗?
    • 如果重复的代码是多行或必须多次使用,那么声明方法并调用该方法当然是个好主意。但在你的情况下,重复的代码是两行,只能在两个地方使用。因此,我只是将这些行复制到各个地方。但是您总是可以声明一个单独的方法并在需要时调用该方法。编程是科学与艺术的结合。是否声明方法,属于美术部分,有些主观。因此,用你最好的直觉来决定是使用方法还是复制代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多