GlazedList更新JTable中的EventList [英] GlazedList update EventList in JTable

查看:82
本文介绍了GlazedList更新JTable中的EventList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何更新EventList列表以更新JTable?这就是我要做的:

How can I update EventList list to update JTable? This is what I do:

        String[] headers = new String[]{"MNO", "NAME", "ID/REG No", "PHONE"};
        String[] properties = new String[]{"milkNo", "fullName", "nationalId", "phone1"};


        TextFilterator<Member> personTextFilterator = new TextFilterator<Member>() {

            @Override
            public void getFilterStrings(List list, Member m) {
                list.add(m.getFullName());
                list.add(m.getMilkNo());
                list.add(m.getNationalId());
                list.add(m.getPhone1());
            }
        };

        MatcherEditor<Member> textMatcherEditor = new TextComponentMatcherEditor<Member>(txtFilter, personTextFilterator);

        FilterList<Member> filterList = new FilterList<Member>(eventList, textMatcherEditor);

        TableFormat tf = GlazedLists.tableFormat(properties, headers);
        model = new EventTableModel<Member>(filterList, tf);

        selectionModel = new EventSelectionModel<Member>(filterList);
        tblMembers.setSelectionModel(selectionModel);

        tblMembers.setModel(model);

探测是当我过滤表中的记录并选择一条记录并尝试更新它时,它会在表中创建一条新记录

The probem is when i filter the records in table, and select a record and trying to update it, it create a new record in the table instead

int updatedRow = tblMembers.convertRowIndexToModel(tblMembers.getSelectedRow());
eventList.set(updatedRow, updatedMember);

推荐答案

一旦您使用GlazedLists为JTable提供动力,那么您仅应使用EventTableModelEventSelectionModelJTable进行交互.您犯的错误是直接在JTable中查询所选行并获取其索引-但是JTable无法理解它是否由EventList支持,该EventList可能对其中的项目进行排序/过滤.因此,JTable中的 i 行不一定与您的EventList中的元素 i 相对应.

Once you're using GlazedLists to power your JTable then you should only use EventTableModel and EventSelectionModel to interact with your JTable. The mistake you've made is to query the JTable directly for the selected row and get its index - but the JTable doesn't understand that it's backed by an EventList which maybe sorting/filtering items within. Therefore row i in the JTable will not necessarily correspond to element i in your EventList.

在您的代码中,您实际上已经设置了一个EventSelectionModel,现在只需要使用它即可.

In your code you have actually set up an EventSelectionModel, now it's just a matter of using it.

if (!selectionModel.isSelectionEmpty()) {
    EventList<Member> selectedMembers = selectionModel.getSelected();
    for (int i = 0; i<selectedMembers.size(); i++) {
        Member member = selectedMembers.get(i);
        //update accordingly...
        //member.setXXX(...); 
        selectedMembers.set(i, member);
     }
}

您必须记住,JTables支持多个行选择(尽管可以将其配置为仅允许单行选择),因此EventSelectionModel明智地将返回所有选定行的EventList,即使仅选择了一个.因此,您需要遍历返回的列表.包含所选项目的EventList由源EventList支持是一个额外的便利,因此您可以直接对该子列表进行更改.

You have to remember that JTables support multiple row selections (although that can be configured allow only single row selection) and therefore the EventSelectionModel sensibly will return an EventList of all the selected rows, even if only one is selected. Therefore you need to iterate over the returned list. There is an additional convenience that the EventList containing the selected items is backed by the source EventList, so you can make changes directly to that sub-list.

高级

当然,EventLists非常适合观察列表的基本变化:删除,插入,更新(即,将索引为 i 的现有对象替换为另一个对象).但是,如果不是直接调用selectedMembers.set(),而是可以直接在EventList中更新一个对象,然后让GlazedLists检测到该属性更改,那不是很好吗?

Of course EventLists are great for observing the fundamental changes to a list: deletion, insertion, updating (ie replacing an existing object at index i with another object). However, wouldn't it be great if instead of calling selectedMembers.set(), we could update an object within an EventList directly and then let GlazedLists detect that property change?

那也是可能的.有一个有用的列表类型,称为ObservableElementList,在这里它将侦听其包含的每个对象的属性更改并相应地刷新.这比必须在列表中定位并称为eventList.set()的对象要方便得多.

Well that's possible too. There's a useful list type called ObservableElementList and here it will listen to property changes for each object it contains and refresh accordingly. This is much more convenient than having to locate the object within the list and called eventList.set().

