Откат Swing DataBinding изменяется при нажатии кнопки отмены

У меня есть простой JFrame с несколькими jtextfields внутри, текстовое свойство каждого jtextfield связано с полем объекта через привязку данных (я использовал построитель окон для настройки привязки), когда пользователь что-то меняет в JTextField, изменения автоматически отражаются к свойству связанного объекта, мне нужно, чтобы, когда пользователь нажимал кнопку JButton (кнопка «Отмена»), все изменения, сделанные пользователем, были отброшены.

Итак, я хочу, чтобы когда пользователь начал редактировать поле, например транзакцию, она была запущена, и в зависимости от действия пользователя (кнопка «ОК» или «Отмена») транзакция была зафиксирована или откатана.

Возможно ли это с помощью структуры привязки данных Swing? Как ?

Вот код, который инициализирует привязки данных:

    /**
     * Data bindings initialization 
     */
    protected void initDataBindings() {
        //Title field
        BeanProperty<Script, String> scriptBeanProperty = BeanProperty.create("description");
        BeanProperty<JTextField, String> jTextFieldBeanProperty = BeanProperty.create("text");
        AutoBinding<Script, String, JTextField, String> autoBinding = Bindings.createAutoBinding(UpdateStrategy.READ_WRITE, script, scriptBeanProperty, textFieldName, jTextFieldBeanProperty, "ScriptTitleBinding");
        autoBinding.bind();
        //Id field 
        BeanProperty<Script, Long> scriptBeanProperty_1 = BeanProperty.create("id");
        BeanProperty<JLabel, String> jLabelBeanProperty = BeanProperty.create("text");
        AutoBinding<Script, Long, JLabel, String> autoBinding_1 = Bindings.createAutoBinding(UpdateStrategy.READ, script, scriptBeanProperty_1, labelScriptNo, jLabelBeanProperty, "ScriptIdBinding");
        autoBinding_1.bind();
    }

person aleroot    schedule 24.12.2011    source источник


Ответы (1)


ничего готового, вам нужно реализовать логику буферизации самостоятельно. пример находится в моем разделе инкубатора Swinglabs, посмотрите на AlbumModel. В основном

  • фасоль Альбом
  • AlbumModel — это обертка (также известная как буфер) вокруг бина с теми же свойствами, что и у обернутого: представление привязано к свойствам этой обертки.
  • внутренне он использует однократно прочитанную привязку к свойствам оболочки
  • кроме того, у оболочки есть свойство «буферизация», которое становится истинным, если какое-либо из ее буферизованных свойств отличается от свойства оболочки. В этом состоянии изменения могут быть либо зафиксированы, либо отменены.

Ниже приведен отрывок из AlbumModel (почти все без проверки), который может дать вам представление. Обратите внимание, что BindingGroupBean — это слегка модифицированная BindingGroup, которая сопоставляет внутреннее состояние со свойством bean-компонента «dirty», чтобы разрешить привязку «буферизации». Вы можете найти его в инкубаторе, а также полное приложение BAlbumBrowser (реализация классического примера Фаулера в терминах BeansBinding)

/**
 * Buffered presentation model of Album. 
 * 
 */
@SuppressWarnings("rawtypes")
public class AlbumModel extends Album {
    @SuppressWarnings("unused")
    private static final Logger LOG = Logger.getLogger(AlbumModel.class
            .getName());
    private Album wrappee;

    private BindingGroupBean context;
    private boolean buffering;

    public AlbumModel() {
        super();
        initBinding();
    }

    @Action (enabledProperty = "buffering")
    public void apply() {
        if ((wrappee == null)) 
            return;
        context.saveAndNotify();
    }

    @Action (enabledProperty = "buffering")
    public void discard() {
        if (wrappee == null) return;
        context.unbind();
        context.bind();
    }

    private void initBinding() {
        initPropertyBindings();
        initBufferingControl();
    }

    private void initBufferingControl() {
        BindingGroup bufferingContext = new BindingGroup();
        // needs change-on-type in main binding to be effective
        bufferingContext.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ, 
                context, BeanProperty.create("dirty"), 
                this, BeanProperty.create("buffering")));
        bufferingContext.bind();
    }

    /**
     * Buffer wrappee's properties to this.
     */
    private void initPropertyBindings() {
        context = new BindingGroupBean(true);
        context.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ_ONCE,
                wrappee, BeanProperty.create("artist"), 
                this, BeanProperty.create("artist")));
        context.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ_ONCE,
                wrappee, BeanProperty.create("title"), 
                this, BeanProperty.create("title")));
        // binding ... hmm .. was some problem with context cleanup 
        // still a problem in revised binding? Yes - because
        // it has the side-effect of changing the composer property
        // need to bind th composer later
        context.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ_ONCE,
                 wrappee, BeanProperty.create("classical"), 
                 this, BeanProperty.create("classical")));
        context.addBinding(Bindings.createAutoBinding(UpdateStrategy.READ_ONCE,
                wrappee, BeanProperty.create("composer"), 
                this, BeanProperty.create("composer")));
        context.bind();
    }

    public void setAlbum(Album wrappee) {
        Object old = getAlbum();
        boolean oldEditEnabled = isEditEnabled();
        this.wrappee = wrappee;
        context.setSourceObject(wrappee);
        firePropertyChange("album", old, getAlbum());
        firePropertyChange("editEnabled", oldEditEnabled, isEditEnabled());
    }

    public boolean isEditEnabled() {
        return (wrappee != null); // && (wrappee != nullWrappee);
    }


    public boolean isComposerEnabled() {
        return isClassical();
    }

    /**
     * Overridden to fire a composerEnabled for the sake of the view.
     */
    @Override
    public void setClassical(boolean classical) {
        boolean old = isComposerEnabled();
        super.setClassical(classical);
        firePropertyChange("composerEnabled", old, isComposerEnabled());
    }

    public boolean isBuffering() {
        return buffering;
    }

    public void setBuffering(boolean buffering) {
        boolean old = isBuffering();
        this.buffering = buffering;
        firePropertyChange("buffering", old, isBuffering());
    } 

    /**
     * Public as an implementation artefact - binding cannot handle
     * write-only properrties? fixed in post-0.61
     * @return
     */
    public Album getAlbum() {
        return wrappee;
    }


}
person kleopatra    schedule 24.12.2011
comment
Это кажется фантастическим решением, где я могу найти исходный файл BindingGroupBean? Это доступно ? - person aleroot; 24.12.2011
comment
@aleroot там же, точный пакет смотрите в импорте :-) - person kleopatra; 24.12.2011