Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Browsing JButtons with Arrow Keys

I've made a JButton array, which represent cards, there are 16 of them, 4 by 4. How can I browse among the JButton with the arrows on keyboard instead of the mouse, and how can I "click" on JButton by pressing ENTER instead of mouseclicking? Maybe there is another way of doing this instead of using JButtons?

Best regards!

like image 631
Carnal Avatar asked Dec 06 '22 19:12

Carnal


1 Answers

I have created a solution that will allow you to navigate buttons with the arrow keys and activate them with space and enter.

Below is all of the code. No comments are provided, so let me know if you have any questions.

import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ButtonPane extends JPanel {

   private JButton[][] buttons;

   public ButtonPane(int row, int col) {
      super(new GridLayout(row, col));
      buttons = new JButton[row][col];
      for (int i = 0; i < buttons.length; i++) {
         for (int j = 0; j < buttons[i].length; j++) {
            final int curRow = i;
            final int curCol = j;
            buttons[i][j] = new JButton(i + ", " + j);
            buttons[i][j].addKeyListener(enter);
            buttons[i][j].addKeyListener(new KeyAdapter() {
               @Override
               public void keyPressed(KeyEvent e) {
                  switch (e.getKeyCode()) {
                  case KeyEvent.VK_UP:
                     if (curRow > 0)
                        buttons[curRow - 1][curCol].requestFocus();
                     break;
                  case KeyEvent.VK_DOWN:
                     if (curRow < buttons.length - 1)
                        buttons[curRow + 1][curCol].requestFocus();
                     break;
                  case KeyEvent.VK_LEFT:
                     if (curCol > 0)
                        buttons[curRow][curCol - 1].requestFocus();
                     break;
                  case KeyEvent.VK_RIGHT:
                     if (curCol < buttons[curRow].length - 1)
                        buttons[curRow][curCol + 1].requestFocus();
                     break;
                  default:
                     break;
                  }
               }
            });
            add(buttons[i][j]);
         }
      }
   }

   private KeyListener enter = new KeyAdapter() {
      @Override
      public void keyTyped(KeyEvent e) {
         if (e.getKeyChar() == KeyEvent.VK_ENTER) {
            ((JButton) e.getComponent()).doClick();
         }
      }
   };

   public static void main(String[] args) {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.add(new ButtonPane(4, 4));
      f.pack();
      f.setVisible(true);
   }
}

To run this, simply paste into a class called ButtonPane.

The important bit here is calling requestFocus() on the correct JButton when an arrow key is called. I also registered an extra KeyListener for when the Enter key is pressed.

like image 105
jjnguy Avatar answered Dec 10 '22 11:12

jjnguy