简体   繁体   中英

Giving a button mouse click focus

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!

  1. Make sure you all you interactions with the UI are executed from within the context of the Event Dispatching Thread
  2. Use requestFocusInWindow instead of requestFocus , requestFocus is system dependent and its functionality is therefore undefined
  3. 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());
        }
    }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM