Связывание данных с Java

У меня есть приложение с несколькими окнами/представлениями, которые показывают один и тот же объект. Например, у меня есть пользовательский объект с именем и местоположением Strings и ImageIcon для их изображения.

Затем в моих окнах я буду использовать детали этого пользовательского объекта, например:

  • Я создаю JPanel.
  • Я добавляю к нему JLabels (nameLabel, locationLabel, imageLabel)
  • Я вызываю setText() (или setIcon для imageLabel) для каждой из этих меток, чтобы установить их текст/изображение в данные объекта пользователя.

Я должен многократно делать это для

  • в каждом окне, где отображаются данные объекта пользователя
  • Каждый раз, когда пользовательский объект изменяется, мне нужно снова вызвать setText() на ярлыках.

В С#, когда я использовал привязку данных, поэтому, когда я обновлял объект, он автоматически отражался в элементе GUI, который был привязан к нему. Что-то подобное существует с Java?

Ответ 2

MVP-шаблон помогает вам достичь этого. Вы должны написать повышение пользовательских событий и подключить слушателей пользовательского интерфейса, чтобы реагировать на эти события (шаблон наблюдателя). Java предоставляет PropertyChangeEvents и PropertyChangeListeners в дополнение к контрактам Observer и Observable.

Ответ 3

Вот пример в Java SE Application Design статьи привязки данных.

См. AbstractModel, который использует PropertyChangeSupport.

Классы, которые должны заметить, что объект изменился, будут реализовывать PropertyChangeListener (см. AbstractController).

Ответ 4

Я долгое время кодировал java и С# и Я закодировал свой собственный PropertyChangeListeners в Java, подражая .net и здесь ниже моего метода.

Для сериализации этого объекта я кодировал специальные фильтры против сериализатора, т.е. XStream, встроенная сериализация объектов Java.

Если вам нужно сделать DIY, вы можете использовать мой способ, или вы также можете продвигаться через инфраструктуру Oracle, поскольку @Pau Kiat Wee связал это в своем ответе.

Посмотрите JGoodies для привязки данных Swing для более уже встроенных в материал http://www.jgoodies.com/download/presentations/binding.pdf http://www.jgoodies.com/downloads/demos/

Вот моя реализация,

Ваш бизнес-объект будет расширен из этого абстрактного класса.

Конечно, если вы уже расширяетесь от чего-то другого, и это не один из ваших, этот вариант не может работать для вас.

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

Обратите внимание, что private void writeObject(java.io.ObjectOutputStream out) и private void readObject(java.io.ObjectInputStream in)подписи. Я намеренно оставил их пустыми, и эти значительные сигнатуры метода рассматриваются Java Object Serialization.

Это наш имитируемый интерфейс PropertyChangeEvent, мы будем использовать шаблон наблюдателя для уведомления наших владельцев регистрации.

public interface IPropertyChangedListener extends EventListener {

    public void onPropertyChanged(Object source,String propertyName,Object oldValue,Object newValue);

}

Это наша база DataBusinessObject

public abstract class DataObjectBase implements Serializable {


    private List<IPropertyChangedListener> propertyChangeListeners=new ArrayList<IPropertyChangedListener>();   
    public void addOnPropertyChangedListener(IPropertyChangedListener propertyChangeListener)
    {   
        ensureRegisterListCreated();
        propertyChangeListeners.add(propertyChangeListener);
    }

    public void removeOnPropertyChangedListener(IPropertyChangedListener propertyChangeListener)
    {
        ensureRegisterListCreated();
        propertyChangeListeners.remove(propertyChangeListener);
    }

    public DataObjectBase()
    {
        ensureRegisterListCreated();
    }

    public void ensureRegisterListCreated()
    {
        if(propertyChangeListeners==null)
            propertyChangeListeners=new ArrayList<IPropertyChangedListener>();      
    }

    protected void onPropertyChanged(Object source,String propertyName,Object oldValue,Object newValue)
    {
        if(propertyChangeListeners.size()<=0)
            return;
        for (IPropertyChangedListener listener : propertyChangeListeners) {
            listener.onPropertyChanged(source, propertyName, oldValue, newValue);
        }
    }

    private void writeObject(java.io.ObjectOutputStream out)
             throws IOException
             {

             }

     private void readObject(java.io.ObjectInputStream in)
              throws IOException {


              }

}

Теперь давайте использовать его

dataObject.addOnPropertyChangedListener(new IPropertyChangedListener() {

                @Override
                public void onPropertyChanged(Object source, String propertyName,
                        Object oldValue, Object newValue) {
                    System.out.println(String.format("%s %s %s",propertyName,oldValue,newValue));
//TODO:Fire your UI change now !!!

                }
            });

Вот что вам нужно сделать в вашем dataObject

public class dataObject extends BaseDataObject
{

    private String editable;

    public String getEditable() {
       return editable;
    }

    public void setEditable(String isEditable) {
        String oldValue=this.editable;      
        this.editable = isEditable;
        onPropertyChanged(this,"Editable",oldValue,isEditable);
    }

}

Если вы не хотите делать свой путь, или вы не можете по какой-то причине. Вы должны следовать JGoodies, это кажется лучшим из всех. В demos загрузите файл JNLP, и вы увидите часть DataBinding. Когда вы нажимаете стрелку, расположенную вверх-вправо, появляется раздел кода. Удачи! http://www.jgoodies.com/downloads/demos/

Ответ 5

Используйте файл betterbeansbinding.jar вместо beansbinding.jar