【问题标题】:Trigger a button when exactly 13 characters in text field当文本字段中恰好有 13 个字符时触发按钮
【发布时间】:2011-05-24 01:00:04
【问题描述】:

我有一个文本字段和一个搜索按钮。如果用户准确输入 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 被触发。你能建议我做错了什么吗?

【问题讨论】:

    标签: java swing


    【解决方案1】:

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

    只需定义一个方法,将其命名为performSearch 或其他名称,然后让按钮上的ActionListenerDocumentListener 各自调用该方法。

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

    【讨论】:

      【解决方案2】:

      那时我可以直接调用搜索代码(它确实有效),但是虽然第 13 个字符已被输入,但直到搜索完成它才真正显示在屏幕上。

      将对搜索代码的调用封装在 SwingUtilities.invokeLater() 中。这会将搜索置于事件调度线程的末尾,因此文本字段将在搜索开始之前更新。

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

      【讨论】:

      • 我完全想念他这么说。这接近于真正的答案,但我个人建议使用 SwingWorker 代替在后台进行搜索,然后稍后对 UI 进行更新。
      • 感谢您的建议,我已经尝试使用 invokeLater 但第 13 个字符仍然只有在搜索完成后才会被绘制。从 invokeLater 的文档中,我原以为 Event Dispatch 线程会在调用搜索之前完成对文本字段的绘制,但似乎没有。接下来我将尝试使用 SwingWorker。
      【解决方案3】:

      camickr 关于使用 invokeLater 的建议奇怪地不起作用,因为在搜索完成之前没有绘制第 13 个字符。马克建议使用 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
          }
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-27
        • 2023-04-06
        • 1970-01-01
        • 1970-01-01
        • 2019-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多