saiarcot895 answer is correct in that it solves the problem at hand (+1). This is an example of how it might be achieved using a the Key Bindings API
KeyListener
is generally a poor choice for monitoring key events as it suffers from focus related issues, which you are attempting to resolve, but are not gurenteed to work.
A better solution is to use the Key Bindings API, which provides you with the ability to configure the focus level at which key events are triggered.
The problem you will have is the fact that you have a large number of possible key strokes to use. To this end, I simply used a Map
to map the key code to an Action
which was used to set the desired color
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Polygon;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Spring extends JPanel {
private Color flower = Color.BLACK;
private String key;
public Spring() {
Map<Integer, ColorAction> mapColors = new HashMap<>(25);
mapColors.put(KeyEvent.VK_F, new ColorAction(this, "F", new Color(10, 10, 10)));
mapColors.put(KeyEvent.VK_B, new ColorAction(this, "B", new Color(223, 45, 45)));
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
for (Integer keyCode : mapColors.keySet()) {
KeyStroke ks = KeyStroke.getKeyStroke(keyCode, 0);
im.put(ks, ks);
am.put(ks, mapColors.get(keyCode));
}
}
public void update(String ks, Color color) {
flower = color;
key = ks;
repaint();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("the key that pressed is " + key, 0, 10);
g.setColor(flower);
Polygon flowa = new Polygon();
flowa.addPoint(220, 270);
flowa.addPoint(250, 300);
flowa.addPoint(270, 270);
flowa.addPoint(250, 300);
g.fillPolygon(flowa);
g.fillRect(250, 300, 30, 30);
}
public static void main(String[] s) { //main method, creates the frame
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame f = new JFrame();
f.getContentPane().add(new Spring());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
});
}
public class ColorAction extends AbstractAction {
private Spring spring;
private String key;
private Color color;
private ColorAction(Spring spring, String ks, Color color) {
this.spring = spring;
this.key = ks;
this.color = color;
}
@Override
public void actionPerformed(ActionEvent e) {
spring.update(key, color);
}
}
}
If you find it useful, an up-vote would be welcome, but saiarcot895 answer should remain marked as correct