Question

I have created a table with GlazedLists to be able to filter the table for searching purposes. Now the question is how to delete, add, or update rows in this table. I did search the API but couldn't figure it out.

Can anyone demonstrate how to achieve for deleting, adding, updating with a simple example?

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

Edited:

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
Était-ce utile?

La solution

If you make changes to the EventList then those changes will be propagated to the JTable via the table model. (That is, if you add a new object to that list, remove one, or update one, then the changes take place automatically. Hence the "Event" prefix - events to the list are communicated to the model.)

So chances are you'll need to keep a reference to your EventList to ensure its accessible to parts of your code outside of retrieveArtikelTable() in your case.

I feel the screencasts at GlazedLists Developer are excellent at covering all the essential topics.

Edit: just a reminder how you can make the list an instance variable so that it can be accessed in any method, not just the one which constructs the table.

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

    }
}

Edit #2: I've included a more complete example in order to give an illustration of how you should properly handle selection using the EventSelectionModel, which allows you to know exactly which rows are selected at any given time, even when a filter has been applied.

Screenshot of sample app

I've copied a file which was partially generated using the Netbeans GUI builder. But the key things to note are:

  1. Declaration of the EventSelectionModel as an instance variable so that it can be accessed elsewhere in the class.

  2. btnDeleteActionPerformed() method. This is what happens when the Delete button is pressed. First I check whether any row is selected. If so, get the selected items (returned as an Eventlist) and simply remove them from the master list.

Here's the sample code for MyFrame.java

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                   
}

I'm using a Person class in my example, and it's a very simple POJO:

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;
    }

}

Personally I'd recommend keeping your data loading separate from the method which creates your table. I've used the loadData() method which populates the list. If there's a no data to be loaded, or a problem with the file you're loading from then the table is still created but there's nothing in it because the list remains empty.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top