2

我在 JPanel 类中创建了一个 KeyAdapter 类,并尝试使用 System.out.println(String par1); 调试单击。

然而它似乎不起作用......

这是课程:

package net.ryanshah;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

public class Menu extends JPanel
{
private GameFrame gf;

private Image bg = new ImageIcon("res/bg.png").getImage();

public Menu(final GameFrame parent) {
    this.gf = parent;
    int width = parent.getWidth();
    int height = parent.getHeight();

    setFocusable(true);

    addKeyListener(new MenuOperator());

    setBackground(Color.black);

    setLayout(null);
}

protected void paintComponent(Graphics g) {
    super.paintComponent(g);

    Graphics2D g2d = (Graphics2D)g;
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

    int w = getWidth();
    int h = getHeight();
    g2d.drawImage(bg, 0, 0, null);
}

public class MenuOperator extends KeyAdapter {
    @Override
    public void keyPressed(KeyEvent event) {
        int keyCode = event.getKeyCode();
        if(keyCode == KeyEvent.VK_SPACE) {
            System.out.println("LOL");
        }
    }
}
}

有谁知道问题可能是什么?我已经在框架中设置了关键处理程序,并将框架设置为可聚焦..

提前致谢

〜瑞恩S。

4

2 回答 2

2

代码中不正确的事情(恕我直言):

  • 您在代码中访问图像的方式。考虑ImageIO,而不是使用 的构造函数ImageIcon,因为前者会通知您,以防出现问题。有关详细信息,请参阅加载图像图标异常以获取更多信息。
  • KeyListeners是 for AWTSwing另一方面使用KeyBindings
  • 之前,在任何设置背景上都JComponent喜欢先将所述的opaque属性设置JComponenttrue。因为,opaque属性通常取决于LookAndFeel使用。
  • 尽量避免使用 setLayout(null), 。请浏览绝对定位的第一段以获取更多信息:-)
  • ImageObserver评论中已经提到的使用。

@camickr的这篇博客Motion Using the KeyboardKeyListeners将再次增加您的知识,为什么不被认为是更好的选择以及为什么KeyBindings更适合这种需求:-)

请看一下这个例子:

import java.awt.*;
import java.awt.event.*;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.*;

public class TestMenu extends JPanel {

    private Image bg;

    public TestMenu() {
        try {
            bg = ImageIO.read(
                    new URL("http://i.imgur.com/Aoluk8n.gif"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        getInputMap().put(KeyStroke.getKeyStroke("SPACE"), "SPACE key");
        getActionMap().put("SPACE key", keyAction);
        setOpaque(true);
        setBackground(Color.black);
    }

    private Action keyAction = new AbstractAction() {
        @Override
        public void actionPerformed(ActionEvent ae) {
            System.out.println("LOL");
        }
    };

    /*
     * Make this a customary habbit to override
     * this method for the JPanel/JComponent,
     * when ever you extend any of the above classes
     */
    @Override
    public Dimension getPreferredSize() {
        return (new Dimension(200, 200));
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                            RenderingHints.VALUE_ANTIALIAS_ON);
        int w = getWidth();
        int h = getHeight();
        /*
         * Here the last part of the drawImage is the 
         * ImageObserver, here it is a good practise
         * to keep the instance of the JPanel on which
         * we drawing the image to be notified, till the
         * end, till the image loading is not complete
         */
        g2d.drawImage(bg, 0, 0, this);
    }

    private void displayGUI() {
        JFrame frame = new JFrame("Painting Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        frame.setContentPane(this);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                new TestMenu().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}
于 2013-08-30T17:10:13.730 回答
0

将您的面板设置为可聚焦是不够的——面板本身无法获得焦点——您必须请求将焦点放在某种事件上。例如,您可以将鼠标侦听器添加到面板并panel.requestFocusInWindow()在您单击它时调用。

当您添加它的组件具有焦点时,键侦听器才会起作用。

于 2013-08-30T16:29:51.673 回答