在文本字段中恰好包含13个字符时触发按钮

时间:2010-12-11 19:28:28

标签: java swing

我有一个文本字段和一个搜索按钮。如果用户输入正好13个数字(条形码),那么我想自动触发搜索。

我在文本字段上有一个DocumentListener,并且正在处理insertUpdate方法以确定已输入13位数字。我可以直接在那一点调用搜索代码(它确实可以工作)但是虽然已经输入了第13个字符,但在搜索完成之前它实际上并没有显示在屏幕上。

我更愿意触发“搜索”按钮,尝试了两种方法:

DocumentListener dlBarcode = new DocumentAdaptor() {
    public void insertUpdate(DocumentEvent e) {
        String value = jtBarcode.getText();
        if (isBarcode(value)) {
            ActionEvent ae = new ActionEvent((Object)jbSearch,
                             ActionEvent.ACTION_PERFORMED, "");
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(ae);
        }
    }
};

第二种是使用:

jbSearch.dispatch(ae);

这两种方法似乎都不会导致触发jbSearch上的ActionListener。你能告诉我我做错了吗?

3 个答案:

答案 0 :(得分:3)

不要以编程方式尝试“单击”按钮。它没有被按下,所以为什么要试图欺骗你的代码以为它是?将动作与执行动作的动作分开是一个重要的原则。通过类比,想想你车上的点火。转动钥匙会触发点火。因此,如果我想设计一个远程汽车启动器,我是否会创建一个物理插入和转动钥匙的机械机器人,或者我的系统是否只是直接发出点火信号?

只需定义一种方法,将其称为performSearch或其他任何方法,并在按钮上设置ActionListener,并且DocumentListener每个方法都可以自行调用该方法。

一个注意事项:不要忘记使用您正在使用的文本控件实际注册文档监听器。

答案 1 :(得分:2)

  

我可以直接在该点调用搜索代码(并且确实有效)但是虽然已经输入了第13个字符,但在搜索完成之前,它实际上并未显示在屏幕上。

将调用包含在SwingUtilities.invokeLater()中的搜索代码中。这将把搜索放在Event Dispatch Thread的末尾,因此在搜索开始之前将更新文本字段。

DocumentListener dlBarcode = new DocumentAdaptor() {
    public void insertUpdate(DocumentEvent e) {
        String value = jtBarcode.getText();
        if (isBarcode(value)) {
            SwingUtilities.invokeLater(new Runnable()
            {
                public void run()
                {
                    invokeSearchMethod();
                }
            });
        }
    }
};

答案 2 :(得分:0)

camickr建议使用invokeLater奇怪的是没有用,因为第13个字符在搜索完成之前没有被绘制。 Mark建议使用SwingWorker做出评论。我的DocumentListener代码现在看起来像:

DocumentListener dlBarcode = new DocumentAdaptor() {
public void insertUpdate(DocumentEvent e) {
    String value = jtBarcode.getText();
    if (isBarcode(value)) {
        PerformSearch ps = new PerformSearch(value);
        ps.execute();
    }
}

我的PerformSearch看起来像:

class PerformSearch extends SwingWorker<Product, Void> {
private String key = null;
public PerformSearch(String key) {
    this.key = key;
}
@Override
protected Product doInBackground() throws Exception {
    return soap.findProduct(this.key);
}
protected void done() {
    Product p = null;
    try {
         p = get();
    } catch (InterruptedException e) {
    } catch (ExecutionException e) {
    }
    prod = p;
    if (prod != null) {
        ... populate text fields
    }
    else {
        ... not found dialog
    }
}

感谢您的帮助。非常感谢。