jface databinding/PojoBindbleはPOJOオブジェクトへのサポートを実現します。


POJO対象は監視できません。
jface databindingでは、一般的なjava bean(get/set方法はありますが、Propty Chane Supportによる属性監視は行われていません)をPOJOオブジェクトと定義します。私たちはPOJOオブジェクトに対してPojoProperties.value(String propertyName)方法でIObservable Valueのインスタンスを提供することができますが、戻ってきたPojoValuePropertyの例は、POJOオブジェクトの監視を本当に実現していませんでした。したがって、UIコンポーネントとPOJOオブジェクトとの間で確立されたデータリンクは一方向であり、UIコンポーネントのデータ変化はPOJOオブジェクトに同期させることができるが、逆にダメである。以下の例では、この違いをデモできます。プログラムを実行し、プログラムを起動すると、Textコンポーネントの内容はPOJOオブジェクトの属性と同じ値に更新されます。しかし、「試験」ボタンを押してPOJOオブジェクトの属性を変更しましたが、Textコントロールの値は同期されていません。
package testwb;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.swt.widgets.Display;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.jface.databinding.swt.DisplayRealm;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.core.databinding.beans.PojoProperties;

public class TestPojoBinding extends Dialog {

    /** *        * @author guyadong * */
    public class Configuration {
        private String name;
        public Configuration(String name) {
            super();
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
            System.out.printf("updated %s
"
,this.name); } } private DataBindingContext m_bindingContext; /** * : */ protected Configuration editorConfig=new Configuration("hello!"); private Text myNametext; /** * Create the dialog. * @param parentShell */ public TestPojoBinding(Shell parentShell) { super(parentShell); } /** * Create contents of the dialog. * @param parent */ @Override protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); container.setLayout(null); Button btnNewButton = new Button(container, SWT.NONE); btnNewButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { editorConfig.setName("word"); } }); btnNewButton.setBounds(38, 154, 80, 27); btnNewButton.setText(" "); myNametext = new Text(container, SWT.BORDER); myNametext.setBounds(38, 27, 80, 23); return container; } /** * Create contents of the button bar. * @param parent */ @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); m_bindingContext = initDataBindings(); } /** * Return the initial size of the dialog. */ @Override protected Point getInitialSize() { return new Point(362, 298); } public static void main(String[] args) { Display display = Display.getDefault(); Realm.runWithDefault(DisplayRealm.getRealm(display), new Runnable() { public void run() { try { TestPojoBinding setting = new TestPojoBinding(null); setting.open(); } catch (Exception e) { e.printStackTrace(); } } }); } protected DataBindingContext initDataBindings() { DataBindingContext bindingContext = new DataBindingContext(); IObservableValue observeTextMyNametextObserveWidget = WidgetProperties.text(SWT.Modify).observe(myNametext); IObservableValue nameEditorConfigObserveValue = PojoProperties.value("name").observe(editorConfig); bindingContext.bindValue(observeTextMyNametextObserveWidget, nameEditorConfigObserveValue, null, null); return bindingContext; } }
Propty Change Support
上の例のデータオブジェクト属性とTextコンポーネントのコンテンツが双方向に同期されている場合。ソリューションの一つは、データオブジェクトを改造するPersonであり、ProptyChape Supportを通じてプロパティモニタを実現する。
package testwb;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Text;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

import org.eclipse.core.databinding.DataBindingContext;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.jface.databinding.swt.WidgetProperties;
import org.eclipse.swt.widgets.Display;
import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.jface.databinding.swt.DisplayRealm;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.core.databinding.beans.BeanProperties;

public class TestPojoBinding2 extends Dialog {
    public class ModelObject {
        private final PropertyChangeSupport changeSupport =
                new PropertyChangeSupport(this);

        public void addPropertyChangeListener(PropertyChangeListener
                listener) {
            changeSupport.addPropertyChangeListener(listener);
        }

        public void removePropertyChangeListener(PropertyChangeListener
                listener) {
            changeSupport.removePropertyChangeListener(listener);
        }

