2

有一个文本字段,当失去焦点时,它将验证输入,如果未通过,则打印出错误消息(简单来说这里只有一个空检查)。文本字段旁边有一个按钮,单击它会打印出文本。

正如我所尝试的,当输入一些文本然后单击按钮时,它将触发文本字段的焦点丢失事件和按钮事件。换句话说,它将首先进行验证,然后打印出输入文本。

我的问题来了,如果验证未通过,防止打印出文本的好方法是什么?或者如果验证未通过,有没有办法“忽略”按钮上的点击事件?

我尝试使用指示验证结果的布尔标志并在执行按钮操作时检查标志,但我认为这不是一个好方法。我知道 Swing 中有一个事件调度程序线程处理事件,我可以从这里取消事件吗?

下面是一段解释问题的代码:

public class SimpleDemo
{
    public static void main(String[] args)
    {
        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel content = new JPanel(new FlowLayout());
        frame.setContentPane(content);

        final JTextField textField = new JTextField(10);
        textField.addFocusListener(new FocusAdapter()
        {
             @Override
             public void focusLost(FocusEvent e)
             {
                 String text = textField.getText();
                 // do some validation here, if not validated 
                 // do not trigger the event on button.
                 if ("".equals(text))
                 {
                     System.out.print("please input a text!");
                 }
             }
        });
        content.add(textField);

        JButton button = new JButton("Print Text");
        button.addActionListener(new ActionListener()
        {
            @Override
            public void actionPerformed(ActionEvent e)
            {
                // action performed for button
                String text = textField.getText();
                System.out.println(text);
            }
        });
        content.add(button);

        frame.setVisible(true);
        frame.pack();
    }
}
4

3 回答 3

1

我在处理应用程序时遇到了类似的问题。我像下面这样解决了我创建了一个抽象类ApplicationFrame,应用程序中的每个框架都扩展了它

public abstract class ApplicationFrame extends JFrame implements ActionListener {
    @Override
    final public void actionPerformed(ActionEvent event) {
        if(validateInput()){
             performAction(event);
        }
    }

    /*
    * Sub class should override this method to receive any action
    */
    protected void performAction(ActionEvent event) {};

    /*
     * Sub class should override this method to perform validation
    */
    abstract protected boolean validateInput();
}

现在,所有框架都将扩展此基础框架,如下所示:

public class Frame1 extends ApplicationFrame{
    @Override
    protected void performAction(ActionEvent event) {
        // perform action
    }
    @Override
    protected boolean validateInput() {
        // return true or false depending upon the validation results
    }
    // if you want to add Action Listener, you need to add like this:
    btnSomeButton.addActionListener(this);
}

如果需要处理 Focus 事件,可以 makeApplicationFrame或 base frame 实现FocusListener。这是我解决问题的自定义实现,希望对您有所帮助。

于 2013-03-28T09:12:17.457 回答
0

让 ui 与用户交流总是有意义的。因此,当用户未输入任何内容时,您可以将“请输入文本”显示为 textField 的默认文本。这是此类自定义文本字段的代码:

public class TextFieldWithDefaultText extends JTextField implements FocusListener{

private final String hint;

public TextFieldWithDefaultText (String $text)
{
    super($text);
    this.hint = $text;
    addFocusListener(this);
}

@Override
public void focusGained (FocusEvent $e)
{
    if (this.getText().isEmpty())
    {
        super.setText("");
    }
}

@Override
public void focusLost (FocusEvent $e)
{
    if (this.getText().isEmpty())
    {
        super.setText(hint);
    }
}

@Override
public String getText ()
{
    String typed = super.getText();
    return typed.equals(hint) ? "" : typed;
}

}

为您的按钮编写 actionListerner,如下所示:

JButton button = new JButton("Print Text");
    button.addActionListener(new ActionListener()
    {
        @Override
        public void actionPerformed(ActionEvent e)
        {
            if(!textField.getText().isEmpty())
                System.out.println(textField.getText());
        }
    });

你的 textField 实现应该是:

final TextFieldWithDefaultText textField = new TextFieldWithDefaultText ("please input a text");

希望这可以帮助 :)

于 2013-03-28T11:23:26.413 回答
0
  • 在启动时禁用按钮
  • 失去焦点后,仅在输入通过验证时验证文本和启用按钮。
  • 开始文本更改时,禁用按钮
于 2013-03-28T09:16:35.277 回答