0

I have went through many answers here and tried implementing the solutions but, my code still won't work as intended... Basically I have a lot of buttons, the size is fixed, so I get the row and column by dividing the relaive X and Y of the buttons. Than I need to send the data to a nother proram. It works with the buttons, but not with the mouse click. I'll give you my code and a dummy main, so you can try it out. Both ways to get the mouse listener working are still there. The first is commented out like /* */ and // The forwarding code was also removed, to keep this to a working minumum.
Thank you for your time.

import java.awt.GridLayout; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import javafx.scene.input.MouseEvent; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; @SuppressWarnings("serial") public class DoorMatrix extends JPanel { static JFrame f = new JFrame(); private static JButton[][] buttons; int x = 0; int y = 0; public DoorMatrix(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((j + 1) + ", " + (i + 1)); buttons[i][j].addKeyListener(enter); buttons[i][j].addMouseListener(new A2()); // buttons[i][j].addMouseListener(pressedit); // addMouseListener(pressedit); 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) { if (curCol != 5) { buttons[curRow][curCol - 1].requestFocus(); } else buttons[curRow][curCol - 2].requestFocus(); } break; case KeyEvent.VK_RIGHT: if (curCol < buttons[curRow].length - 1) { if (curCol != 3) { buttons[curRow][curCol + 1].requestFocus(); } else buttons[curRow][curCol + 2].requestFocus(); } break; default: break; } // end of switch } }); 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(); y = ((JButton) e.getComponent()).getX(); x = ((JButton) e.getComponent()).getY(); if (x != 0) {x = (x / 26);} x++; if (y != 0) {y = (y / 54);} y++; System.out.print(y + ". module " + x + ". door \n"); x = 0; y = 0; } if (e.getKeyChar() == KeyEvent.VK_ESCAPE) {f.dispose();} } }; /* private MouseListener pressedit = new MouseAdapter() { public void mouseClicked(MouseEvent m) { if (m.getEventType() == MouseEvent.MOUSE_PRESSED) { ((JButton) m.getSource()).doClick(); y = ((JButton) m.getSource()).getX(); x = ((JButton) m.getSource()).getY(); if(x != 0){x = (x / 26);} x++; if(y != 0){y = (y / 54);} y++; System.out.print(y + ". module " + x + ". door \n"); x =0; y =0;} }}; */ public class A2 extends MouseAdapter { public void MousePressed(MouseEvent e) { ((JButton) e.getSource()).doClick(); y = ((JButton) e.getSource()).getX(); x = ((JButton) e.getSource()).getY(); if (x != 0) {x = (x / 26);} x++; if (y != 0) {y = (y / 54);} y++; System.out.print(y + ". module " + x + ". door"); x = 0; y = 0; } // end of event public void mouseClicked(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} } // end of adapter public static void main(String[] args) { int a = 0; int b = 7; f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new DoorMatrix(12, 9)); while (a < 2) { while (b < 12) { buttons[b][a].setVisible(false); b++; } a++; b = 7; } a = 4; b = 0; while (b < 12) { buttons[b][a].setVisible(false); b++; } b = 7; a = 7; while (a < 9) { while (b < 12) { buttons[b][a].setVisible(false); b++; } a++; b = 7; } f.pack(); f.setVisible(true); f.setResizable(false); } } 
1
  • 1
    1- Don't use KeyListener with buttons, 2- Don't use ActionListener with buttons...use a ActionListener Commented Aug 4, 2014 at 6:47

1 Answer 1

1
  1. Don't use KeyListeners with buttons
  2. Don't use MouseListeners with buttons

Buttons are designed to operate with ActionListeners or Actions.

In your case, I would suggest that the Action API provides you with the greatest flexibility, as you can pass the physical row/col position of the button within the array that the button appears and then re-use this information without needing to rely on performing calculations.

This takes care of what happens when the user clicks the button and presses the "action" key (typically the Enter key)

For example, you could replace your KeyListener and MouseListener with something like...

public class ButtonAction extends AbstractAction { private int row, col; protected ButtonAction(int j, int i) { putValue(NAME, (j + 1) + ", " + (i + 1)); row = i; col = j; } public int getRow() { return row; } public int getCol() { return col; } @Override public void actionPerformed(ActionEvent e) { System.out.println("Look, button @ " + getCol() + "x" + getRow() + " was activated, that was easy..."); } } 

Which will print out the index of the row/col of the button within the buttons array when it is actioed. We can reuse this information later.

We can replace the KeyListener with the key bindings API, for example...

InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right"); ActionMap am = getActionMap(); am.put("up", new MoveAction(0, -1)); am.put("down", new MoveAction(0, 1)); am.put("left", new MoveAction(-1, 0)); am.put("right", new MoveAction(1, 0)); 

Which uses

public class MoveAction extends AbstractAction { private int colDelta; private int rowDelta; public MoveAction(int colDelta, int rowDelta) { this.colDelta = colDelta; this.rowDelta = rowDelta; } public int getColDelta() { return colDelta; } public int getRowDelta() { return rowDelta; } @Override public void actionPerformed(ActionEvent e) { Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if (owner instanceof JButton) { JButton btn = (JButton) owner; Action action = btn.getAction(); if (action instanceof ButtonAction) { ButtonAction ba = (ButtonAction) action; int row = ba.getRow(); int col = ba.getCol(); do { row += getRowDelta(); col += getColDelta(); if (row < 0) { row = buttons.length - 1; } else if (row >= buttons.length) { row = 0; } if (col < 0) { col = buttons[row].length - 1; } else if (col >= buttons[row].length) { col = 0; } } while (!buttons[row][col].isVisible()); buttons[row][col].requestFocusInWindow(); } } } } 

Which basically looks up the currently focused component, determines if it's JButton or not, if it contains a ButtonAction or not and if those conditions are try, it will extract the row and col position of the ButtonAction. This information is then modified (the deltas are applied) and the next focusable button is looked and focused...

As a fully runnable example...

import java.awt.Component; import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.KeyboardFocusManager; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.ActionMap; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class DoorMatrix extends JPanel { static JFrame f = new JFrame(); private static JButton[][] buttons; int x = 0; int y = 0; public DoorMatrix(int row, int col) { super(new GridLayout(row, col)); buttons = new JButton[row][col]; InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left"); im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right"); ActionMap am = getActionMap(); am.put("up", new MoveAction(0, -1)); am.put("down", new MoveAction(0, 1)); am.put("left", new MoveAction(-1, 0)); am.put("right", new MoveAction(1, 0)); for (int i = 0; i < buttons.length; i++) { for (int j = 0; j < buttons[i].length; j++) { buttons[i][j] = new JButton(new ButtonAction(j, i)); add(buttons[i][j]); } } } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } int a = 0; int b = 7; f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new DoorMatrix(12, 9)); while (a < 2) { while (b < 12) { buttons[b][a].setVisible(false); b++; } a++; b = 7; } a = 4; b = 0; while (b < 12) { buttons[b][a].setVisible(false); b++; } b = 7; a = 7; while (a < 9) { while (b < 12) { buttons[b][a].setVisible(false); b++; } a++; b = 7; } f.pack(); f.setVisible(true); f.setResizable(false); } }); } public class ButtonAction extends AbstractAction { private int row, col; protected ButtonAction(int j, int i) { putValue(NAME, (j + 1) + ", " + (i + 1)); row = i; col = j; } public int getRow() { return row; } public int getCol() { return col; } @Override public void actionPerformed(ActionEvent e) { System.out.println("Look, button @ " + getCol() + "x" + getRow() + " was activated, that was easy..."); } } public class MoveAction extends AbstractAction { private int colDelta; private int rowDelta; public MoveAction(int colDelta, int rowDelta) { this.colDelta = colDelta; this.rowDelta = rowDelta; } public int getColDelta() { return colDelta; } public int getRowDelta() { return rowDelta; } @Override public void actionPerformed(ActionEvent e) { Component owner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner(); if (owner instanceof JButton) { JButton btn = (JButton) owner; Action action = btn.getAction(); if (action instanceof ButtonAction) { ButtonAction ba = (ButtonAction) action; int row = ba.getRow(); int col = ba.getCol(); do { row += getRowDelta(); col += getColDelta(); if (row < 0) { row = buttons.length - 1; } else if (row >= buttons.length) { row = 0; } if (col < 0) { col = buttons[row].length - 1; } else if (col >= buttons[row].length) { col = 0; } } while (!buttons[row][col].isVisible()); buttons[row][col].requestFocusInWindow(); } } } } } 

Take a look at How to Use Actions, How to Use Key Bindings, How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listeners for more details

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, it works like a charm. I'll analyze this code more in dept; to avoid future mistakes. Have a nice day.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.