Tutorial : SwingX Filter Table dengan lebih dari 1 Kondisi (Part 2)

Seperti janji saya pada bagian sebelumnya Tutorial : SwingX Filter Table dengan lebih dari 1 Kondisi (Part 1) yaitu membuat Kondisi filter table yang otomatis dari nama kolom setiap table. Konsepnya kurang lebih sama pada bagian pertama, yang membedakan hanyalah pengambilan data untuk setiap ComboBox. Perubahan yang akan kita lakukan adalah menghapus static string conditions, FIRST_NAME, LAST_NAME, melakukan modifikasi pada fungsi dengan nama loadComboCondition(), menambahkan fungsi getConditionFromTable() serta memodifikasi fungsi  dengan nama createSearchFilter(). Untuk melihat perubahan apa saja yang dilakukan pada source code pada bagian sebelumnnya  silahkan kalian pelajari dibawah ini.



package org.motekar.latihan.swingX;

import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.regex.Pattern;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import org.jdesktop.swingx.JXComboBox;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.JXTextField;
import org.jdesktop.swingx.autocomplete.AutoCompleteDecorator;
import org.jdesktop.swingx.combobox.ListComboBoxModel;

/**
 *
 * @author Muhamad Wibawa
 */
public class FilterTableExtendedExample2 extends JFrame {

    private JXTable table = new JXTable();
    private static String[] peopleName = new String[]{"Adam Barclay",
        "Aleksandras Novikovas", "Bill Snyder", "Bryan Young",
        "Dan Leuck", "Daniel Lewis", "Daniel Olivera",
        "David Bolsover", "David Hall", "Diego Gil",
        "Dirk Hillbrecht", "Doug Berkland",
        "Erik Vickroy", "Fred Lavigne",
        "Gilles Philippart", "Haris Peco",
        "Jan Bosenberg", "James Morgan",
        "Jeanette Winzenburg", "Mario Cesar",
        "Mark Davidson", "Mark Fortner", "Mark Thornton",
        "Matt Nathan", "Michael Bush", "Michael Swindle",
        "Neil Weber", "Nicola Ken Barozzi", "Noel Grandin",
        "Oleg Minukhin", "Patrick Gotthardt", "Patrick Wright",
        "Pierre Le Lannic", "Ray Turnbull", "Ricardo Lopes",
        "Richard Bair", "Richard Osbaldeston", "Robert Eden", "Robert Stone",
        "Ronald Tetsuo Miura", "Salvan Haas", "Scott Delap",
        "Sean McNamara", "Simon Morris", "Shai Almog",
        "Thomas Bierhance", "Wade Chandler", "Waldemar Klaczynski",
        "Walter Wang", "Xavier Hanin", "Yannick Menager"};
    private JXTextField fieldSearch = new JXTextField();
    private JXTextField fieldSearch2 = new JXTextField();
    private JXComboBox comboCondition = new JXComboBox();
    private JXComboBox comboCondition2 = new JXComboBox();
    //
    private static final String NULL = " ";
    private static final String FIRST_NAME = "First Name";
    private static final String LAST_NAME = "Last Name";
    private RowFilter<Object, Object> searchFilter;
    private RowFilter<Object, Object> searchFilter2;

    public FilterTableExtendedExample2() {
        construct();
    }

    private void construct() {

        fieldSearch.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                updateSearchFilter();
            }

            public void removeUpdate(DocumentEvent e) {
                updateSearchFilter();
            }

