【问题标题】:How to set my request focus event listener thread safe?如何设置我的请求焦点事件侦听器线程安全?
【发布时间】:2018-01-29 23:32:35
【问题描述】:

我正在使用焦点事件侦听器为所有 JTextComponents(JTextField、JTextArea ...)实现占位符解决方案,我的实现如下

public class PlaceHolderDecorator {

public static void decorate(JTextField field, String placeHoldingText) {
    field.setForeground(Color.GRAY);
    field.addFocusListener(new FocusListener() {
        @Override
        public void focusGained(FocusEvent e) {
            if (field.getText().equals(placeHoldingText)) {
                field.setText("");
                field.setForeground(Color.BLACK);
            }
        }

        @Override
        public void focusLost(FocusEvent e) {
            if (field.getText().isEmpty()) {
                field.setForeground(Color.GRAY);
                field.setText(placeHoldingText);
            }
        }
    });
}
public static void decorate(JTextField field, String placeHoldingText,Color placeHolderColor,Color textColor) {
    field.setForeground(placeHolderColor);
    field.addFocusListener(new FocusListener() {
        @Override
        public void focusGained(FocusEvent e) {
            if (field.getText().equals(placeHoldingText)) {
                field.setText("");
                field.setForeground(textColor);
            }
        }

        @Override
        public void focusLost(FocusEvent e) {
            if (field.getText().isEmpty()) {
                field.setForeground(placeHolderColor);
                field.setText(placeHoldingText);
            }
        }
    });
}

final public static int DATE_FIELD_P = 10;
final public static int PHONE_FIELD_P = 14;

public static void decorate(JFormattedTextField field,String placeHoldingText,Color placeHolderColor,Color textColor,int checkFieldProperty){
    field.setForeground(placeHolderColor);
    final JFormattedTextField.AbstractFormatterFactory formatterFactory = field.getFormatterFactory();
    field.setFormatterFactory(null);
    field.setText(placeHoldingText);
    field.addFocusListener(new FocusListener() {
        @Override
        public void focusGained(FocusEvent e) {
            if (field.getText().equals(placeHoldingText)) {
                field.setText("");
                field.setForeground(textColor);
                field.setFormatterFactory(formatterFactory);
            }
        }

        @Override
        public void focusLost(FocusEvent e) {
            if (field.getText().trim().length()!=checkFieldProperty ) {
                field.setFormatterFactory(null);
                field.setText("");
            }
            if (field.getText().isEmpty()) {
                field.setFormatterFactory(null);
                field.setForeground(placeHolderColor);
                field.setText(placeHoldingText);
            }
        }
    });
 }
}

要使用占位符工具,我会执行以下操作

    final Color writingColor = new Color(45, 45, 45);
    final Color holdingColor = new Color(127, 127, 127);

    PlaceHolderDecorator.decorate(jFTFDateDepot, "Date dépot du dossier", holdingColor, writingColor, PlaceHolderDecorator.DATE_FIELD_P);
    PlaceHolderDecorator.decorate(jtfNom, "Nom", holdingColor, writingColor);

这样,当焦点发生时,占位符就会显示出来,之后我需要为我的输入创建一个验证机制,所以我想像这样检查我的字段:

    public class RequiredFieldValidator {

        final private List<JTextComponent> components;
        private ErrorDialog dialog;

        public RequiredFieldValidator() {
            components = new ArrayList<>();
        }

        public void add(JTextComponent jTextComponent) {
            components.add(jTextComponent);
        }

        public boolean validate() {

            for (final JTextComponent component : components) {
                String placeHolder = component.getText();
                System.out.println("placeholder : " + placeHolder);

                component.requestFocus();
                if (component.getText().trim().isEmpty()) {
                    System.out.println("validation started");
                    dialog = new ErrorDialog(null, true);
                    dialog.showErrorDialog("Veuillez remplir le champs " + placeHolder + " obligatoir");
                    component.requestFocus();
                    return false;
                }

            }
            return true;
        }
    }

正如您在我的代码中看到的那样,我确实要求获得焦点,如果用户没有输入任何文本,则文本将为空,否则用户的输入将保留

我确实像这样使用这个字段验证器

我在初始化部分注册了我的必填字段

    fieldValidator = new RequiredFieldValidator();

    fieldValidator.add(jFTFDateDepot);
    fieldValidator.add(jFTFDateNaissance);
    fieldValidator.add(jFTFNumTel);
    fieldValidator.add(jtfLieuNaissance);
    fieldValidator.add(jtfNom);
    fieldValidator.add(jtfPrenom);

然后我在创建事件上触发验证过程。

我在这段代码中的问题是,在运行之前,我期待在创建事件上出现这个 LIKE 序列图

获取当前组件 >> requestFocus() >> fire place holding event >> 对组件的文本进行处理 >> 返回验证 >> 获取处理后的文本 >> if empty show alert >> if not loop to下一个组件

但令我惊讶的是,我在当前组件上的请求焦点侦听器稍后会在 swing 线程调度程序上触发

请问如何使这个线程安全,我需要在获取验证文本之前触发焦点侦听器。

【问题讨论】:

    标签: java multithreading swing focus jtextcomponent


    【解决方案1】:

    您不需要请求关注某个组件来检查该组件是否有文本。当您循环浏览所有文本字段以进行验证时,如果焦点不断移动到最后一个文本字段,用户将不会欣赏它。

    因此,使用您当前的方法,您真正需要的是一种查看文本字段中的文本是否为“占位符”值的方法。因此,也许您可​​以将“占位符”逻辑与验证逻辑结合起来,以便两种方法都可以访问占位符值。

    另一种方法是不将文本字段的文本设置为占位符值。然后验证逻辑可以检查文本字段是否为空。如需使用此方法的解决方案,请查看Text Prompt。它显示一个提示而不设置文本字段的文本。

    【讨论】:

    • 使用文本提示是满足我需求的更好解决方案。
    猜你喜欢
    • 1970-01-01
    • 2023-02-23
    • 2013-11-30
    • 1970-01-01
    • 1970-01-01
    • 2014-04-01
    • 2014-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多