Статьи

Как быстро добавить код проверки в пользовательский интерфейс Swing

Simple Validation API, доступный на Kenai , представляет собой простую библиотеку для быстрого добавления кода проверки в пользовательские интерфейсы Swing. Он обрабатывает проверку пользовательского ввода, когда пользователь изменяет значение компонента, показывая сообщения об ошибках и декорируя компоненты, чтобы указать, какой компонент является источником проблемы. Он содержит большое количество встроенных валидаторов для обработки наиболее распространенных ситуаций, таких как проверка номеров, адресов электронной почты, URL-адресов и т. Д.

Основная цель состоит в том, чтобы упростить модификацию кода проверки на существующих интерфейсах без необходимости что-либо переписывать или добавлять более нескольких строк кода.

Очень часто данные, которые вводит пользователь, должны быть проверены — проверены на законность. Пользовательский интерфейс (UI) должен убедиться в том, что введенный пользователем текст является законным; если это не так, пользователю следует показать, в чем проблема, и, возможно, некоторые части пользовательского интерфейса должны быть отключены.

Например, когда отображается диалоговое окно с просьбой ввести что-то пользователю, если есть проблема с тем, что он напечатал, кнопка ОК в диалоговом окне должна быть отключена, и пользователю должно быть показано сообщение, указывающее, в чем заключается проблема.

Библиотека состоит из нескольких простых понятий:

  • Валидаторы — это интерфейс для вещей, которые проверяют объекты некоторого типа, обычно String. Валидатор производит
  • Проблемы — информация для показа пользователю. Проблемы имеют три степени серьезности : FATAL, WARNING и INFO.
  • ValidationGroup — группа компонентов, которые представлены вместе, могут влиять друг на друга. Обычно для каждой панели существует одна группа ValidationGroup. Изменение одного компонента в пользовательском интерфейсе может инициировать повторную проверку содержимого других компонентов.
  • ValidationUI — пользовательский интерфейс, который может отображать проблему пользователю. Для этого вы можете использовать встроенную панель ValidationPanel или реализовать ее через существующий интерфейс, добавив два метода. ValidationGroup.createProblemLabel () может создать метку, которая показывает проблемы с соответствующим цветом и значками.
  • Converter — Validator, который не выполняет собственную проверку, но принимает тип объекта, который создает пользовательский интерфейс (например, javax.swing.text.Document), преобразует его в тип, более подходящий для проверки (например, java.lang.String), и вызывает другой валидатор против преобразованного объекта
  • Валидаторы — перечисление часто используемых встроенных валидаторов, которые должны обрабатывать наиболее распространенные ситуации валидации пользовательского интерфейса.

Валидаторы могут быть объединены в цепочку в порядке приоритета — в каждом компоненте будет один Валидатор, но этот валидатор может фактически объединить несколько. Это делается довольно просто, например

Validator<String> v = Validators.merge(validator1, validator2, validator3)

Библиотека содержит предварительно созданные валидаторы для большинства распространенных случаев в пользовательских интерфейсах, поэтому большинству пользовательских интерфейсов не потребуется собственный собственный код валидации. Например, чтобы подтвердить URL, вы просто позвоните

validationGroup.add (theTextField,        Validators.REQUIRE_NON_EMPTY_STRING,        Validators.NO_WHITESPACE,        Validators.VALID_URL);

Если вы хотите добавить свой собственный валидатор, это будет так же просто, как

validationGroup.add (theTextField,        Validators.REQUIRE_NON_EMPTY_STRING,        Validators.NO_WHITESPACE,        new MyCustomValidator());

Загрузка библиотеки простой проверки

JAR-файл, javadoc, исходный код и модуль библиотеки NetBeans доступны в разделе загрузок.

Скриншоты

Далее приведены модули Java Card NetBeans, в которых показаны ПРЕДУПРЕЖДЕНИЯ и ОШИБКИ. Для добавления проверки в этот интерфейс потребовалось совсем немного кода.

