Post a KeyEvent to the focused component

What is the best way to post a Button Press to a component? I tried using the Robot class and it works, normally. However, this class has some problems under some Linux platforms, so I wonder what is the best Java-only way to post an event to a component.

In this particular case, I want to post backspace events to a JTextField when I press a button.

EDIT: I've used the Robot class after all. I fixed the problem that prevented this class from working correctly under Linux

Answers


You can find example of such key post event, like in this class

Those posts are using the dispatchEvent() function

public void mousePressed(MouseEvent event) {
    KeyboardButton key = getKey(event.getX(), event.getY());

[...]

      KeyEvent ke;
      Component source = Component.getFocusComponent();
      lastPressed = key;
      lastSource = source;
      key.setPressed(true);

      if(source != null) {

        if((key == k_accent || key == k_circle) && (lastKey instanceof KeyboardButtonTextJapanese)) {
          int accent = ((KeyboardButtonTextJapanese)lastKey).getAccent();
          if(accent >= 1 && key == k_accent) {

            /*
            ** First send a backspace to delete the previous character, then send the character with the accent.
            */

            source.dispatchEvent(new KeyEvent(source, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, k_backspace.getKeyEvent(), k_backspace.getKeyChar()));
            source.dispatchEvent(new KeyEvent(source, KeyEvent.KEY_TYPED,   System.currentTimeMillis(), 0, k_backspace.getKeyEvent(), k_backspace.getKeyChar()));

I ended up using the robot class, which was the easiest way after all. The problem is that in the specific Linux distro I was using, the instantiation of the Robot class would hang the Virtual Machine. Looking at the log files I found out that java was trying to load a DLL that wasn't available:

libXi.so.6

After adding this library to the distro I was able to continue


There's also this approach to avoid relaying in the robot:

import java.awt.*;
import java.awt.event.KeyEvent;
import javax.swing.*;

public class KeyEventTest
{
    public static void main(String[] args)
    {
        final JTextField textField = new JTextField(8);
        textField.setFont(textField.getFont().deriveFont(18f));
        JPanel panel = new JPanel(new GridBagLayout());
        panel.add(textField, new GridBagConstraints());
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.getContentPane().add(panel);
        f.setSize(300,160);
        f.setLocation(200,200);
        f.setVisible(true);
        new Thread(new Runnable()
        {
            public void run()
            {
                Toolkit toolkit = Toolkit.getDefaultToolkit();
                EventQueue queue = toolkit.getSystemEventQueue();
                try {
                    Thread.sleep(1500);
                } catch(InterruptedException ie) { }
                char newChar = 'x';
                queue.postEvent(new KeyEvent(textField,
                                             KeyEvent.KEY_TYPED,
                                             System.currentTimeMillis(),
                                             0,
                                             KeyEvent.VK_UNDEFINED,
                                             newChar));
                try {
                    Thread.sleep(1500);
                } catch(InterruptedException ie) { }
                queue.postEvent(new KeyEvent(textField,
                                             KeyEvent.KEY_PRESSED,
                                             System.currentTimeMillis(),
                                             0,
                                             KeyEvent.VK_BACK_SPACE,
                                             KeyEvent.CHAR_UNDEFINED));
            }
        }).start();
    }
}

I must warn you that if the component loses the focus the generated events will be lost! D:


Need Your Help

WPF MVVM: How to enable/disable buttons in ListBox if I'm using a DataTemplate

wpf mvvm listbox command datatemplate

I have a WPF/MVVM app with a ListBox which displays data through a DataTemplate. I managed to change the selected item in the ListBox when pressing a button so the CommandParameter is linked to the

iPhone video control and dual video playback

iphone video uiwebview mpmovieplayercontroller playback

I need a way of controlling video non-fullscreen in my application. I've played around with both MPMoviePlayerController and a solution using UIWebViews.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.