【问题标题】:JApplet can't get focus when run from browser从浏览器运行时 JApplet 无法获得焦点
【发布时间】:2012-12-06 15:50:21
【问题描述】:

我有一些简单的代码,我试图将键盘事件输入到 Java 小程序中。使用 appletviewer 运行代码时运行良好,但是当我从浏览器加载它时(尝试了 Chrome 和 Firefox),JApplet 不会关注点击。

用 Applet 而不是 JApplet 尝试完全相同的代码没有问题。

这是我的代码:

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);
    }
}

【问题讨论】:

    标签: java swing focus japplet appletviewer


    【解决方案1】:
    • 应在 Event Dispatch Thread 上创建小程序,方法是将代码包装在 SwingUtilities.invokeAndWait() 块中重写的 init() 方法中

    • 不要将KeyListener 用于JApplet/Swing 组件使用KeyBindings

    • 在创建所有内容并将所有内容添加到容器后,在 JApplet 上调用 requestFocusInWindow()(虽然这对于键绑定不是必需的)

    • 也不要在paint() 中绘图,而是将JPanel 添加到容器并覆盖paintComponent(..)

    这是一个小例子,它是一个简单的JLabel,带有一个虚拟标签和一个添加到容器的文本字段,KeyBinding 仅用于 A;所以当 A 被按下时,它将被添加到JLabel 文本中:

    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,感谢您的建议,但您的示例显示的行为与我的相同。从浏览器运行时,除非您单击 JTextField,否则小程序不会获得焦点。从 appletviewer 运行时,无需单击文本字段即可获得焦点。我也尝试使用 KeyBinding API 而不是 KeyEventListener,但问题是焦点,requestFocusInWindow() 总是返回 false。
    • @lonutnicu 所以当您在浏览器中打开小程序并按 a 时,什么都没有发生?...如果您希望 jtextfield 聚焦而不是在 textfield 上调用 requestFocusInWindow
    • 不,我希望小程序获得焦点,而不是文本字段。我什至不想有一个文本字段。确实,当我从浏览器打开它并按“a”时,什么也没有发生。如果我用小程序查看器运行它并按“a”它可以工作。就像我的例子一样。
    • 不确定我还能做些什么,在 Windows 7 x64 Java7u9 和 IE 8/Chrome 上进行了测试,它对我来说工作正常,所以一定要确保你正在使用的应用程序的所有版本是最新的
    • 我这里有 Ubuntu 12.10 x86_64 并在 Chrome 23.0.1271.95(官方版本 169798)和 Firefox 17.0.1 上进行了测试。这可能是平台特定的问题。我明天将使用 Windows VM 进行测试并发布结果。谢谢!
    猜你喜欢
    • 2012-06-16
    • 2018-04-02
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-04
    相关资源
    最近更新 更多