Call ((JPanel) printer).requestFocus();
after setVisible(true);
For more info have a look at JComponent#requestFocus()
Question
I have a problem with listening to keyboard input in JPanel. I tried almost everything! Please help me with this one. I will be very grateful.
Here is my code:
public class SudokuBoardDisplay extends JPanel implements Printer, KeyListener{
private static final long serialVersionUID = 1L;
private Dimension size = new Dimension(500,100);
private SudokuBoard game;
private List<JButton> fields = new ArrayList<JButton>();
private int clickedX = -1;
private int clickedY = -1;
private int userValue = -1;
public SudokuBoardDisplay(SudokuBoard board) {
this.game = board;
this.setLayout(new GridBagLayout());
JButton picLabel;
for(int i=0; i<SudokuBoard.TAB_SIZE*SudokuBoard.TAB_SIZE; i++){
picLabel = new JButton();
picLabel.setPreferredSize(new Dimension(50,50));
picLabel.setFont(new Font("Serif", Font.PLAIN, 40));
picLabel.setBorder(BorderFactory.createDashedBorder(getForeground()));
picLabel.setActionCommand(Integer.toString(i));
fields.add(picLabel);
}
for(JButton button : fields){
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
for(int y=0; y<SudokuBoard.TAB_SIZE; y++){
for(int x=0; x<SudokuBoard.TAB_SIZE; x++){
if(e.getActionCommand().equals(Integer.toString(x+y*SudokuBoard.TAB_SIZE))){
clickedX=x;
clickedY=y;
draw();
revalidate();
repaint();
}
}
}
}
});
}
this.addKeyListener(this);
this.setFocusable(true);
this.requestFocusInWindow();
draw();
this.setVisible(true);
}
public void keyPressed(KeyEvent e) {
int userValue = Character.getNumericValue(e.getKeyChar());
System.out.println(userValue);
//((SudokuBoardDisplay)(printer)).setUserValue(userValue);
//this.requestFocusInWindow();
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
public class MainWindow extends JFrame{
public MainWindow(){
this.setLayout(new FlowLayout());
btnSolve = new JButton("Solve");
printer = new SudokuBoardDisplay(game);
dao = DaoFactory.createDao("WorkingDirectory/SAVE");
dao.write(game);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(600,650);
setResizable(false);
btnSolve.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
SudokuSolver solver = new BacktrackingSudokuSolver();
try {
game = solver.solve(game);
} catch (SolutionHasBeenFound e) {
}
printer.show(game);
}
});
add(btnSolve);
btnSave = new JButton("Save");
btnSave.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
dao.write(game);
}
});
add(btnSave);
btnLoad = new JButton("Load");
btnLoad.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
game = (SudokuBoard) dao.read();
printer.show(game);
}
});
add(btnLoad);
btnNew = new JButton("New");
btnNew.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent arg0) {
game = new SudokuBoard(5);
printer.show(game);
}
});
add(btnNew);
add((JPanel) printer);
setVisible(true);
}
}
I've deleted irrelevant pieces of code.
The focus always is on "solve" button even if I try to request focus on the JPanel.
Solution
Call ((JPanel) printer).requestFocus();
after setVisible(true);
For more info have a look at JComponent#requestFocus()
OTHER TIPS
Consider using Key Bindings instead, they provide more control over the focus level requirements need in order to generate key events, unlike KeyListener
which must be registered to a component that both is focusable and has focus in order for it to raise key events