Преамбула
На досуге решил разобрать биндинг и валидацию в Java Beans Binding (JSR 295). Реализация предлагаемая JSR 295 показалась мне проще и удобнее, чем аналогичный функционал, предоставляемый в рамках JGoodies.
Ниже рассмотрю два небольших примера биндинга контролов и пример создания и использования валидатора.
Биндинг текстового поля (JTextField)
Определим простой класс, со свойствами которого будут связаны элементы формы
Процесс биндинга текстовых полей довольно прост и в комментариях практически не нуждается. Связывание двух свойств различных элементов осуществляется путем создания объекта класса AutoBinding. Этот класс синхронизирует свойства объектов, руководствуясь одной из трех стратегий:
1. READ_ONCE — синхронизация осуществляется только один раз, во время связывания полей объектов.
2. READ — целевой объект синхронизируется с источником.
3. READ_WRITE — синхронизация объектов друг с другом.
Процесс создания объектов класса AutoBinding может быть упрощен посредством использования фабрики классов Bindings
Все очевидно.
Биндинг комбобоксов (JComboBox)
Биндинг комбобоксов осуществляется в два этапа. Вначале комбобокс связывается со списком возможных значений, после чего осуществляется связывание свойства selectedItem с соответствующим свойством целевого класса.
Определим простой класс, представляющий элемент списка значений комбобокса
Добавим в класс MyBean поле, с которым будет связываться свойство selectedItem комбобокса
Создадим список значений комбобокса
Поддержку биндинга сложных Swing-компонентов осуществляет фабрика классов SwingBindings. Свяжем комбобокс со список значений
Осталось связать свойство selectedItem комбобокса с соответствующим свойством целевого класса
создание Валидатора
В качестве примера реализуем простой валидатор для рассмотренного выше элемента textField. Наш валидатор будет осуществлять две проверки — на непустоту и на максимальное количество символов.
Все валидаторы должны наследоваться от параметризованного класса Validator, где T — тип данных с которым будет осуществляться работа.
Проверкой значения занимается функция validate. В случае, если значение прошло валидацию, должен быть возвращен null. В противном случае следует возвратить объект класса Result, содержащий описание проблемы и код ошибки.
Использование валидатора
Для того, чтобы воспользоваться валидатором нужно немного имзенить код, осуществляющий биндинг
Осталось только отреагировать на события валидации
Конец.
На досуге решил разобрать биндинг и валидацию в Java Beans Binding (JSR 295). Реализация предлагаемая JSR 295 показалась мне проще и удобнее, чем аналогичный функционал, предоставляемый в рамках JGoodies.
Ниже рассмотрю два небольших примера биндинга контролов и пример создания и использования валидатора.
Биндинг текстового поля (JTextField)
Определим простой класс, со свойствами которого будут связаны элементы формы
class MyBean extends AbstractBean {
private String strProperty = "";
//
// Конструкторы, геттеры и сеттеры здесь.
//
}
Процесс биндинга текстовых полей довольно прост и в комментариях практически не нуждается. Связывание двух свойств различных элементов осуществляется путем создания объекта класса AutoBinding. Этот класс синхронизирует свойства объектов, руководствуясь одной из трех стратегий:
1. READ_ONCE — синхронизация осуществляется только один раз, во время связывания полей объектов.
2. READ — целевой объект синхронизируется с источником.
3. READ_WRITE — синхронизация объектов друг с другом.
Процесс создания объектов класса AutoBinding может быть упрощен посредством использования фабрики классов Bindings
// ...где-то в глубинах кода...
MyBean modelBean = new MyBean();
// ...
JTextField textField = new JTextField();
// ...
Bindings.createAutoBinding(READ_WRITE,
modelBean, BeanProperty.create("strProperty"),
textField, BeanProperty.create("text")).bind();
Все очевидно.
Биндинг комбобоксов (JComboBox)
Биндинг комбобоксов осуществляется в два этапа. Вначале комбобокс связывается со списком возможных значений, после чего осуществляется связывание свойства selectedItem с соответствующим свойством целевого класса.
Определим простой класс, представляющий элемент списка значений комбобокса
class ComboBoxVal {
private int id = 0;
private String text = "";
//
// Конструкторы, геттеры и сеттеры здесь.
//
}
Добавим в класс MyBean поле, с которым будет связываться свойство selectedItem комбобокса
class MyBean extends AbstractBean {
private String stringProperty = "Hello!";
private ComboBoxVal comboProperty =
new ComboBoxVal(0, "Item0");
// ...
Создадим список значений комбобокса
// ...где-то в глубинах кода...
private List comboBoxData = new ArrayList();
// ...
for (int i = 0; i < 10; i++)
comboBoxData.add(
new ComboBoxVal(i, "Item" + i));
Поддержку биндинга сложных Swing-компонентов осуществляет фабрика классов SwingBindings. Свяжем комбобокс со список значений
JComboBox comboBox = new JComboBox();
// ...
SwingBindings.createJComboBoxBinding(
READ, comboBoxData, comboBox).bind();
Осталось связать свойство selectedItem комбобокса с соответствующим свойством целевого класса
Bindings.createAutoBinding(READ_WRITE,
comboBox,
BeanProperty.create("selectedItem"),
modelBean,
BeanProperty.create("comboProperty")).bind();
создание Валидатора
В качестве примера реализуем простой валидатор для рассмотренного выше элемента textField. Наш валидатор будет осуществлять две проверки — на непустоту и на максимальное количество символов.
Все валидаторы должны наследоваться от параметризованного класса Validator, где T — тип данных с которым будет осуществляться работа.
class StringValidator extends Validator {
private int maxStrLength = 10;
// ...
// Конструкторы, геттеры и сеттеры здесь.
// ...
public Result validate(String value) {
if (value == null || value.length() == 0)
return new StringEmptyResult();
if (value.length() > maxStrLength)
return new StringTooLong();
return null;
}
public static class StringEmptyResult
extends Result {
public StringEmptyResult() {
super(0, "Str empty msg");
}
}
public static class StringTooLong
extends Result {
public StringTooLong() {
super(1, "Str too long msg");
}
}
}
Проверкой значения занимается функция validate. В случае, если значение прошло валидацию, должен быть возвращен null. В противном случае следует возвратить объект класса Result, содержащий описание проблемы и код ошибки.
Использование валидатора
Для того, чтобы воспользоваться валидатором нужно немного имзенить код, осуществляющий биндинг
//...где-то в глубинах кода...
private Binding textBinding;
// ...
textBinding = Bindings.createAutoBinding(
READ_WRITE,
modelBean, BeanProperty.create("strProperty"),
textField, BeanProperty.create("text"));
textBinding.setValidator(validator);
textBinding.bind();
Осталось только отреагировать на события валидации
textBinding.addBindingListener(
new BindingListener(){
public void syncFailed(Binding binding,
Binding.SyncFailure failure) {
// Реакция на ошибку валидации.
}
public void synced(Binding binding) {
// Реакция на успешную валидацию.
}
// ...
Конец.