Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: GUI и Java FX приложения > Вопросы по JGoodies


Автор: ShkVal 7.10.2005, 17:12
Подскажите пожалуйста.
Мне надо отвалидировать некоторую форму. Там есть обязательные поля для заполнения, нужно укозать каким-то образом, что поле обязательное. Это поле должно быть определённого формата. Как узнать, что пользователь вводит не правильное значение (не того формата, что нужно). Нужно подсветить поле с неправильными данными и вывести подсказку какой должен быть формат.
И потом при сохранении формы как узнать, что в полях некоректные данные или не все обязательные поля заполнены. Может кто подскажет как это сделать или выложит небольшой понятный пример. Зарание спасибо!

Автор: ShkVal 12.10.2005, 09:45
Подскажите, что хоть надо создать (какие классы от каких должны наследоваться) и для чего каждый класс нужен.

Автор: carper 12.10.2005, 10:51
ShkVal
Господи! Я смотрю Вы уже неделю мучаетесь. smile
Просто тут очень неконкретный и, одновременно, слишком простой для гуру вопрос.

Давайте тогда я попробую помочь.

Забыл добавить: smile
Точнее, просто поддержу тему, т.к. помощи от меня маловато будет, но хоть будет понятно, что кто-то читает тему. Так, что извините если что.

Прежде всего я помню, что в теме прозвучало про JGoodies, а не просто так. Поскольку я в этом не силен, то и молчал себе в тряпочку. Только зашел на http://www.jgoodies.com и почитал.
Но не понятно зачем это нужно вообще? Зачем покупать платный фрэймворк, когда подавляющее большинство возможностей легко реализуется самостоятельно?
Зачем привязываться к стороннему разработчику, да еще за денежку?
Может лучше обойтись стандартными средствами?
Это и быстрей будет и полный контроль в ваших руках, а не стороннего дяди.


Смотрите как чудненько все получается: smile


1. Для указания того, что поле обязательное, следует указать, что оно обязательное. smile
Например, поставить звездочки у таких полей и дать внизу сноску. Можно это сообщить внизу поля мелким шрифтом. Можно сделать выделение рамочкой, цветом, шрифтом...
Можно не выпускать пользователя из поля (см. тут же на форуме, как работать с фокусом ввода - там вполне конкретный пример) до тех пор пока это поле не будет заполнено, а при попытке выхода из такого поля выдавать диалог с требованием заполнения и нужное пояснение.
Кстати, "не выпускать" - это плохая практика, я рекомендую выпускать, но не давать заполнять другие поля, если не заполнено очередное обязательное поле.

2. Если нужно поле определенного формата, то и задавайте этот формат, например, с помощью
JFormattedTextField либо с использованием паттернов.

3. Если при сохранении формы нужна доп. валидация, то и делайте ее. В чем тут-то вопрос?
Считываем поля, смотрим что введено, сверяемся с бизнес-правилом и соответственно реагируем.

Да, а что за загадочное "сохранение формы"? Форму-то зачем сохранять?
Что-то мне подсказывает, что имелось в виду сохранение данных, а саму форму, на всякий случай, можно сохранить с помощью механизма сериализации. smile


4. Если нужна изощренная проверка во время ввода, то рекомендую переопределить соотв. модель для текстового компонента (тут в форуме есть пример, см. JTextField, с указанием "какие классы от чего наследовать" smile ).

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

6. Если хочется создать "универсальный" валидатор на все случаи жизни, то не советую. smile


P.S. Еще раз извините, наверное все это Вы без меня знаете и в сто раз больше можете сами рассказать.
Просто действительно непонятно стремление пользовать что-то постороннее от небольшой фирмы без КРАЙНЕЙ нужды. Я уже много раз обжигался на VCL компонентах, когда работал на Delphi.

