Почему перестает работать кейлистенер?

В моей 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"));
    }
}

person sticks    schedule 25.09.2011    source источник
comment
1) Пожалуйста, указывайте код, а не ссылку на него. 2) hsb.setText(hue + "� " + sat + "% " + bri + "%"); А? Что это снова за оттенок?   -  person Andrew Thompson    schedule 25.09.2011


Ответы (3)


Чтобы KeyListener работал, прослушиваемый компонент должен иметь фокус. Как только фокус перенаправляется в другое место, KeyListener дает сбой. Часто вместо этого лучше использовать привязки клавиш.

person Hovercraft Full Of Eels    schedule 25.09.2011

Однако совет ремесла использовать привязки клавиш, как правило, является лучшим решением при прослушивании отдельных нажатий клавиш. Привязки клавиш в этом случае также должны быть предпочтительнее, чем KeyListener.

Однако основная проблема в этом случае заключается в том, что вы сделали фрейм видимым до того, как добавили в него компоненты. Метод setVisible(true) всегда должен выполняться после добавления всех компонентов в графический интерфейс. Добавление компонентов после того, как рамка стала видимой, приводило к тому, что панель не получала фокус. По крайней мере, это проблема использования JDK6_7 в XP.

В будущем размещайте код на форуме, чтобы мы могли видеть код, не загружая его. Если бы я не нашел время, чтобы загрузить его, мы бы просто строили дикие догадки.

person camickr    schedule 25.09.2011

Вам просто нужно добавить следующие строки:

frame.setFocusable(true);

в недействительном главном

а также

requestFocus();

в конце void actionPerformed

Я надеялся, что это решит ваши проблемы;)

person JOKUE2002    schedule 05.08.2017