        protected void firePropertyChange(String propertyName, Object oldValue,
                Object newValue) {
            changeSupport.firePropertyChange(propertyName, oldValue, newValue);
        }
    }
    /** *       ,  ModelObject ,             * @author guyadong * */
    public class Person extends ModelObject {
        private String name;
        public Person(String name) {
            super();
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            //   set  ,        ,  firePropertyChange             
            firePropertyChange("name", this.name, this.name = name);
            System.out.printf("updated %s
"
,this.name); } } private DataBindingContext m_bindingContext; /** * : */ protected Person editorConfig=new Person("hello!"); private Text myNametext; /** * Create the dialog. * @param parentShell */ public TestPojoBinding2(Shell parentShell) { super(parentShell); } /** * Create contents of the dialog. * @param parent */ @Override protected Control createDialogArea(Composite parent) { Composite container = (Composite) super.createDialogArea(parent); container.setLayout(null); Button btnNewButton = new Button(container, SWT.NONE); btnNewButton.addSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { editorConfig.setName("word"); } }); btnNewButton.setBounds(38, 154, 80, 27); btnNewButton.setText(" "); myNametext = new Text(container, SWT.BORDER); myNametext.setBounds(38, 27, 80, 23); return container; } /** * Create contents of the button bar. * @param parent */ @Override protected void createButtonsForButtonBar(Composite parent) { createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true); createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false); m_bindingContext = initDataBindings(); } /** * Return the initial size of the dialog. */ @Override protected Point getInitialSize() { return new Point(362, 298); } public static void main(String[] args) { Display display = Display.getDefault(); Realm.runWithDefault(DisplayRealm.getRealm(display), new Runnable() { public void run() { try { TestPojoBinding2 setting = new TestPojoBinding2(null); setting.open(); } catch (Exception e) { e.printStackTrace(); } } }); } protected DataBindingContext initDataBindings() { DataBindingContext bindingContext = new DataBindingContext(); // Text IObservableValue observeTextMyNametextObserveWidget = WidgetProperties.text(SWT.Modify).observe(myNametext); // IObservableValue nameEditorConfigObserveValue = BeanProperties.value("name").observe(editorConfig); // bindingContext.bindValue(observeTextMyNametextObserveWidget, nameEditorConfigObserveValue, null, null); // return bindingContext; } }
プログラムを再実行し、「テスト」ボタンをクリックして、Textの値はデータオブジェクトの属性と同期して変化しました。
PojoBindable
上記のプログラムは、データオブジェクトとUIコンポーネントの双方向同期更新を実現したが、POJOオブジェクトを改造する必要があるという欠点があり、プロジェクトの中に複数のPOJOオブジェクトがある場合、UIコンポーネントとのダブル同期更新を実現する必要がある場合、この作業量もかなり大きい。既存のPOJOオブジェクトのコードを変えずに双方向同期を実現する方法がありますか?あります。解決策はここの問題です。jface databinding/PojoBindble。【注意:これはまだ実験項目で、慎重に使用する必要がある】PojoBindableは、ASMコードを用いて動的に修正する技術で、実行時にPOJOオブジェクトにPropertyChange Supportを追加し、setter方法を修正することにより、開発者が自分のPOJOコードを修正せずにPOJOオブジェクトに完全なデータバインディング能力を持たせる方法を提供します。すべてのものには代償があります。Pojobindableを使ってPOJOの対象コードを修正しないでProptyChange Supportの能力を持つと、価格は何ですか?
JVMの運転パラメータを変更したいです。
Pojo BindableはJava Agentであるため、PojoBindableを使用するためには、javaプログラムの起動時にjvmパラメータを指定し、-javaagentパラメータでPojoBindableを使用することを指定しなければならない。
-javaagent:/org.eclipse.core.databinding.pojo.bindable_1.0.0.jar
どのようなpojoオブジェクトに対してjavaコードを修正するかを指定する-Dbindable.packagesが必要です。
-Dbindable.packages=org.eclipse.core.examples.databinding.pojo.bindable.model
ASMサポートが必要です
Object Web ASMをクラスパスに加入しなければなりません。
Pojo Bindanbleの構成については、その公式サイトを参照してください。
https://wiki.eclipse.org/JFace_Data_Binding/PojoBindable〓With_ポジョンBindable
参考資料「JFace Data Binding/PojoBindable」「AJFace Data Binding-Tutorial」