Автор: ShkVal 12.10.2005, 11:22
carper, спасибо. Я мучаюсь только 3 день, так как поставили более приоритетную задачу. А c JGoodies пришлось разбираться потому, что начальник типа умный сам не шарит ни в чём, нашёл в инете как-то этот JGoodies и сказал, чтобы было на нём вся валидация и ничего не хотит слушать.
И если кто поможет разобраться буду благодарен. Мне тяжеловато ещё разобраться т.к. очень плохо знаю английский. Да и на Java программирую когда подкидывают проекты для неё.

Автор: ShkVal 12.10.2005, 11:50
И ещё вопрос, что такое binding в JGoodies

Автор: batigoal 12.10.2005, 12:00
Обычно "binding" - это привязка чего-то к чему-то. Например, в IntelliJ Idea, binding - это привязка элемента интерфейса к какому-нибудь полю класса. Наверное, здесь тоже что-то подобное.

Автор: carper 12.10.2005, 14:59
ShkVal

Цитата

И если кто поможет разобраться буду благодарен. Мне тяжеловато ещё разобраться т.к. очень плохо знаю английский.


Ok. Есть исходники и описание для JGoodies?
При наличии и того и другого, могу попробовать помочь, хотя бы посмотреть куда рыть, с английским особых проблем нет. smile
Только с документацией, без исходников, сидеть лениво , а ставить себе это чудо желания нет.

Автор: ShkVal 12.10.2005, 19:17
Кое что есть тут http://www.jgoodies.com/articles/validation.pdf
Исходники документация и нужные либы можно взять отсюда http://www.jgoodies.com/downloads/libraries.html щёлкнув по ссылке JGoodies Validation

Автор: carper 13.10.2005, 10:55
ShkVal
Ну, так тут вроде бы все построено на обычной надстройке над SWING с переделанной моделью, рядом интерфейсов и классов реализующих эти интерфейсы по-умолчанию (просто для облегчения жизни). Также есть классы, например, ValidationComponentUtils, которые позволяют задать поведение конкретного компонента при проверке.
Все вполне разумно и вроде как логично.

Я бы начал с чтения описания интерфейса ValidationResultModel, а также класса реализующего его методы по-умолчанию - DefaultValidationResultModel.

Насколько я понял, класс, отвечающий за валидацию, неважно одного поля или нескольких ( я так понимаю, что удобнее - одно поле = один класс-валидатор) должен реализовать интерфейс
ValidationCapable, который, в свою очередь, описывает метод public ValidationResult validate() - Этакий усеченный по самое немогу вариант интерфейса DefaultValidationResultModel.

В этом методе следует проверять конкретные величины в поле, в чем может помочь клас Class ValidationUtils со своими статическими методами, использовать его методы совсем не обязательно, но очень полезно, т.к. иначе придется самому реализовать проверки, которые тут уже и так есть во множестве.

Для более тонкого анализа, можно дополнительно переопределять еще ряд методов PropertyValidationSupport, например, слушатель.

Назначение же своей модели в данном фреймворке ясно видно в классе-примере ExampleComponentFactory - именно здесь и есть то место, где обычный swing компонент приобретает дополнительную функциональность, а именно свою модель, которой потом можно управлять, например с помощью ValidationComponentUtils.
Например: ValidationComponentUtils.setMandatory(mandatoryOrderNoField, true);
ValidationComponentUtils.setMessageKey(mandatoryOrderNoField, "Order.Order No");

См. раздел создания и инициализации компонент, обратите внимание, что используется свой класс-фабрика (это не стандартный класс, а просто класс-пример, который присобачивает модель к полю, пример этой самой модели см. OrderModel.java), а также на то, что можно смешивать обычные компоненты и компоненты с переопределенной моделью. По секрету - для вас это означает возможность удовлетворить шефа малой кровью smile .

В общем, где-то так.
Довольно гибкий интерфейс, к тому же, если я правильно понял, то с данным framework идут исходники, т.е. несложно поменять что-то и в самой модели, если чего не устроит.

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

Если надо перевести конкретный фрагмент документации (в разумных размерах) you are welcome. smile

