如何在java中添加、删除和更新GlazedList/JTable中的行?

如何在java中添加、删除和更新GlazedList/JTable中的行?,java,swing,jtable,jtextfield,glazedlists,Java,Swing,Jtable,Jtextfield,Glazedlists,我创建了一个带有GlazedList的表,以便能够为搜索目的过滤该表。现在的问题是如何删除、添加或更新此表中的行。我确实搜索了API,但没有找到它 有人能用一个简单的例子演示如何实现删除、添加和更新吗? public static JTable retrieveArtikelTable(String filePath, String[] header, JTextField filterField) { EventList eventList = new BasicEventList()

我创建了一个带有GlazedList的表,以便能够为搜索目的过滤该表。现在的问题是如何删除、添加或更新此表中的行。我确实搜索了API,但没有找到它

有人能用一个简单的例子演示如何实现删除、添加和更新吗?

public static JTable retrieveArtikelTable(String filePath, String[] header, JTextField filterField) {
    EventList eventList = new BasicEventList();
    String[] headers = new String[0];
    CsvReader reader = null;
    JTable t = new JTable();
    if (filePath != null) {
        if (new File(filePath).exists()) {
            try {
                reader = new CsvReader(filePath, ';');
                if (header != null) {
                    headers = header;
                } else {
                    headers = reader.getHeaders();
                }
                while (reader.readRecord()) {
                    String[] values = reader.getValues();
                    eventList.add(new Artikel(values[0], values[1], values[2]));
                }
                reader.close();
                TextFilterator artikelFilterator = new TextFilterator() {
                    public void getFilterStrings(List baseList, Object element) {
                        Artikel artikel = (Artikel) element;
                        baseList.add(artikel.getCode());
                        baseList.add(artikel.getName());
                        baseList.add(artikel.getNumber());
                    }
                };
                TextComponentMatcherEditor matcherEditor = new TextComponentMatcherEditor(filterField, artikelFilterator);
                FilterList filteredArtikels = new FilterList(eventList, new ThreadedMatcherEditor(matcherEditor));

                // build a JTable
                TableFormat tf = GlazedLists.tableFormat(Artikel.class,headers, headers);
                t = new JTable(new EventTableModel(filteredArtikels, tf));
            } catch (Exception ex) {
                OeExceptionDialog.show(ex);
            } finally {
                assert reader != null;
                reader.close();
            }
        }
    }else{
        t=new JTable();
        JOptionPane.showMessageDialog(filterField.getParent(),"Attention: " +filePath+
                "There is no such a file to be able to create a table!");
    }


    return t;
}


header = new String[]{"Code","Name","Number"};
JTextField filterField = new JTextField();
JTable table = retrieveArtikelTable("c:\articl.csv", header, filterField)

int selectedRow = table.getSelectedRow();
EventTableModel tableModel = (EventTableModel) table.getModel();
// code for deleting a row from this table

// code for add row to this table

// code for updating row from this table
编辑:

EventList eventList = new BasicEventList();
JTable table = retrieveArtikelTable("c:\articl.csv", header, filterField, eventList)
int selectedRow = table.getSelectedRow();

// code for deleting a row from this table
 eventList.remove(selectedRow);
// code for add row to this table

// code for updating row from this table

如果对事件列表进行更改,那么这些更改将通过表模型传播到JTable。(也就是说,如果向该列表中添加新对象、删除新对象或更新新对象,则会自动进行更改。因此,“事件”前缀-列表中的事件会传递给模型。)

因此,您可能需要保留一个对事件列表的引用,以确保在您的情况下,
retrieveArtikelTable()
之外的部分代码可以访问事件列表

我觉得上一期的视频非常适合涵盖所有重要的主题

编辑:提醒您如何使列表成为实例变量,以便可以通过任何方法访问它,而不仅仅是通过构造表的方法

public class Example {
    private EventList<Person> eventList = new BasicEventList<Person>();

    public JTable createTable(...) { ... code to generate the table ...}

    public void manipulateTable() {
        // add to the table (via the eventList)
        eventList.add(new Person("Steve Jobs"));
        // remove first object in the table (and the list)
        eventList.remove(0);
        // update a row
        Person p = eventList.get(0);
        p.setName("A N Other");
        eventList.set(0,p); // overwrite the old object in the list

    }
}
在我的示例中,我使用了一个Person类,它非常简单:


我个人建议将数据加载与创建表的方法分开。我使用了填充列表的
loadData()
方法。如果没有要加载的数据,或者从中加载的文件有问题,则仍然会创建表,但表中没有任何内容,因为列表仍然为空。

我可以通过以下方式或任何其他方式从表中获取事件列表:''eventList list=(eventList)table.getEventList`不直接获取。充其量,您必须扩展EventTableModel,并创建一个新方法,以向公众提供对其源字段(Eventlist)的访问。然后可以得到表的模型及其源。但是,将事件列表放在其他位置(例如父类的实例变量)要容易得多,而不是在创建JTable的方法中声明它,事实上,第二个解决方案更简单。我让它工作了。部分工作了,但不是全部工作。当我搜索表并找到一行,选择它,然后删除它时,它会留在那里,但如果不搜索并选择一行,然后删除它,则删除成功。我怀疑您没有使用正确的方法来检测所选行。请参阅我编辑的答案,了解完整的工作示例应用程序。
public class MyFrame extends javax.swing.JFrame {

    private EventList<Person> eventList = new BasicEventList<Person>();
    private EventSelectionModel<Person> selectionModel;

    /**
     * Creates new form MyFrame
     */
    public MyFrame() {
        initComponents();
        loadData();
        configureTable();
    }

    private void loadData() {

        eventList.add(new Person("Richard", "Dawkins"));
        eventList.add(new Person("Sam", "Harris"));
        eventList.add(new Person("Christopher", "Hitchens"));
        eventList.add(new Person("Daniel", "Dennett"));

    }

    private void configureTable() {
        String[] headers = new String[]{"Firstname", "Lastname"};
        String[] properties = new String[]{"firstname", "lastname"};


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

            @Override
            public void getFilterStrings(List list, Person p) {
                list.add(p.getFirstname());
                list.add(p.getLastname());
            }
        };

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

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

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

        selectionModel = new EventSelectionModel<Person>(filterList);
        tblNames.setSelectionModel(selectionModel);

        tblNames.setModel(model);
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jLabel1 = new javax.swing.JLabel();
        txtFilter = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        tblNames = new javax.swing.JTable();
        btnDelete = new javax.swing.JButton();
        btnReload = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("GlazedLists test");

        jLabel1.setText("Filter");

        tblNames.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null},
                {null, null, null, null}
            },
            new String [] {
                "Title 1", "Title 2", "Title 3", "Title 4"
            }
        ));
        jScrollPane1.setViewportView(tblNames);

        btnDelete.setText("Delete");
        btnDelete.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnDeleteActionPerformed(evt);
            }
        });

        btnReload.setText("Reload data");
        btnReload.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnReloadActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(layout.createSequentialGroup()
                        .add(jLabel1)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(txtFilter))
                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 388, Short.MAX_VALUE)
                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
                        .add(btnReload)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .add(btnDelete)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .addContainerGap()
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(jLabel1)
                    .add(txtFilter, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 240, Short.MAX_VALUE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(btnDelete)
                    .add(btnReload))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {                                          
        if (!selectionModel.isSelectionEmpty()) {
            eventList.removeAll(selectionModel.getSelected());
        }
    }                                         

    private void btnReloadActionPerformed(java.awt.event.ActionEvent evt) {                                          
        eventList.clear();
        loadData();
    }                                         

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {

        /*
         * Create and display the form
         */
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MyFrame().setVisible(true);
            }
        });
    }
    // Variables declaration - do not modify                     
    private javax.swing.JButton btnDelete;
    private javax.swing.JButton btnReload;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTable tblNames;
    private javax.swing.JTextField txtFilter;
    // End of variables declaration                   
}
public class Person {

    private String firstname;
    private String lastname;

    public Person() {
    }

    public Person(String firstname, String lastname) {
        this.firstname = firstname;
        this.lastname = lastname;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

}