使用 Java 进行数据绑定

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9907806/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 22:50:56  来源:igfitidea点击:

Data binding with Java

javaswingdata-binding

提问by Jim_CS

I have an application with several windows/views that show the same object. For example I have a user object with name and location Strings and an ImageIcon for their picture.

我有一个应用程序,其中包含多个显示相同对象的窗口/视图。例如,我有一个带有名称和位置字符串的用户对象以及一个用于其图片的 ImageIcon。

Then on my windows I will use the details of that user object like this -

然后在我的窗户上,我将像这样使用该用户对象的详细信息 -

  1. I create a JPanel.
  2. I add JLabels to it (nameLabel, locationLabel, imageLabel)
  3. I call setText() (or setIcon for imageLabel) for each of these labels to set their text/image to the user object data.
  1. 我创建了一个 JPanel。
  2. 我向它添加 JLabels (nameLabel, locationLabel, imageLabel)
  3. 我为这些标签中的每一个调用 setText()(或为 imageLabel 调用 setIcon)以将它们的文本/图像设置为用户对象数据。

I have to repeatedly do this for

我必须反复这样做

  1. each window where the user object's data is shown
  2. every time the user object is changed I have to call setText() on the labels again.
  1. 每个显示用户对象数据的窗口
  2. 每次更改用户对象时,我都必须再次在标签上调用 setText()。

In C# when I was using databinding so when I updated an object it was automatically reflected in the GUI element that was databound to it. Does something similar exist with Java?

在 C# 中,当我使用数据绑定时,当我更新一个对象时,它会自动反映在数据绑定到它的 GUI 元素中。Java 是否存在类似的东西?

采纳答案by Pau Kiat Wee

What you need is Property Change Listener

您需要的是Property Change Listener

回答by Sérgio Michels

There's a example in the Java SE Application Designarticle of data binding.

数据绑定的Java SE 应用程序设计文章中有一个示例。

See the AbstractModelthat uses PropertyChangeSupport.

请参阅AbstractModel使用PropertyChangeSupport.

The classes that need to notice that the object has changed will implement PropertyChangeListener(see AbstractController).

需要注意对象已更改的类将实现PropertyChangeListener(请参阅 参考资料AbstractController)。

回答by questzen

MVP pattern helps you achieve this. You have to write raise custom events and attach UI listeners to respond to these events (observer pattern). Java provides PropertyChangeEvents and PropertyChangeListeners in additional to Observer and Observable contracts.

MVP 模式可帮助您实现这一目标。您必须编写引发自定义事件并附加 UI 侦听器以响应这些事件(观察者模式)。除了 Observer 和 Observable 合同之外,Java 还提供了 PropertyChangeEvents 和 PropertyChangeListeners。

回答by Davut Gürbüz

I've been coding with java and c# for a long time and I've coded my own propertyChangeListeners in Java by imitating .net and here below my method.

我已经用 java 和 c# 编码很长时间了,我通过模仿 .net 和下面我的方法在 Java 中编写了我自己的 propertyChangeListeners。

For serialization of this object I coded special filters against serializer ,i.e. XStream , java native object serialization

为了序列化这个对象,我针对序列化程序编写了特殊的过滤器,即 XStream ,java 原生对象序列化

If you need to DIY you may use my way or you may also progress by going through Oracle's infrastructure as @Pau Kiat Wee linked it in his/her answer.

如果您需要 DIY,您可以使用我的方式,或者您也可以通过浏览 Oracle 的基础设施来取得进展,因为@Pau Kiat Wee 在他/她的回答中将其链接到。

Have a look JGoodies for Swing data binding for more already built in stuff http://www.jgoodies.com/download/presentations/binding.pdfhttp://www.jgoodies.com/downloads/demos/

看看 JGoodies for Swing 数据绑定,了解更多已经内置的东西http://www.jgoodies.com/download/presentations/binding.pdf http://www.jgoodies.com/downloads/demos/

Here is my implementation,

这是我的实现,

Your business object will be extended from this abstract class.

您的业​​务对象将从这个抽象类扩展而来。

Sure, if you are already extending from something else and this is not one of yours this option impossibly work for you.

当然,如果您已经从其他东西扩展并且这不是您的一个,那么这个选项不可能适合您。

Most possibly you have no intention to serialize propertyChangeListenersregistrants and send some data to somewhere with it(a remote service which doesn't know your UI dependent class and this will be headache).So,we are skipping serialization by this way.

很可能您无意序列化propertyChangeListeners注册人并将一些数据发送到某个地方(一个不知道您的 UI 依赖类的远程服务,这会让人头疼)。所以,我们通过这种方式跳过序列化。

Please notice private void writeObject(java.io.ObjectOutputStream out)and private void readObject(java.io.ObjectInputStream in)signatures. I intentionally left them empty and these significant method signatures are considered by Java Object Serialization.

请注意 private void writeObject(java.io.ObjectOutputStream out)private void readObject(java.io.ObjectInputStream in)签名。我故意将它们留空,这些重要的方法签名由Java Object Serialization.

This is our PropertyChangeEvent imitated interface,we will use observer pattern to notify our registrants.

这是我们的 PropertyChangeEvent 模仿接口,我们将使用观察者模式来通知我们的注册人。

public interface IPropertyChangedListener extends EventListener {

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

}

This is our base of DataBusinessObject

这是我们 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 {


              }

}

Now , lets use it

现在,让我们使用它

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 !!!

                }
            });

Here is what you need to do in your dataObject

这是您需要在 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);
    }

}

If you don't wanna do my way, or you can't for some reason. You should follow JGoodies, this seem the best one of all. In demos download JNLP file and you you will see DataBinding part. There is code section when you click on an arrow placed up-right. Good luck! http://www.jgoodies.com/downloads/demos/

如果你不想按照我的方式做,或者出于某种原因你不能。你应该关注 JGoodies,这似乎是最好的一个。在演示中下载 JNLP 文件,您将看到 DataBinding 部分。当您单击位于右上角的箭头时,会出现代码部分。祝你好运! http://www.jgoodies.com/downloads/demos/

回答by Bala sp

Use betterbeansbinding.jar file instead of beansbinding.jar

使用 betterbeansbinding.jar 文件代替 beansbinding.jar