P.S. Все вышенаписанное предполагает, что у Вас уже скачано то, что Вы рекомендовали скачать мне иначе будут проблемы с названиями классов. smile

Автор: ShkVal 13.10.2005, 11:59
carper всё мне это было понятно у меня проблемы с binding. Не могу ещё понять зачем в com.jgoodies.validation.tutorial.shared.OrderValidator метод validate().
PropertyValidationSupport support =
new PropertyValidationSupport(order, "Order");
передавать order

Автор: carper 13.10.2005, 12:32
ShkVal
Этот конструктор содает экземпляр класса PropertyValidationSupport для данного объекта валидации(проверки) и его роли. При этом уровень безопасности по-умолчанию=Severity.WARNING.

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

Таким образом, order - это просто экземпляр класса Order, к которому, что вполне естественно, и привязываются всякие там сообщения валидатора (см. private final Order order;).



Цитата

у меня проблемы с binding


В чем конкретно?
Мне кажется, что задача разбивается на 2 больших этапа, сначала обычный SWING создает свой компонент, потом его надо передать в класс (свой собственный), который назначит ему модель от нашего framework + назначит ему наш же класс-валидатор, ответственный за проверку вводимого значения, т.к. модель понятия не имеет, что из себя конкретно представляет наш SWING объект и как именно его захочется проверять (правда зато дает класс, который проверяет самые употребительные случаи).

Автор: ShkVal 13.10.2005, 15:59
carper, непонятно каким образом вызываются сетеры в com.jgoodies.validation.tutorial.shared.Order

Спасибо за помощь и затраченное время. Буду благодарен если найдёшь ответ smile

И ещё не понятно всё таки зачем тут Order был нужен, так тоже всё работает
PropertyValidationSupport support =
new PropertyValidationSupport(new Object(), "Order");

Автор: carper 13.10.2005, 17:34
ShkVal
Основной конструктор выглядит так:
Код

/**
     * Создает экземпляр  PropertyValidationSupport для данного конкретного
     * объекта валидации и его роли
     * @param defaultResult    Не обязательный параметр ValidationResult, который 
     * используется чтобы добавить ValidationMessage к
     * @param defaultSeverity   Не обязательный параметр Severity, используемый 
    *  для создания сообщения когда не задано никакого severity (ограничения)
     * @param target    Проверяемый объект (Замедьте – это обязательное поле)
     * @param role     Если буквально, то роль объекта валидации во внешнем 
     * контексте. Фиг его знает, что это такое.
     * ……………………………………..
     */
    public PropertyValidationSupport(ValidationResult defaultResult, Severity defaultSeverity, Object target, String role) {
       ………………….
        this.defaultResult = defaultResult;
        this.defaultSeverity = defaultSeverity;

        //Нас интересует эта строка:
        this.target = target;

        this.role   = role;
    }



Эта строка всплывает в

Код

public PropertyValidationMessage create(Severity severity, String property, String text) {
        return new PropertyValidationMessage(severity, text, target, role, property);
    }


Смотрим дальше:
Код

public PropertyValidationMessage(Severity severity, String text, Object target, String role, String property) {
        super(text, severity);
        if (target == null)
            throw new NullPointerException("The target must not be null.");
        if (role == null)
            throw new NullPointerException("The role must not be null.");
        if (property == null)
            throw new NullPointerException("The property must not be null.");
        
        this.target   = target;
        this.role     = role;
        this.property = property;
    }


Таким образом, ты умудряешься создать ненулевой объект, поэтому ничего и не ругается, но смысла в этом действе нет никакого.
Хотя бы из-за того, что при этом бог его знает как потом работает функция
Код

/**
     * Возвращает объект валидации, который содержит свойство валидации. Что за 
     * свойство, опять же кто его знает.  Я в свойства лезть не стал. :)
     */
    public Object target() {
        return target;
    }


