为什么keylistener停止工作?

时间:2011-09-25 04:18:35

标签: java swing key-bindings keylistener

在我的Java程序中,每当我从JTextField中选择一些文本时,keyListener就会停止检测按键。我注意到按下JButton时会发生同样的事情。使用后我是否需要从对象中删除keyListener?如果是这样,我该怎么做?

以下是我遇到问题的程序的副本:

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

public class ColourDropper extends JPanel implements KeyListener, ActionListener {

    private Color background = Color.WHITE;
    private int mouseX, mouseY;
    private Timer t;
    private JTextField rgb, hsb, hex, alp;
    private JLabel tRgb, tHsb, tHex, tHold, tAlp;
    private String hexString;
    private boolean hold = false;

    public ColourDropper() {
        this.setFocusable(true);
        t = new Timer(100, this);
        t.start();
        rgb = new JTextField(7);
        hsb = new JTextField(9);
        hex = new JTextField(6);
        alp = new JTextField(3);
        tRgb = new JLabel("RGB");
        tHsb = new JLabel("HSB");
        tHex = new JLabel("Hex");
        tAlp = new JLabel("Alpha");

        rgb.setEditable(false);
        hsb.setEditable(false);
        hex.setEditable(false);
        alp.setEditable(false);

        add(tRgb);
        add(rgb);
        add(tHex);
        add(hex);
        add(tHsb);
        add(hsb);
        add(tAlp);
        add(alp);
        addKeyListener(this);
    }

    public void actionPerformed(ActionEvent e) {
        if(!hold) {
            mouseX = MouseInfo.getPointerInfo().getLocation().x;
            mouseY = MouseInfo.getPointerInfo().getLocation().y;

            try {   
                Robot robot = new Robot();
                background = robot.getPixelColor(mouseX, mouseY);
                hexString = "#" + Integer.toHexString(background.getRGB()).toUpperCase().substring(2);
            } catch(AWTException a) {
                System.out.println(a.getMessage());
            } catch(Exception x) {
                System.out.println(x.getMessage());
            }

            try {
                rgb.setText(background.getRed() + " " + background.getGreen() + " " + background.getBlue());
                float[] cHsb = Color.RGBtoHSB(background.getRed(), background.getGreen(), background.getBlue(), null);
                int hue = (int)(cHsb[0] * 360);
                int sat = (int)(cHsb[1] * 100);
                int bri = (int)(cHsb[2] * 100);
                hsb.setText(hue + "� " + sat + "% " + bri + "%");
                hex.setText(hexString);
                alp.setText("" + background.getAlpha());
            } catch(NullPointerException n) {
                System.out.println(n.getMessage());
            }

            repaint();
        }
    }

    public void keyPressed(KeyEvent e) {        
        if(e.getKeyCode() == KeyEvent.VK_SPACE) hold = !hold;
        if(hold) {
            rgb.setForeground(Color.RED);
            hex.setForeground(Color.RED);
            hsb.setForeground(Color.RED);
            alp.setForeground(Color.RED);
        } else {
            rgb.setForeground(Color.BLACK);
            hex.setForeground(Color.BLACK);
            hsb.setForeground(Color.BLACK);
            alp.setForeground(Color.BLACK);
        }
    }

    public void paintComponent(Graphics g) {
        g.setColor(new Color(238, 238, 238));
        g.fillRect(0, 0, 246, 120);
        g.setColor(background);
        g.fillRect(5, 57, 230, 30);
    }

    public void keyTyped(KeyEvent e) {}
    public void keyReleased(KeyEvent e) {}

    public static void main(String[] args) {
        JFrame frame = new JFrame("Colour Dropper");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setPreferredSize(new Dimension(246, 120));
        frame.pack();
        frame.setVisible(true);
        ColourDropper frameContent = new ColourDropper();
        frame.add(frameContent);
        frame.setResizable(false);
        frame.setLocation(100, 100);
        frame.setAlwaysOnTop(true);
        frame.setIconImage(Toolkit.getDefaultToolkit().getImage("dropper.png"));
    }
}

3 个答案:

答案 0 :(得分:4)

要使KeyListener起作用,正在侦听的组件必须具有焦点。一旦焦点指向其他地方,KeyListener就会失败。通常你最好使用键绑定。

答案 1 :(得分:3)

在收听各个KeyStrokes时,使用Key Bindings的一般建议通常是最好的解决方案。在这种情况下,Key Bindings也应优先于KeyListener。

但是,在这种情况下,主要问题是在将组件添加到框架之前使框架可见。在将所有组件添加到GUI之后,应始终执行setVisible(true)方法。在使框架可见后添加组件会导致面板无法获得焦点的问题。至少这是在XP上使用JDK6_7的问题。

在论坛的未来邮政代码中,我们可以看到代码而无需下载。如果我没有花时间下载它,我们就会做出疯狂的猜测。

答案 2 :(得分:0)

您只需添加以下几行:

frame.setFocusable(true);
void main

requestFocus();

void actionPerformed

结束时

我希望,这会解决你的问题;)