How would I programmatically click a Swing JButton in a way that would register all the relevant action/mouse events and be visible to the user (i.e. they'd see the button being pressed as if they actually clicked it)?
The button is in the same application I'm running; I'm not trying to control a button in another application. I suppose I could directly inject events into the queue, but I'd prefer to avoid that approach if possible, and doing it that way wouldn't show a visible click.
I see the java.awt.Robot class offers methods to move the mouse and click the mouse, but not to make it click a particular button.
Have you tried using doClick()?
If doClick() is not what you want, you can move the mouse really to the button and press it:
public void click(AbstractButton button, int millis) throws AWTException
{
Point p = button.getLocationOnScreen();
Robot r = new Robot();
r.mouseMove(p.x + button.getWidth() / 2, p.y + button.getHeight() / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try { Thread.sleep(millis); } catch (Exception e) {}
r.mouseRelease(InputEvent.BUTTON1_MASK);
}
Even though the asker was satisfied with button.doClick(), I was looking for something like what happens after setting a mnemonic, i.e. with button.setMnemonic(KeyEvent.VK_A). You can actually hold down ALT + A without anything happening (except the visual change). And upon release of the key A (with or without ALT), the button fires an ActionEvent.
I found that I can get the ButtonModel (see Java 8 API) with button.getModel(), then visually press the button with model.setPressed(true); model.setArmed(true); (both are changed by mnemonics), and visually release the button by setting both to false. And when model.setPressed(false) is called while the button is both pressed and armed, the button fires an ActionEvent automatically (calling model.setArmed(false) only changes the button visually).
[Quote from ButtonModel Java API documentation]
A button is triggered, and an ActionEvent is fired, when the mouse is released while the model is armed [...]
To make the application react to key presses when the button is visible (without the containing window or the button needing to be the focus owner, i.e. when another component in the window is focussed) I used key bindings (see the Official Java Tutorial).
Working code: Press SHIFT + A to visually press the button (in contrast to pressing ALT with the key after the mnemonic is set with button.setMnemonic()). And release the key to print the action command ("button") on the console.
// MnemonicCode.java
import javax.swing.*;
import java.awt.event.*;
public class MnemonicCode extends JFrame
{
public MnemonicCode(int keyCode)
{
JButton button = new JButton("button");
getContentPane().add(button);
addMnemonicToButton(button,keyCode);
button.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e)
{
System.out.println(e.getActionCommand());
}
});
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) throws Exception
{
MnemonicCode bp = new MnemonicCode(KeyEvent.VK_A);
}
void addMnemonicToButton(JButton button,int keyCode)
{
int shiftMask = InputEvent.SHIFT_DOWN_MASK;
// signature: getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)
KeyStroke keyPress = KeyStroke.getKeyStroke(keyCode,shiftMask,false);
KeyStroke keyReleaseWithShift = KeyStroke.getKeyStroke(keyCode,shiftMask,true);
// get maps for key bindings
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = button.getActionMap();
// add key bindings for pressing and releasing the button
inputMap.put(keyPress,"press"+keyCode);
actionMap.put("press"+keyCode, new ButtonPress(button));
inputMap.put(keyReleaseWithShift,"releaseWithShift"+keyCode);
actionMap.put("releaseWithShift"+keyCode, new ButtonRelease(button));
///*
// add key binding for releasing SHIFT before A
// if you use more than one modifier it gets really messy
KeyStroke keyReleaseAfterShift = KeyStroke.getKeyStroke(keyCode,0,true);
inputMap.put(keyReleaseAfterShift,"releaseAfterShift"+keyCode);
actionMap.put("releaseAfterShift"+keyCode, new ButtonRelease(button));
//*/
}
class ButtonPress extends AbstractAction
{
private JButton button;
private ButtonModel model;
ButtonPress(JButton button)
{
this.button = button;
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
// visually press the button
model.setPressed(true);
model.setArmed(true);
button.requestFocusInWindow();
}
}
class ButtonRelease extends AbstractAction
{
private ButtonModel model;
ButtonRelease(JButton button)
{
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
if (model.isPressed()) {
// visually release the button
// setPressed(false) also makes the button fire an ActionEvent
model.setPressed(false);
model.setArmed(false);
}
}
}
}
You could always simulate it by firing an action event with it as the source.
http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html
To fire it, create the action event above, and whatever listener you want just call
ActionEvent e = new ActionEvent(myButton,1234,"CommandToPeform");
myListener.actionPerformed(e);
From: http://download.oracle.com/javase/6/docs/api/javax/swing/JButton.html
/**
* Click a button on screen
*
* #param button Button to click
* #param millis Time that button will remain "clicked" in milliseconds
*/
public void click(AbstractButton button, int millis) {
b.doClick(millis);
}
Based on #Courteaux's answer, this method clicks the first cell in a JTable:
private void clickFirstCell() {
try {
jTable1.changeSelection(0, 0, false, false);
Point p = jTable1.getLocationOnScreen();
Rectangle cellRect = jTable1.getCellRect(0, 0, true);
Robot r = new Robot();
Point mouse = MouseInfo.getPointerInfo().getLocation();
r.mouseMove(p.x + cellRect.x + cellRect.width / 2,
p.y + cellRect.y + cellRect.height / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try {
Thread.sleep(50);
} catch (Exception e) {
}
r.mouseRelease(InputEvent.BUTTON1_MASK);
r.mouseMove(mouse.x, mouse.y);
} catch (AWTException ex) {
}
}
Related
How would I programmatically click a Swing JButton in a way that would register all the relevant action/mouse events and be visible to the user (i.e. they'd see the button being pressed as if they actually clicked it)?
The button is in the same application I'm running; I'm not trying to control a button in another application. I suppose I could directly inject events into the queue, but I'd prefer to avoid that approach if possible, and doing it that way wouldn't show a visible click.
I see the java.awt.Robot class offers methods to move the mouse and click the mouse, but not to make it click a particular button.
Have you tried using doClick()?
If doClick() is not what you want, you can move the mouse really to the button and press it:
public void click(AbstractButton button, int millis) throws AWTException
{
Point p = button.getLocationOnScreen();
Robot r = new Robot();
r.mouseMove(p.x + button.getWidth() / 2, p.y + button.getHeight() / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try { Thread.sleep(millis); } catch (Exception e) {}
r.mouseRelease(InputEvent.BUTTON1_MASK);
}
Even though the asker was satisfied with button.doClick(), I was looking for something like what happens after setting a mnemonic, i.e. with button.setMnemonic(KeyEvent.VK_A). You can actually hold down ALT + A without anything happening (except the visual change). And upon release of the key A (with or without ALT), the button fires an ActionEvent.
I found that I can get the ButtonModel (see Java 8 API) with button.getModel(), then visually press the button with model.setPressed(true); model.setArmed(true); (both are changed by mnemonics), and visually release the button by setting both to false. And when model.setPressed(false) is called while the button is both pressed and armed, the button fires an ActionEvent automatically (calling model.setArmed(false) only changes the button visually).
[Quote from ButtonModel Java API documentation]
A button is triggered, and an ActionEvent is fired, when the mouse is released while the model is armed [...]
To make the application react to key presses when the button is visible (without the containing window or the button needing to be the focus owner, i.e. when another component in the window is focussed) I used key bindings (see the Official Java Tutorial).
Working code: Press SHIFT + A to visually press the button (in contrast to pressing ALT with the key after the mnemonic is set with button.setMnemonic()). And release the key to print the action command ("button") on the console.
// MnemonicCode.java
import javax.swing.*;
import java.awt.event.*;
public class MnemonicCode extends JFrame
{
public MnemonicCode(int keyCode)
{
JButton button = new JButton("button");
getContentPane().add(button);
addMnemonicToButton(button,keyCode);
button.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e)
{
System.out.println(e.getActionCommand());
}
});
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) throws Exception
{
MnemonicCode bp = new MnemonicCode(KeyEvent.VK_A);
}
void addMnemonicToButton(JButton button,int keyCode)
{
int shiftMask = InputEvent.SHIFT_DOWN_MASK;
// signature: getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)
KeyStroke keyPress = KeyStroke.getKeyStroke(keyCode,shiftMask,false);
KeyStroke keyReleaseWithShift = KeyStroke.getKeyStroke(keyCode,shiftMask,true);
// get maps for key bindings
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = button.getActionMap();
// add key bindings for pressing and releasing the button
inputMap.put(keyPress,"press"+keyCode);
actionMap.put("press"+keyCode, new ButtonPress(button));
inputMap.put(keyReleaseWithShift,"releaseWithShift"+keyCode);
actionMap.put("releaseWithShift"+keyCode, new ButtonRelease(button));
///*
// add key binding for releasing SHIFT before A
// if you use more than one modifier it gets really messy
KeyStroke keyReleaseAfterShift = KeyStroke.getKeyStroke(keyCode,0,true);
inputMap.put(keyReleaseAfterShift,"releaseAfterShift"+keyCode);
actionMap.put("releaseAfterShift"+keyCode, new ButtonRelease(button));
//*/
}
class ButtonPress extends AbstractAction
{
private JButton button;
private ButtonModel model;
ButtonPress(JButton button)
{
this.button = button;
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
// visually press the button
model.setPressed(true);
model.setArmed(true);
button.requestFocusInWindow();
}
}
class ButtonRelease extends AbstractAction
{
private ButtonModel model;
ButtonRelease(JButton button)
{
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
if (model.isPressed()) {
// visually release the button
// setPressed(false) also makes the button fire an ActionEvent
model.setPressed(false);
model.setArmed(false);
}
}
}
}
You could always simulate it by firing an action event with it as the source.
http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html
To fire it, create the action event above, and whatever listener you want just call
ActionEvent e = new ActionEvent(myButton,1234,"CommandToPeform");
myListener.actionPerformed(e);
From: http://download.oracle.com/javase/6/docs/api/javax/swing/JButton.html
/**
* Click a button on screen
*
* #param button Button to click
* #param millis Time that button will remain "clicked" in milliseconds
*/
public void click(AbstractButton button, int millis) {
b.doClick(millis);
}
Based on #Courteaux's answer, this method clicks the first cell in a JTable:
private void clickFirstCell() {
try {
jTable1.changeSelection(0, 0, false, false);
Point p = jTable1.getLocationOnScreen();
Rectangle cellRect = jTable1.getCellRect(0, 0, true);
Robot r = new Robot();
Point mouse = MouseInfo.getPointerInfo().getLocation();
r.mouseMove(p.x + cellRect.x + cellRect.width / 2,
p.y + cellRect.y + cellRect.height / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try {
Thread.sleep(50);
} catch (Exception e) {
}
r.mouseRelease(InputEvent.BUTTON1_MASK);
r.mouseMove(mouse.x, mouse.y);
} catch (AWTException ex) {
}
}
How would I programmatically click a Swing JButton in a way that would register all the relevant action/mouse events and be visible to the user (i.e. they'd see the button being pressed as if they actually clicked it)?
The button is in the same application I'm running; I'm not trying to control a button in another application. I suppose I could directly inject events into the queue, but I'd prefer to avoid that approach if possible, and doing it that way wouldn't show a visible click.
I see the java.awt.Robot class offers methods to move the mouse and click the mouse, but not to make it click a particular button.
Have you tried using doClick()?
If doClick() is not what you want, you can move the mouse really to the button and press it:
public void click(AbstractButton button, int millis) throws AWTException
{
Point p = button.getLocationOnScreen();
Robot r = new Robot();
r.mouseMove(p.x + button.getWidth() / 2, p.y + button.getHeight() / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try { Thread.sleep(millis); } catch (Exception e) {}
r.mouseRelease(InputEvent.BUTTON1_MASK);
}
Even though the asker was satisfied with button.doClick(), I was looking for something like what happens after setting a mnemonic, i.e. with button.setMnemonic(KeyEvent.VK_A). You can actually hold down ALT + A without anything happening (except the visual change). And upon release of the key A (with or without ALT), the button fires an ActionEvent.
I found that I can get the ButtonModel (see Java 8 API) with button.getModel(), then visually press the button with model.setPressed(true); model.setArmed(true); (both are changed by mnemonics), and visually release the button by setting both to false. And when model.setPressed(false) is called while the button is both pressed and armed, the button fires an ActionEvent automatically (calling model.setArmed(false) only changes the button visually).
[Quote from ButtonModel Java API documentation]
A button is triggered, and an ActionEvent is fired, when the mouse is released while the model is armed [...]
To make the application react to key presses when the button is visible (without the containing window or the button needing to be the focus owner, i.e. when another component in the window is focussed) I used key bindings (see the Official Java Tutorial).
Working code: Press SHIFT + A to visually press the button (in contrast to pressing ALT with the key after the mnemonic is set with button.setMnemonic()). And release the key to print the action command ("button") on the console.
// MnemonicCode.java
import javax.swing.*;
import java.awt.event.*;
public class MnemonicCode extends JFrame
{
public MnemonicCode(int keyCode)
{
JButton button = new JButton("button");
getContentPane().add(button);
addMnemonicToButton(button,keyCode);
button.addActionListener(new ActionListener () {
public void actionPerformed(ActionEvent e)
{
System.out.println(e.getActionCommand());
}
});
pack();
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) throws Exception
{
MnemonicCode bp = new MnemonicCode(KeyEvent.VK_A);
}
void addMnemonicToButton(JButton button,int keyCode)
{
int shiftMask = InputEvent.SHIFT_DOWN_MASK;
// signature: getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease)
KeyStroke keyPress = KeyStroke.getKeyStroke(keyCode,shiftMask,false);
KeyStroke keyReleaseWithShift = KeyStroke.getKeyStroke(keyCode,shiftMask,true);
// get maps for key bindings
InputMap inputMap = button.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = button.getActionMap();
// add key bindings for pressing and releasing the button
inputMap.put(keyPress,"press"+keyCode);
actionMap.put("press"+keyCode, new ButtonPress(button));
inputMap.put(keyReleaseWithShift,"releaseWithShift"+keyCode);
actionMap.put("releaseWithShift"+keyCode, new ButtonRelease(button));
///*
// add key binding for releasing SHIFT before A
// if you use more than one modifier it gets really messy
KeyStroke keyReleaseAfterShift = KeyStroke.getKeyStroke(keyCode,0,true);
inputMap.put(keyReleaseAfterShift,"releaseAfterShift"+keyCode);
actionMap.put("releaseAfterShift"+keyCode, new ButtonRelease(button));
//*/
}
class ButtonPress extends AbstractAction
{
private JButton button;
private ButtonModel model;
ButtonPress(JButton button)
{
this.button = button;
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
// visually press the button
model.setPressed(true);
model.setArmed(true);
button.requestFocusInWindow();
}
}
class ButtonRelease extends AbstractAction
{
private ButtonModel model;
ButtonRelease(JButton button)
{
this.model = button.getModel();
}
public void actionPerformed(ActionEvent e)
{
if (model.isPressed()) {
// visually release the button
// setPressed(false) also makes the button fire an ActionEvent
model.setPressed(false);
model.setArmed(false);
}
}
}
}
You could always simulate it by firing an action event with it as the source.
http://download.oracle.com/javase/6/docs/api/java/awt/event/ActionEvent.html
To fire it, create the action event above, and whatever listener you want just call
ActionEvent e = new ActionEvent(myButton,1234,"CommandToPeform");
myListener.actionPerformed(e);
From: http://download.oracle.com/javase/6/docs/api/javax/swing/JButton.html
/**
* Click a button on screen
*
* #param button Button to click
* #param millis Time that button will remain "clicked" in milliseconds
*/
public void click(AbstractButton button, int millis) {
b.doClick(millis);
}
Based on #Courteaux's answer, this method clicks the first cell in a JTable:
private void clickFirstCell() {
try {
jTable1.changeSelection(0, 0, false, false);
Point p = jTable1.getLocationOnScreen();
Rectangle cellRect = jTable1.getCellRect(0, 0, true);
Robot r = new Robot();
Point mouse = MouseInfo.getPointerInfo().getLocation();
r.mouseMove(p.x + cellRect.x + cellRect.width / 2,
p.y + cellRect.y + cellRect.height / 2);
r.mousePress(InputEvent.BUTTON1_MASK);
try {
Thread.sleep(50);
} catch (Exception e) {
}
r.mouseRelease(InputEvent.BUTTON1_MASK);
r.mouseMove(mouse.x, mouse.y);
} catch (AWTException ex) {
}
}
I'm currently working on my first GUI program, and there's one issue I do not know how to solve - I've provided a minimal (non-compilable) example below.
The problem is that, in some cases, if the delete key is pressed shortly after the mouse click which should change activeElement, the key action is executed before activeElement has been changed to the new value. How can I ensure that the code in actionPerformed waits for activeElement to be changed by mouseClicked?
public class Problem extends JPanel implements MouseListener{
Element activeElement = null;
public Problem(){
super();
this.addMouseListener(this);
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE,0),"test");
am.put("test",new AbstractAction(){
#Override
public void actionPerformed(ActionEvent ae){
if(activeElement!=null){
doSomethingWith(activeElement);
repaint();
}
}
});
}
#Override
public void mouseClicked(MouseEvent me){
activeElement = getElementByCoordinates(me.getX(),me.getY());
}
private Element getElementByCoordinates(int x, int y){
[...]
}
private void doSomethingWith(Element e){
[...]
}
}
mouseClicked is called after you have pressed and the released the mouse in (nearly) the same location. If you type your key before releasing the mouse, the InputMap will be triggered before mouseClicked is called.
To register a mouse press before the key is pressed, regardless of whether the mouse button has been released, place your code in mousePressed rather than mouseClicked.
I have a situation where I have a popup menu created when a JTable is right clicked on. Standard way of creating the popup menu:
aJTable.setComponentPopupMenu(rightClickMenu);
Now afterwards in the action that gets registered, I am unable to find out which cell was right clicked on to get that popup menu to appear.
rightClickMenuItem.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
// Work out what cell was right clicked to generate the menu
}
});
Any ideas on how you do this?
Astonishing fact: with a componentPopupMenu installed, a mouseListener never sees the mouseEvent that is the popupTrigger (reason is that showing the componentPopup is handled globally by a AWTEventListener installed by BasicLookAndFeel, and that listener consumes the event).
The only place which sees the mousePosition of that trigger is the getPopupLocation(MouseEvent), so the only reliable way to get hold of it (for doing location dependent config/actions) is #Mad's suggestion to override that method and store the value somewhere for later use.
The snippet below uses a clientProperty as storage location:
final JTable table = new JTable(new AncientSwingTeam()) {
#Override
public Point getPopupLocation(MouseEvent event) {
setPopupTriggerLocation(event);
return super.getPopupLocation(event);
}
protected void setPopupTriggerLocation(MouseEvent event) {
putClientProperty("popupTriggerLocation",
event != null ? event.getPoint() : null);
}
};
JPopupMenu popup = new JPopupMenu();
Action action = new AbstractAction("show trigger location") {
#Override
public void actionPerformed(ActionEvent e) {
JPopupMenu parent = (JPopupMenu) SwingUtilities.getAncestorOfClass(
JPopupMenu.class, (Component) e.getSource());
JTable invoker = (JTable) parent.getInvoker();
Point p = (Point) invoker.getClientProperty("popupTriggerLocation");
String output = p != null ? "row/col: "
+ invoker.rowAtPoint(p) + "/" + invoker.columnAtPoint(p) : null;
System.out.println(output);
}
};
popup.add(action);
popup.add("dummy2");
table.setComponentPopupMenu(popup);
#MadProgrammer's suggestion of getPopupLocation looked promising, but I couldn't work out how to get the information across between the table and the actionEvent...
I got around this by making sure that the row was selected when you rightclicked on it -> since the popup menu prevents the selection of the row, you can add in a mouse listener that makes sure the row gets selected no matter what click (left or right) is pressed.
aTable.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
int r = aTable.rowAtPoint(e.getPoint());
if (r >= 0 && r < clt.getRowCount()) {
aTable.setRowSelectionInterval(r, r);
} else {
aTable.clearSelection();
}
}
});
This means that in the rightClickMenuItem's action listener, you can grab the table's selected cell / row
rightClickMenuItem.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
aTable.get details about the selected one....
}
});
Too easy! Thanks everyone for the help.
JTable has methods
int row = rowAtPoint(p);
int col = columnAtPoint(p);
So pass the MouseEvent's point and use the values
Add a MouseListener and store the last right click point somewhere.
Hopefully I can explain this well enough to make sense.
My cousin is disabled and used a single button to control applications on the computer. All these applications are custom made and they rely on buttons that cycle focus and highlight in bold. By doing this you can just click when the button is highlighted and this removes the need to move the mouse.
I'm currently making a little game for him and I've hit a snag with the focusing part. I'm using a thread to cycle the focus and LayoutButton.requestFocus(); to get the focus.
This works if the space bar is pressed, but the button he uses however pushes the left mouse click.
Is there a way to set focus of a button to the left mouse click? So the mouse would have to effectively point at the button so when you click the mouse the button pushes. It would then have to unfocus that button and refocus on the next button. Make sense?
If someone could point me in the right direction I'd appreciate it. Thanks!
Make sure you all you interactions with the UI are executed from within the context of the Event Dispatching Thread
Use requestFocusInWindow instead of requestFocus, requestFocus is system dependent and its functionality is therefore undefined
You can change the position of the mouse cursor to sit on the button through the use of the Robot class.
You will want to use a combination of Component#getLocationOnScreen and Robot#mouseMove
Something like...
try {
button.requestFocusInWindow();
Robot bot = new Robot();
Point pos = button.getLocationOnScreen();
bot.mouseMove(pos.x + (button.getWidth() / 2), pos.y + (button.getHeight() / 2));
} catch (AWTException ex) {
Logger.getLogger(TestRobot.class.getName()).log(Level.SEVERE, null, ex);
}
UPDATED with example
Okay, here's a working example. This has a timer built into it that simple moves to the next focusable component.
I've attached a focus component to each button that moves the mouse to the center of each button.
This means that you can allow the timer to move to the next component or press tab and you should get the same result
public class TestFocusTransversal {
public static void main(String[] args) {
new TestFocusTransversal();
}
public TestFocusTransversal() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new ButtonPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
FocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
}
});
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
});
}
public class ButtonPane extends JPanel {
public ButtonPane() {
setLayout(new GridLayout(3, 2));
FocusHandler focusHandler = new FocusHandler();
ActionHandler actionHandler = new ActionHandler();
for (int index = 0; index < 6; index++) {
JButton button = new JButton("Button " + index);
button.addActionListener(actionHandler);
button.addFocusListener(focusHandler);
add(button);
}
}
}
public class FocusHandler extends FocusAdapter {
#Override
public void focusGained(FocusEvent e) {
try {
Robot bot = new Robot();
Component component = e.getComponent();
Point pos = component.getLocationOnScreen();
bot.mouseMove(pos.x + (component.getWidth() / 2), pos.y + (component.getHeight() / 2));
} catch (AWTException ex) {
ex.printStackTrace();
}
}
}
public class ActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
JButton button = ((JButton)e.getSource());
System.out.println("Fired " + button.getText());
}
}
}