Java LostFocus和InputVerifier,以反向制表符顺序移动 [英] Java LostFocus and InputVerifier, moving in reverse-tab-order

查看:296
本文介绍了Java LostFocus和InputVerifier,以反向制表符顺序移动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个GUI应用程序,使用InputVerifier在产生焦点之前检查文本字段的内容。这一切都很正常。然而,昨天却发现了一个问题 - 这似乎是一个错误,但在任何地方我都找不到任何提及。在我报告这个错误之前,我想我会问:我在这里丢失了什么明显的东西?



情况:


  • 包含InputVerifier的一组文本字段。
  • 所有控件上的FocusLost和FocusGained的侦听器,所以我可以看到发生了什么。

  • 一个单独的线程使用DefaultKeyboardFocusManager来报告(每2秒)哪个控件有焦点。
  • 我将无效数据放在窗体中间的JTextField中,并试图离开控制。



如果我尝试使用鼠标移开此控件,或者使用tab键, 我不能。但是,如果我尝试以反向Tab键顺序移开控件,则使用Shift键-Tab 有时 FocusLost事件触发。如果发生这种情况,单独的线程报告没有控件有焦点,即getFocusOwner()返回null。



编辑:下面是一个显示问题的小示例程序。这个问题与额外的线程无关 - 线程只是使问题更加明显。如果存在竞争条件,则在Swing中的某处。



要查看问题,请转到第二个文本框并将其清空。控件应该保持焦点,除非你按shift-tab离开它。不像完整的应用程序,错误似乎在100%的时间里出现。在OpenJDK 6和Oracle Java 7下都是如此。



这是一个错误,而且在多个Java环境中都会发生。因此,我怀疑我失去了一些明显的东西。任何人?

  public class FocusBugDemo extends JFrame {
static JTextField txtOne = new JTextField(Ignore this control);
static JTextField txtTwo = new JTextField(Delete this text,then shift shift-tab);
static JLabel lblFocus = new JLabel();
static KeyboardFocusManager kfm = new DefaultKeyboardFocusManager();

public static void main(String [] args){
new FocusBugDemo();
Thread t = new Thread(){
@Override
public void run(){
while(true){
Component c = kfm.getFocusOwner();
String focusInfo =其他;
if(c == null){focusInfo =null;
} else if(c == txtOne){focusInfo =txtOne;
} else if(c == txtTwo){focusInfo =txtTwo;
}
lblFocus.setText(System.currentTimeMillis()+ - Focus owner+ focusInfo);
尝试{
Thread.sleep(1000);
} catch(InterruptedException e){
}
}
}
};
t.start();

$ b $ private FocusBugDemo(){
super(Focus bug demo);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300,100));
setLayout(new GridLayout(3,1));
NotEmpty validator = new NotEmpty();
txtOne.setInputVerifier(validator);
txtTwo.setInputVerifier(validator);
add(txtOne);
add(txtTwo);
add(lblFocus);
pack();
setVisible(true);

$ b private class NotEmpty extends InputVerifier {
@Override
public boolean verify(JComponent input){
JTextField txtField =(JTextField)input;
return(txtField.getText().length()> 0);




$ div class =h2_lin>解决方案 7167871 。


I have a GUI application that uses an InputVerifier to check the content of text fields before yielding the focus. This is all very normal. Yesterday, however, discovered a problem - it seems to be a bug, but I cannot find any mention of it anywhere. Before I report this as a bug, I thought I would ask: am I missing something obvious here?

Situation:

  • A set of text fields with InputVerifiers.
  • Listeners for FocusLost and FocusGained on all controls, so I can see what is happening.
  • A separate thread uses a DefaultKeyboardFocusManager to report (every 2 seconds) which control has the focus.
  • I place invalid data in a JTextField in the middle of the form, and try to leave the control.

If I try to move away from this control using the mouse, or using the tab-key, I cannot. The FocusLost event does not fire and the control properly retains the focus.

However, if I try to move away from the control in reverse tab order, using Shift-Tab, sometimes the FocusLost event fires. If this happens, the separate thread reports that no control has the focus, i.e., getFocusOwner() returns null.


Edit: below is a small sample program that shows the problem. The problem has nothing to do with the extra thread - the thread is just there to make the problem more obvious. If there is a race-condition, it is somewhere in Swing.

To see the problem, go to the second text box and empty it. The control should retain the focus, and does so unless you leave it by pressing shift-tab. Unlike the full application, the error seems to occur here 100% of the time. This is true both under OpenJDK 6 and under Oracle Java 7.

This is almost too obvious to be a bug, plus it happens in multiple Java environments. Hence, my suspicion that I am missing something obvious. Anyone?

public class FocusBugDemo extends JFrame {
    static JTextField txtOne = new JTextField("Ignore this control");
    static JTextField txtTwo = new JTextField("Delete this text, then press shift-tab");
    static JLabel lblFocus = new JLabel("");
    static KeyboardFocusManager kfm = new DefaultKeyboardFocusManager();

    public static void main(String[] args) {
        new FocusBugDemo();
        Thread t = new Thread() {
            @Override
            public void run() {
                while(true) {
                    Component c = kfm.getFocusOwner();
                    String focusInfo = "elsewhere";
                    if (c == null) {                        focusInfo = "null";
                    } else if (c == txtOne) {       focusInfo = "txtOne";
                    } else if (c == txtTwo) {       focusInfo = "txtTwo";
                    }
                    lblFocus.setText(System.currentTimeMillis() + " - Focus owner " + focusInfo);
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                    }
                }
            }
        };
        t.start();
    }

    private FocusBugDemo() {
        super("Focus bug demo");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(300,100));
        setLayout(new GridLayout(3,1));
        NotEmpty validator = new NotEmpty();
        txtOne.setInputVerifier(validator);
        txtTwo.setInputVerifier(validator);
        add(txtOne);
        add(txtTwo);
        add(lblFocus);
        pack();
        setVisible(true);
    }

    private class NotEmpty extends InputVerifier {
        @Override
        public boolean verify(JComponent input) {
            JTextField txtField = (JTextField) input;
            return (txtField.getText().length() > 0);
        }
    }
}

解决方案

Now reported to Oracle as bug 7167871.

这篇关于Java LostFocus和InputVerifier,以反向制表符顺序移动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