您首先需要使您的类支持属性侦听器,即是适当的Java bean,然后使用ObservableElementList.Connector.

You first need to make your class support property listeners, i.e., is a proper Java bean, and then use a ObservableElementList.Connector.

我已经创建了一个小而完整的示例来进行实际操作.在此示例中,顶部有一个用于过滤的文本输入,一个包含简短作者列表的表以及一个底部的按钮,该按钮将更新任何选定行的名称.

I've created a small but complete example of this in action. In this example there is a text input at the top for filtering, a table containing a short list of authors, and a button at the bottom which will update the name of any selected row.

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.ObservableElementList;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.matchers.MatcherEditor;
import ca.odell.glazedlists.swing.EventSelectionModel;
import ca.odell.glazedlists.swing.EventTableModel;
import ca.odell.glazedlists.swing.TextComponentMatcherEditor;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;

public class GlazedListSelectionObservable {

    private JFrame frame;
    private JTable table;
    private JTextField txtInput;

    private EventList<Person> people;
    private EventSelectionModel<Person> selectionModel;

    public GlazedListSelectionObservable() {

        setupGui();
        setupGlazedLists();
        populatedList();
        frame.setVisible(true);
    }

    private void setupGui() {

        frame = new JFrame("GlazedLists Selection Example");
        frame.setSize(600, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        txtInput = new JTextField();
        table = new JTable();
        frame.getContentPane().add(new JScrollPane(table), BorderLayout.CENTER);

        JButton updateTableButton = new JButton("Update selected row");

        updateTableButton.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (!selectionModel.isSelectionEmpty()) {
                    EventList<Person> selectedPeople = selectionModel.getSelected();
                    for (Person person: selectedPeople) {
                        person.setFirstName("David");
                        person.setLastName("Baldacci");
                    }
                }
            }
        });

        frame.getContentPane().add(txtInput, BorderLayout.NORTH);
        frame.getContentPane().add(updateTableButton, BorderLayout.SOUTH);

    }

    private void populatedList() {
        people.add(new Person("John", "Grisham"));
        people.add(new Person("Patricia", "Cornwell"));
        people.add(new Person("Nicholas", "Sparks"));
        people.add(new Person("Andy", "Weir"));
        people.add(new Person("Elizabeth", "George"));        
    }

    private void setupGlazedLists() {
        people = new BasicEventList<Person>();
        MatcherEditor<Person> textMatcherEditor = new TextComponentMatcherEditor<Person>(txtInput, new PersonTextFilterator());

        ObservableElementList.Connector<Person> personConnector = GlazedLists.beanConnector(Person.class);
        EventList<Person> observedPeople = new ObservableElementList<Person>(people, personConnector);

        FilterList<Person> filteredPeople = new FilterList<Person>(observedPeople, textMatcherEditor);

        EventTableModel model = new EventTableModel(filteredPeople, GlazedLists.tableFormat(new String[]{"firstName", "lastName"} , new String[]{"First Name", "Last Name"}));

        selectionModel = new EventSelectionModel<Person>(filteredPeople);

        table.setModel(model);
        table.setSelectionModel(selectionModel);
    }

    class PersonTextFilterator implements TextFilterator<Person> {

        @Override
        public void getFilterStrings(List<String> list, Person person) {
            list.add(person.getFirstName());
            list.add(person.getLastName());
        }

    }

    public class Person {

        private String firstName;
        private String lastName;

        private final PropertyChangeSupport support = new PropertyChangeSupport(this);

        public Person() {
        }

        public Person(String firstName, String lastName) {
            this.firstName = firstName;
            this.lastName = lastName;
        }

        public String getFirstName() {
            return firstName;
        }

        public String getLastName() {
            return lastName;
        }

        public void setFirstName(String firstName) {
            final String oldFirstName = this.firstName;
            this.firstName = firstName;
            support.firePropertyChange("firstName", oldFirstName, firstName);
        }

        public void setLastName(String lastName) {
            final String oldLastName = this.lastName;
            this.lastName = lastName;
            support.firePropertyChange("lastName", oldLastName, lastName);
        }

        public void addPropertyChangeListener(PropertyChangeListener l) {
            support.addPropertyChangeListener(l);
        }

        public void removePropertyChangeListener(PropertyChangeListener l) {
            support.removePropertyChangeListener(l);
        }

    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
              new GlazedListSelectionObservable();
            }
        });
    }

}

这篇关于GlazedList更新JTable中的EventList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