2

I have some simple code where I'm trying to get keyboard events into a Java applet. The code runs just fine when being run with appletviewer, but when I'm loading it from a browser (tried both Chrome and Firefox), the JApplet won't get focus on click.

Trying exactly the same code with Applet instead of JApplet works without a problem.

Here's my code:

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

public class Test extends JApplet {
    String s = "";

    public void init() {
            setFocusable(true);
            setEnabled(true);
            addKeyListener(new KeyAdapter() {
                    @Override
                    public void keyPressed(KeyEvent e) {
                            s = "KEY PRESSED: " + e.getKeyCode();
                            repaint();
                    }

            });
            addMouseListener(new MouseAdapter() {
                     @Override
                     public void mousePressed(MouseEvent e) {
                             boolean ret = requestFocusInWindow();
                             s = "requestFocusInWindow: " + ret;
                             repaint();
                     }
            });
            requestFocusInWindow();
    }

    public void start() {
            requestFocusInWindow();
    }

    public void paint(Graphics g) {
            super.paint(g);
            requestFocusInWindow();
            g.setColor(Color.BLACK);
            s = "Focus owner: " + isFocusOwner() + ", " + s;
            g.drawString(s, 24, 24);
    }
}
Roman C
  • 49,761
  • 33
  • 66
  • 176
Ionut Nicu
  • 21
  • 1

1 Answers1

2
  • Applets should be created on Event Dispatch Thread by wrapping code in overridden init() method in SwingUtilities.invokeAndWait() block

  • Dont use KeyListener for JApplet/Swing components use KeyBindings

  • call requestFocusInWindow() on JApplet after creating and adding all content to container (this is not necessary with keybindings though)

  • Also dont do drawing in paint() rather add JPanel to container and override paintComponent(..)

Here is a small example, its a simple JLabel with a dummy label and textfield added to the container with a KeyBinding for A only; so when A is pressed it will be added to JLabel text:

enter image description here

import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.lang.reflect.InvocationTargetException;
import javax.swing.AbstractAction;
import javax.swing.JApplet;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;

public class Test extends JApplet {

    @Override
    public void init() {
        try {
            SwingUtilities.invokeAndWait(new Runnable() {
                @Override
                public void run() {

                    final JLabel label = new JLabel("Text:");
                    final JLabel label2 = new JLabel("Dummy label");
                    final JTextField jtf = new JTextField("Dummy Field");
                    label2.setFocusable(true);
                    label.setFocusable(true);

                    //allwos user to add letter A to JLabel
                    label.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_A, 0), "A");
                    label.getActionMap().put("A", new AbstractAction() {
                        @Override
                        public void actionPerformed(ActionEvent ae) {
                            String tmp = label.getText();
                            label.setText(tmp + "A");

                        }
                    });

                    setLayout(new GridLayout(3, 1));

                    add(label);
                    add(label2);
                    add(jtf);
                }
            });
        } catch (InterruptedException | InvocationTargetException ex) {
            ex.printStackTrace();
        }
    }
}
David Kroukamp
  • 36,155
  • 13
  • 81
  • 138
  • David, thanks for your suggestions, but your example shows the same behavior as mine. When run from a browser the applet doesn't get focus unless you click on the JTextField. When run from appletviewer it gets focus without clicking on the text field. I tried also using the KeyBinding API instead of KeyEventListener, but the problem is the focus, requestFocusInWindow() always returns false. – Ionut Nicu Dec 06 '12 at 18:13
  • @lonutnicu so when you open the applet in your browser and press *a* nothing happens?...if you want jtextfield focused than call requestFocusInWindow on textfield – David Kroukamp Dec 06 '12 at 18:16
  • No, I want the applet to be focused, not the text field. I don't even want to have a text field. Indeed, when I open it from the browser and press 'a' nothing happens. If I run it with applet viewer and press 'a' it works. Just like in my example. – Ionut Nicu Dec 06 '12 at 18:20
  • Not sure what I can do further, tested on Windows 7 x64 Java7u9 and IE 8/Chrome and it works fine for me, so must be something else make sure all your versions of the applications you are using are up to date – David Kroukamp Dec 06 '12 at 18:22
  • I have Ubuntu 12.10 x86_64 here and tested on Chrome 23.0.1271.95 (Official Build 169798) and Firefox 17.0.1. It may be a platform specific problem. I will test tomorrow with a Windows VM and post the results. Thanks! – Ionut Nicu Dec 06 '12 at 18:52
  • I've tested on Windows XP and Windows 7 and both samples work ok. Even on Linux it works with the Sun JDK. I was using the OpenJDK icedtea7 plugin. So, I guess my problem was related to the icedtea java plugin rather than the code. – Ionut Nicu Dec 07 '12 at 14:40