Что содержит эта библиотека

SimpleValidation разработан с учетом следующих целей:

  • Минимальные концептуальные накладные расходы
  • Легкость принятия

    • Часто валидация может быть добавлена ​​к существующему пользовательскому интерфейсу с помощью всего лишь нескольких строк кода.
  • Предоставьте полезные предварительно созданные валидаторы для общих случаев в пользовательских интерфейсах Swing, поэтому большинству пользовательских интерфейсов не нужно включать рукописный код валидации, такой как

    • Непустая строка
    • Неотрицательное число
    • Идентификатор Java (т.е. не ключевое слово)
    • чисел
    • Целые
    • шестнадцатеричный
    • URL-адреса (включая проверку недопустимых кодировок и некондиционных идентификаторов серверов и номеров портов, чего не делает java.net.URL)
    • Юридические имена файлов
    • Нет пробела в строке
    • Имя файла должно представлять существующий файл
    • Имя файла должно представлять несуществующий файл
    • Файл, который является каталогом
    • Файл, который не является каталогом
    • Имя интернет-хоста
    • Адрес электронной почты в интернете
    • Имя строковой кодировки
    • Диапазон номеров
    • Минимальная / максимальная длина ввода
    • Соответствие регулярному выражению
    • Проверка номера для конкретного региона
    • IP-адреса
    • Строка, кодируемая в определенной кодировке символов
    • Имена кодировки символов
    • Имя пакета Java
    • Строка не может начинаться с цифры
    • Строка соответствует определенному регулярному выражению

Кроме того, существуют встроенные валидаторы, которые разбивают строку на компоненты и затем запускают какой-то другой валидатор для каждого компонента, а также валидаторы, которые обертывают валидатор ввода и сначала вызывают String.trim () во входной строке.

Чем эта библиотека не является

Эта библиотека не является универсальной средой валидации для всего и вся (например, специальные Java-бины и т. Д.) И не предназначена для инкапсуляции теоретически полного представления валидации или строки-> ad-hoc-object-> преобразование строк. Такие библиотеки уже существуют .

Следовательно, хотя он может содержать такие понятия, как ProblemSource, который расширяет MessageSource и т. Д., Он этого не делает; тяжести могут быть представлены как плавающие от 0,0F до 1,0F; вместо этого есть три уровня серьезности, которые являются адекватными для решения наиболее распространенных случаев. Одна из целей разработки — минимизировать концептуальную площадь поверхности — то есть любая абстракция, которая не имеет немедленной полезности, не должна быть тем, что люди видят в списке классов в javadoc.

Эта библиотека предназначена для упрощения некоторых распространенных случаев в пользовательских интерфейсах (например, не позволяя пользователю продолжить работу, если поле пустое или, например, содержит неверный URL), а не спасать мир.

Простой пример