            public void changedUpdate(DocumentEvent e) {
                updateSearchFilter();
            }
        });

        fieldSearch2.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void insertUpdate(DocumentEvent e) {
                updateSearchFilter();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                updateSearchFilter();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                updateSearchFilter();
            }
        });

        fillTableData();

        loadComboCondition();

        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        this.setTitle("Filter Table Extended Examples");
        this.setPreferredSize(new Dimension(500, 500));
        this.setDefaultCloseOperation(EXIT_ON_CLOSE);

        this.getContentPane().setLayout(new BorderLayout());
        this.getContentPane().add(createMainPanel(), BorderLayout.CENTER);

    }

    protected JPanel createMainPanel() {
        FormLayout lm = new FormLayout(
                "pref,10px,pref,5px,fill:default:grow,10px",
                "pref,5px,pref,5px,fill:default:grow,5px,pref,5px");
        DefaultFormBuilder builder = new DefaultFormBuilder(lm);
        builder.setDefaultDialogBorder();

        JScrollPane scPane = new JScrollPane();
        scPane.setViewportView(table);

        CellConstraints cc = new CellConstraints();

        builder.addLabel("Cari", cc.xy(1, 1));
        builder.add(comboCondition, cc.xy(3, 1));
        builder.add(fieldSearch, cc.xy(5, 1));

        builder.add(comboCondition2, cc.xy(3, 3));
        builder.add(fieldSearch2, cc.xy(5, 3));

        builder.add(scPane, cc.xywh(1, 5, 5, 2));

        return builder.getPanel();
    }

    private ArrayList<String> getConditionFromTable() {
        ArrayList<String> conditions = new ArrayList<String>();

        if (table != null) {
            int columnCount = table.getColumnCount();
            if (columnCount > 0) {
                conditions.add(" "); // add Empty String
                for (int i = 0; i < columnCount; i++) {
                    Object obj = table.getColumnModel().getColumn(0).getHeaderValue();
                    if (obj instanceof String) {
                        conditions.add((String)obj);
                    }
                }
            }

        }

        return conditions;
    }

    private void loadComboCondition() {
        comboCondition.setModel(new ListComboBoxModel<String>(getConditionFromTable()));
        AutoCompleteDecorator.decorate(comboCondition);

        comboCondition2.setModel(new ListComboBoxModel<String>(getConditionFromTable()));
        AutoCompleteDecorator.decorate(comboCondition2);

    }

    private void updateSearchFilter() {

        String conditionText = (String) comboCondition.getSelectedItem();
        String conditionText2 = (String) comboCondition2.getSelectedItem();

        if (conditionText != null && !conditionText.equals(NULL)) {
            searchFilter = createSearchFilter(fieldSearch.getText(), conditionText);
        }

        if (conditionText2 != null && !conditionText2.equals(NULL)) {
            searchFilter2 = createSearchFilter(fieldSearch2.getText(), conditionText2);
        }

        updateFilters();
    }

    private void updateFilters() {
        if ((searchFilter != null) && (searchFilter2 != null)) {
            List<RowFilter<Object, Object>> filters =
                    new ArrayList<RowFilter<Object, Object>>(2);
            filters.add(searchFilter);
            filters.add(searchFilter2);
            RowFilter<Object, Object> comboFilter = RowFilter.andFilter(filters);
            table.setRowFilter(comboFilter);
        } else if (searchFilter != null) {
            table.setRowFilter(searchFilter);
        } else {
            table.setRowFilter(searchFilter2);
        }
    }

    private void fillTableData() {
        DefaultTableModel model = new DefaultTableModel();

        model.addColumn("First Name");
        model.addColumn("Last Name");


        for (String p : peopleName) {

            StringTokenizer token = new StringTokenizer(p, " ");

            String first = token.nextToken();
            String last = token.nextToken();

            model.addRow(new Object[]{first, last});
        }


        table.setModel(model);
    }

    private RowFilter<Object, Object> createSearchFilter(final String filterString, final String conditionText) {
        return new RowFilter<Object, Object>() {

            @Override
            public boolean include(Entry<? extends Object, ? extends Object> entry) {
                DefaultTableModel model = (DefaultTableModel) entry.getModel();
                
                boolean matches = false;
                Pattern p = Pattern.compile("(?i).*" + filterString + ".*",
                        Pattern.CASE_INSENSITIVE | Pattern.DOTALL);

                String condition = null;
                
                int columnCount = table.getColumnCount();
                
                for (int i=0;i<columnCount;i++) {
                    Object obj = table.getColumnModel().getColumn(0).getHeaderValue();
                    String headerValue = "";
                    if (obj instanceof String) {
                        headerValue =  (String)obj;
                    }
                    
                    if (conditionText.equals(headerValue)) {
                        condition = (String) model.getValueAt(((Integer) entry.getIdentifier()).intValue(), 0);
                    }
                }

                
                if (condition != null) {
                    matches = p.matcher(condition).matches();
                }

                return matches;
            }
        };
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            public void run() {
                JFrame test = new FilterTableExtendedExample();
                test.pack();
                test.setLocationRelativeTo(null);
                test.setVisible(true);
            }
        });
    }
}


Dengan modifikasi kode diatas, data filter pada ComboBox akan mengikuti pada jumlah kolom pada table yang telah kalian definisikan sesuai kebutuhan. Sekian, penjelasan singkat dari saya, semoga bermanfaat dan semoga kita dapat berjumpa kembali pada lain kesempatan, jangan lupa kasih komentar.

Wassalam,
Muhamad Wibawa