问题
In my Java program, whenever I select some text from a JTextField, the keyListener stops detecting key presses. I noticed the same thing happens when a JButton is pressed. Do I need to remove the keyListener from the objects after using them? If so, how to I do this?
Here is a copy of the program I'm having problems with:
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"));
}
}
回答1:
For a KeyListener to work, the component that is being listened to must have the focus. As soon as the focus is directed elsewhere, the KeyListener fails. Often you're better off using key bindings instead.
回答2:
Howevercrafts advice to use Key Bindings is generally the best solution when listening for individual KeyStrokes. Key Bindings should be preferred over a KeyListener in this case as well.
However, the main problem in this case is that you made the frame visible before adding the components to the frame. The setVisible(true) method should always be executed after all components have been added to the GUI. Adding components after making the frame visible caused a problem with the panel not getting focus. At least that is the problem using JDK6_7 on XP.
In the future post code in the forum so we can see the code without downloading it. If I didn't take the time to download it we would just be making wild guesses.
回答3:
You just have to add these following lines:
frame.setFocusable(true);
in the void main
and
requestFocus();
at the end of void actionPerformed
I hoped, that this will fix your problems ;)
来源:https://stackoverflow.com/questions/7543628/why-does-the-keylistener-stop-working