Ниже приведен весь код, необходимый для проверки URL в диалоговом окне.

  public static void main(String[] args) {    //This is our actual UI    JPanel inner = new JPanel();    JLabel lbl = new JLabel("Enter a URL");    JTextField f = new JTextField();    f.setColumns(40);    //Setting the component name is important - it is used in    //error messages    f.setName("URL");    inner.add(lbl);    inner.add(f);    //Create a ValidationPanel - this is a panel that will show    //any problem with the input at the bottom with an icon    ValidationPanel panel = new ValidationPanel();    panel.setInnerComponent(inner);    ValidationGroup group = panel.getValidationGroup();    //This is all we do to validate the URL:    group.add(f, Validators.REQUIRE_NON_EMPTY_STRING,            Validators.NO_WHITESPACE,            Validators.URL_MUST_BE_VALID);    //Convenience method to show a simple dialog    if (panel.showOkCancelDialog("URL")) {      System.out.println("User clicked OK.  URL is " + f.getText());      System.exit(0);    } else {      System.err.println("User clicked cancel.");      System.exit(1);    }  }

Содействующие валидаторы

Мы приветствуем вклад новых Валидаторов для обработки дополнительных распространенных случаев. Есть три простых правила для взносов:

  • Предоставленные валидаторы не должны требовать, чтобы эта библиотека зависела от классов, отличных от JDK

    • Для очень часто используемых библиотек, которые добавляют несколько типов, они могут быть размещены здесь, но должны находиться в своем собственном файле JAR
  • Как правило, не раскрывайте тип реализации вашего Validator; скорее добавьте константу или фабричный метод в org.netbeans.validation.api.builtin.Validators. Валидаторы без сохранения состояния должны использовать константу enum; валидаторы с сохранением состояния (те, которым передаются некоторые параметры при создании) должны получить фабричный метод.
  • Добавленные валидаторы должны иметь модульные тесты

Другие общие вопросы

Почему имя пакета org.netbeans. *?

Эта библиотека была создана для добавления проверки в компоненты пользовательского интерфейса в NetBeans, которые не имели и нуждались в этом. Это было полезно и достаточно обобщенно, чтобы сделать его отдельным проектом.

Я добавил валидатор (число, URL и т. Д.), Но он говорит, что с пустой строкой все в порядке. Что случилось?

Каждый валидатор делает только одну вещь . Они могут быть объединены в цепочку с помощью Validators.merge () и вызываются по порядку, пока не обнаружится фатальная проблема. Все, что исключает пустую строку, должно иметь Validators.REQUIRE_NON_EMPTY_STRING в качестве первого валидатора в цепочке. Валидатор обычно проверяет некоторые входные данные; более значимая обратная связь с пользователем может быть достигнута путем их объединения в цепочку — «URL не может быть пустым» — это более приятное сообщение, чем «» не является действительным URL ». Валидаторы, ожидающие, что некоторые входные данные могут молчать, когда их нет — для этого и нужен Validators.REQUIRE_NON_EMPTY_STRING.

Что такое NbBundle (или Утилиты, Исключения и т. Д.)?

NbBundle — это класс, который NetBeans использует внутри для обработки локализованных строк. Он лучше справляется с кэшированием и управлением памятью, чем любой из стандартных JDK-способов обработки пакетов ресурсов и декодирования встроенных форматированных строк.

Подпроект nbstubs содержит рабочие версии всех таких классов; они автоматически включаются в дистрибутив JAR. Вам не нужны какие-либо части NetBeans для использования этой библиотеки; Поскольку библиотека изначально была разработана для работы внутри NetBeans, она использует их внутри.

Как использовать эту библиотеку из модуля NetBeans?

В настоящее время вам необходимо собрать его (не вызывая целевой выпуск Ant, чтобы он связывался с реальными классами org.openide.util, а не с версиями-заглушками), и создать для него модуль-оболочку библиотеки .

Что касается I18N — имена компонентов обычно не локализуются!

Есть два способа решить это:

  • Установите имя компонента в локализованную строку
  • Вместо этого используйте putClientProperty (ValidationListener.CLIENT_PROP_NAME, theLocalizedName), если имя компонента уже используется для каких-либо других целей.

Что такое модуль NetBeans?

Это плагин NetBeans, который добавляет библиотеку SimpleValidation в список встроенных библиотек, которые вы можете использовать в своем проекте, и включает в себя javadoc и исходный код для отладки.

UML-диаграммы

Некоторые UML-диаграммы доступны на странице UML

мозговая атака

Этот проект совсем не близок к версии 1.0 — добавьте свои идеи на страницу мозгового штурма

Расширенные возможности

Здесь стоит упомянуть несколько особенностей:

Группы проверки цепочки

ValidationGroup имеет методы addValidationGroup () и RemoveValidationGroup. Они полезны, когда вы создаете панель, которая имеет собственную группу ValidationGroup, внутри другой, которая также может иметь некоторый пользовательский интерфейс для проверки. Например, представление основной детали в диалоговом окне со списком элементов, каждый из которых имеет настройщик, вероятно, будет иметь группу ValidationGroup для всего, что может быть введено в родительской форме; настройщик будет иметь свой собственный. Просто добавьте ValidationGroup дочернего компонента в группу проверки родителя. У вас есть возможность отключить пользовательский интерфейс ребенка (если, скажем, это приведет к тому, что в вашем пользовательском интерфейсе появятся две метки ошибок, показывающие одно и то же).

Несколько ValidationUIs

Вы можете добавить несколько групп валидации в группу валидации, просто вызвав addUI (). Это полезно, например, если у вас есть некоторый базовый код, который показывает все диалоговые окна OK / отмена в вашем приложении — если он реализует ValidationUI, вы можете управлять включенным состоянием кнопки OK. Но вы также, вероятно, хотите показать обратную связь (для этого полезно ValidationGroup.createProblemLabel ()).

Внесение программных изменений в проверенные компоненты

Иногда вы можете установить значения в нескольких компонентах программно. Например, на снимках экрана выше, всякий раз, когда значение порта Http изменяется, URL-адреса внизу должны обновляться, если они еще не редактировались вручную.

Когда вы делаете программные изменения, вы не хотите, чтобы это вызывало бурю проверки — ваш код знает, что он делает. Поэтому просто оберните любой подобный код в Runnable и передайте его ValidationGroup.modifyComponents (). Это отключит всю проверку (обратите внимание, что modifyComponents () является реентерабельным, поэтому ваш runnable может инициировать другой вызов modifyComponents () без проблем — проверка возобновится, когда существует последний runnable).

Резьбонарезной

Все методы ValidationGroup должны вызываться в потоке событий AWT. Это подтверждается утверждениями. Никогда, никогда не безопасно изменять или даже создавать компонент Swing в любом потоке, кроме потока событий. Исключения из этого правила в стандартном Swing можно считать с одной стороны. Вся работа с пользовательским интерфейсом должна происходить в потоке событий, точка.

javax.swing.text.Document является потокобезопасным для изменений. Если ValidationListener получает DocumentEvent в другом потоке, он запланирует проверку для запуска в потоке событий с помощью EventQueue.invokeLater (). Проверка всегда происходит в потоке событий.

Управление жизненным циклом и памятью

ValidationGroup содержит ссылки на компоненты пользовательского интерфейса, добавленные к нему. Лучший способ избежать утечек памяти — убедиться, что для каждой панели существует одна группа ValidationGroup, и на нее не ссылается ничего, кроме этой панели. Таким образом, группа проверки будет существовать только до тех пор, пока панель существует, и ее можно собирать, когда панель и ее компоненты существуют.

В случае, когда группы проверки составлены вместе, обязательно удалите любую дочернюю группу проверки из ее родителя, если связанный с дочерним интерфейсом пользовательский интерфейс больше не используется.

Производительность

Валидация может выполняться в любое время, в частности, поскольку валидаторы входят в группы, связанные с несколькими компонентами, ваш валидатор может быть запущен из-за изменения совершенно другого компонента. Алгоритм проверки работает следующим образом:

  • Когда компонент изменяется (в соответствии с выбранной вами ValidationStrategy), запускаются его валидаторы.
  • Если средство проверки этого компонента создает проблему Severity.FATAL, остановите и обновите пользовательский интерфейс с этой ошибкой.

    • Если нет, запускайте проверку всех компонентов в группе, пока не будет обнаружена проблема серьезности. FATAL.

      • Если нет проблем, очистите проблему в пользовательском интерфейсе
      • Если это нефатальная проблема, обновите пользовательский интерфейс с самой ранней проблемой с самой высокой серьезностью (FATAL, WARNING, INFO)

Итак, вкратце, проверка должна быть быстрой — если для проверки требуется сетевое соединение или интенсивный файловый ввод-вывод, эта библиотека является неправильным решением.

На странице мозгового штурма есть несколько идей по добавлению поддержки асинхронной проверки в будущем.

С http://kenai.com/projects/simplevalidation/pages/Home