Можно, конечно, и дальше полазить по иерархии классов, но оно тебе надо?
В общем-то прозрачно говориться, что наш объект служит в основном для того, чтобы мы могли всегда получить источник, который выдал данное сообщение. Если не хотим, то, наверное, и не заметим, что мы определили объект неверно. smile


Цитата

непонятно каким образом вызываются сетеры


Не понял.
Типа public void setDeliveryDate(Date newDate) ?
В чем тут проблема?
Нет, тут что-то не так, наверное, я все же не понял.
Можно поподробнее изложить, что непонятно?

Автор: ShkVal 13.10.2005, 18:40
Что нужно сделать, чтобы вызвался например метод setOrderNo(). Явно он не вызывается. Так кто его вызывает. Кто заполняет значениями поля модели?

Автор: carper 14.10.2005, 09:17
ShkVal
Как это не вызывается?
А, чтоже тогда такое (validationOrderEditor) :
Код

// Synchronizing Model and View - Т.е. как раз, когда нужна стыковка между моделью 
//и представлением он и вызывается.
 ...................
  private void updateModel() {
       //Т.е. получили текст, который мы ввели в поле, например, с клавиатуры, или из буфера
       //и теперь хотим обновить данные модели. Для ввода самого текста нам использовать метод
       //setOrderNo совсем не обязательно.
        getOrder().setOrderNo(orderNoField.getText());
  ....................


updateModel, в свою очередь, вызывается при initComponents(), который, в свою очередь, добавляет слушатель, который, в свою очередь, вызывает updateModel, когда нажата клавиша OK и валидация поля прошла успешно, т.е. можно обновить (запомнить) то, что мы ввели в поле.

Эта процедура (setOrderNo), в примере используется вовсе не для того, чтобы Вы сами что-то вводили в поле с ее применением, хотя никто не мешает это делать (недаром она объявлена как public).

Насколько я понял, эту бодягу, т.е. цепочку, придется для каждой своей формы ваять самостоятельно. Т.е. как именно Вы сами собираетесь использовать этот метод и даже использовать ли отдельный метод вообще или встроить обновление модели прямо в процедуру валидации - всецело на Вашей совести, думаю, что стоит просто скопировать подход авторов примера.
Set и Get методы - это НЕ методы реализации интерфейса или абстрактных методов, это просто нам дали пример грамотной валидации и обновления модели.

Грубо говоря, стремление авторов framework к универсальности просто привело к тому, что вам придется каждый раз проделать работу пожалуй даже большую, чем писать проверку каждый раз самому. Т.к. придется самостоятельно отслеживать нерушимость цепочки get и set методов + сочетание их с валидацией.

Автор: ShkVal 14.10.2005, 11:52
Посмотрите сами по стеку поставив точку останова на setOrderNo() явно не вызывается и мне не понятно, что нужно сделать чтобы вызвался этот метод. Запускаю main() из com.jgoodies.validation.tutorial.basics.ComponentFeedbackExample

Автор: ShkVal 14.10.2005, 12:04
Вроде понял это указывается сдесь
severityOrderNoField = ExampleComponentFactory.createTextField(
orderModel.getModel(Order.PROPERTYNAME_ORDER_NO), false);
если не так поправте.
Так как я плохо знаю SWING и тем более JGoodies не могли бы подсказать что даёт этот вызов firePropertyChange(PROPERTYNAME_ORDER_NO, oldValue, newValue) в setOrderNo()?

Автор: batigoal 14.10.2005, 13:13
Цитата(ShkVal @ 14.10.2005, 13:04)
не могли бы подсказать что даёт этот вызов firePropertyChange(PROPERTYNAME_ORDER_NO, oldValue, newValue) в setOrderNo()?

Собственно, создает новое событие, событие изменения поля. Видимо, PROPERTYNAME_ORDER_NO - это имя поля, oldValue - старое значение, newValue - новое значение.

Автор: carper 14.10.2005, 14:18
ShkVal
Цитата(ShkVal @ 14.10.2005, 11:52)
Посмотрите сами по стеку поставив точку останова на setOrderNo() явно


Да не могу я посмотреть, я же JGoodies целиком не ставил (да и нет его у меня, есть только то, что Вы указали, а это морока приторачивать отдельно валидатор, собирать пакет, да ну его smile ).
Кнопка OK в тестовом примере есть?
По ее нажатию, если проходит валидация !, метод updateModel разве не вызывается?


Цитата(ShkVal @ 14.10.2005, 12:04)
не могли бы подсказать что даёт этот вызов firePropertyChange(PROPERTYNAME_ORDER_NO, oldValue, newValue) в setOrderNo()?


Это работа MVC (model-view-controller) - модель - представление - контроллер.
Модель отвечает за работу с данными, например, хранит их, предоставляет невизуальные методы для добавления и отображения данных...
Представление отвечает за отображение данных.
Контроллер отвечает за взаимодействие (например, отрабатывает события от мыши и клавиатуры - ну, скажем нажали на клавишу - контролер вызовет метод модели для добавления символа и метод представления для его отображения) между представлением и моделью.
Часто модель и контроллер логически объединяют вместе.

Также есть интерфейсные классы, типа JTextField, которые "прячут" от нас реализацию MVC и выступают как некий готовый объект, обладающий всеми свойствами MVC сразу.

Таким образом, метод firePropertyChange - говорит представлению, что данные, хранящиеся в модели, изменились и представлению следует позаботится об обновлении. Представление, получив сигнал, что такие-то данные изменились, поставит в очередь событий SWING работу по изменению экранного представления данного компонента, может еще что-то поменяет внутри своих собственных переменных состояния.

Кстати, метод firePropertyChange это не метод Goodies, насколько я могу догадываться это часть работы стандартного механизма java.beans (отсюда и наши public set and get методы называются именно так (с эти префиксом), иначе их не будет использовать IDE).

( Поскольку SWING НЕ потокобезопасное решение (он использует один собственный поток для ускорения работы), то и существует необходимость очереди - нельзя сразу обновлять тот или иной компонент (тем более нельзя этого делать из модели, не понимая как это можно сделать - можно вступить в конфликт с другими событиями SWING). )

Теперь понятно, что сделали разработчики JGoodies в их validate?
Они не стали трогать представление - т.е. вы можете использовать с этим модулем любые компоненты SWING, включая собственноручно написанные (главное, чтобы в них не была затронута модель).
Они просто переписали стандартную модель (именно это Вы сделали бы и сами, т.к. это самый простой и правильный путь как-то изменить работу с данными).

Чтобы мы могли как-то взаимодействовать с этой переписанной моделью, они нам предоставили интерфейс и описание своего видения как должны работать методы этого самого интерфейса.

Хотим послушаемся, хотим насоздаем заглушек и просто сведем работу валидатора к нулю.


P.S. Короче, set и get методы можете оставить теми же, что и в примере, только скорректируйте названия (например, setMySuperTextField) и, разумеется, получайте/отдавайте величины своего поля.





Автор: ShkVal 14.10.2005, 14:40
carper, спасибо. Рейтинг я тебе поднял за помощь. smile Как всё создать я понял, а как работает всё пока нет. Но мне это пока и не надо. Главное разобрался как делать (что надо создать и что где вызвать)

Автор: carper 14.10.2005, 14:53
ShkVal

Цитата(ShkVal @ 14.10.2005, 14:40)
Рейтинг я тебе поднял за помощь.


Спасибо.
Не думаю, что сильно помог, но я старался. smile


Цитата(ShkVal @ 14.10.2005, 14:40)
Главное разобрался как делать (что надо создать и что где вызвать)


Согласен, т.к. что-то мне смутно подсказывает, что особо глубоко в JGoodies копать и не стоит.
Ведь он и покупался для облегчения жизни, а не ее усложнения. smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)