Как получить текущую отфильтрованную TableModel

У меня есть этот код ниже, в котором после события mouseClick он фильтрует строки на основе JList getSelectedItem().toString(), вот код:

try{
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(easypath.doctorBusiness_table.getModel());
        easypath.doctorBusiness_table.setRowSorter(rowSorter);
        String selected = easypath.drname_jlist.getSelectedValue().toString();
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));

    }

Он работает нормально и фильтрует строки на основе выбранной строки.


Но я также хочу отфильтровать отфильтрованную модель на основе дат, хотя фильтрация по дате отлично работает на DefaultTableModel, но когда я пытаюсь передать текущую модель таблицы, она не работает.

Итак, я надеюсь, что смог объяснить свою проблему здесь, так как мне нужно пройти отфильтрованную TableModelдля фильтрации даты. Любые предложения помогут.

Спасибо за ваше время

ОБНОВИТЬ

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.RowFilter;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class testFilter extends javax.swing.JFrame {

    public testFilter() {
        initComponents();
    }

public void dateSearch() {
    try {
        DateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        String string1 = "01/07/2015";
        Date startDate = format.parse(string1);
        System.out.println(startDate);

        String string2 = "31/07/2015";
        Date endDate = format.parse(string2);
        System.out.println(endDate);

        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel());
        dataTable.setRowSorter(rowSorter);

        List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(2);
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
        RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
        rowSorter.setRowFilter(rf);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public void dateString_Search(){
    try {
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel()); //  String Filtering 
        dataTable.setRowSorter(rowSorter);                                                 //  table here
        String selected = "Nissan SUV";                                                    //  to get
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));                  //  current TableModel 

        JOptionPane.showMessageDialog(null, dataTable.getRowCount()); // <--- For checking current Row Count

        DateFormat format = new SimpleDateFormat("dd/MM/yyyy");

        String string1 = "01/07/2015";
        Date startDate = format.parse(string1);
        System.out.println(startDate);
        String string2 = "31/07/2015";
        Date endDate = format.parse(string2);
        System.out.println(endDate);

        TableRowSorter<TableModel> filteredRowSorter = new TableRowSorter<>(dataTable.getModel()); //<-- Getting the current table Model After String Search
        dataTable.setRowSorter(filteredRowSorter); 
        List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(2);
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
        filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
        RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
        filteredRowSorter.setRowFilter(rf);


    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}



private void initComponents() {

    jScrollPane1 = new javax.swing.JScrollPane();
    dataTable = new javax.swing.JTable();
    dateSearch_btn = new javax.swing.JButton();
    stringSearch_btn = new javax.swing.JButton();
    dateStringSearch_btn = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setResizable(false);

    dataTable.setModel(new javax.swing.table.DefaultTableModel(
        new Object [][] {
            {"Nissan Micra", new Date(), "20000"},
            {"Nissan SUV", new Date(), "30000"},
            {"Nissan SUV", new Date(), "40000"},
            {"Nissan SUV", new Date(), "50000"},
            {"Nissan SUV", new Date(), "50000"},
            {"Ford Mustang", new Date(), "70000"},
            {"Ford Cobra", new Date(), "70000"},
            {"Nissan SUV", new Date(), "40000"},
            {"Nissan SUV", new Date(), "60000"},
            {"Nissan SUV", new Date(), "65000"},
            {"Nissan SUV", new Date(), "70000"},
            {"Tata Sumo", new Date(), "70000"}
        },
        new String [] {
            "Name", "Date", "Rate"
        }
    ));
    putDateInTable();
    jScrollPane1.setViewportView(dataTable);

    dateSearch_btn.setText("Date Search");
    dateSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            dateSearch_btnActionPerformed(evt);
        }
    });

    stringSearch_btn.setText("String Search");
    stringSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            stringSearch_btnActionPerformed(evt);
        }
    });

    dateStringSearch_btn.setText("Date+String");
    dateStringSearch_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            dateStringSearch_btnActionPerformed(evt);
        }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 463, Short.MAX_VALUE)
                .addGroup(layout.createSequentialGroup()
                    .addComponent(dateSearch_btn)
                    .addGap(90, 90, 90)
                    .addComponent(stringSearch_btn)
                    .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(dateStringSearch_btn)))
            .addContainerGap())
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 223, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGap(18, 18, 18)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(dateSearch_btn)
                .addComponent(stringSearch_btn)
                .addComponent(dateStringSearch_btn))
            .addContainerGap(25, Short.MAX_VALUE))
    );

    pack();
}

private void stringSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                                 
    try {
        TableRowSorter<TableModel> rowSorter = new TableRowSorter<>(dataTable.getModel());
        dataTable.setRowSorter(rowSorter);
        String selected = "Nissan SUV";
        rowSorter.setRowFilter(RowFilter.regexFilter("(?i)" + selected));
        JOptionPane.showMessageDialog(null, dataTable.getRowCount());

    } catch (Exception e) {
        JOptionPane.showMessageDialog(null, e);
    }
}

private void dateSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                               
    dateSearch();
}

private void dateStringSearch_btnActionPerformed(java.awt.event.ActionEvent evt) {                                                     
    dateString_Search();
}

private void putDateInTable() {
    Date formatDate = new Date();
    Calendar c = Calendar.getInstance();
    c.setTime(formatDate);
    c.add(Calendar.DATE, - 1);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 0, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +5);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 1, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +1);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 2, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, - 16);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 3, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +30);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 4, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +55);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 5, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +155);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 6, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -23);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 7, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -22);

    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 8, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -21);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 9, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -29);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 10, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, -50);
    formatDate = c.getTime();
    dataTable.setValueAt(formatDate, 11, 1);
    c.setTime(formatDate);
    c.add(Calendar.DATE, +100);


}

public static void main(String args[]) {

    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new testFilter().setVisible(true);
        }
    });
}
private javax.swing.JTable dataTable;
private javax.swing.JButton dateSearch_btn;
private javax.swing.JButton dateStringSearch_btn;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JButton stringSearch_btn;
}

Вот измененный код для фильтрации, Создал eventListeners dateSearch, stringSearch и dateStringSearch. Первые два работают нормально, но третий не работает должным образом, даже если я пытаюсь создать текущую модель. Пожалуйста, предложите, спасибо


person mustangDC    schedule 18.07.2015    source источник
comment
@camickr, вы ошиблись, я бы попросил перечитать вопрос до конца, здесь вопрос в дате   -  person mustangDC    schedule 18.07.2015
comment
I need to filter the filtered rows - вам нужен andFilter, как было продемонстрировано в вашем последнем вопросе. Когда вы используете && if оператор if, вы ограничены только двумя условиями или можете использовать более двух условий?   -  person camickr    schedule 18.07.2015
comment
Да, вы абсолютно правы, но то, что я здесь спросил, не полностью зависит от дат, я также упомянул здесь о JList, где проблема не в датах, а в Я НЕ ПОЛУЧАЮ ФИЛЬТРИРОВАННУЮ ТАБЛИЧНУЮ МОДЕЛЬ в зависимости от строки, переданной из формы JList, для которой я предоставил полную информацию   -  person mustangDC    schedule 18.07.2015
comment
@camickr, надеюсь, я успешно объяснил, чего я пытаюсь здесь достичь   -  person mustangDC    schedule 18.07.2015
comment
Я не говорю о датах. У вас есть условие фильтра, которое вы создали из выбранного элемента в JList, затем у вас есть еще два условия для дат, поэтому у вас есть andFilter с 3 условиями. Нельзя делать два отдельных фильтра, нужно объединить все условия в один фильтр.   -  person camickr    schedule 18.07.2015
comment
Я полностью понимаю, что вы пытаетесь здесь заявить, но это не работает, потому что логика программы не может предоставить модель отфильтрованной таблицы, которая является входом для фильтрации даты (отлично работает)   -  person mustangDC    schedule 18.07.2015
comment
I completely understand what you are trying to state here - Не думаю. does not work because the program logic is unable to give the filtered table model, - вы не можете предоставить отфильтрованную модель таблицы (если только вы не хотите скопировать все данные и создать новую TableModel для отображения в таблице. Вы пытаетесь отфильтровать исходную TableModel с 3 условиями, а не с 1.   -  person camickr    schedule 18.07.2015
comment
Хорошо, теперь я получил то, что вы сказали. Попробую сейчас и дам вам знать, спасибо :)   -  person mustangDC    schedule 18.07.2015
comment
Не могли бы вы помочь с конструкцией, так как я пытался передать фильтр строки таблицы фильтру даты, но он не работает, если вы хотите, я могу обновить вопрос и опубликовать то, что я пытался   -  person mustangDC    schedule 18.07.2015
comment
@camickr: ПОМОГИТЕ МНЕ С КОНСТРУКЦИЕЙ КОДА О ТЕКУЩЕЙ ФИЛЬТРАЦИИ ROOWFILTERING? Я НОВИЧОК В JAVA И В НАСТОЯЩЕЕ ВРЕМЯ ПЫТАЮСЬ РАСШИРИТЬ СВОИ ЗНАНИЯ. БУДЕМ ОЧЕНЬ БЛАГОДАРНЫ, ЕСЛИ ВЫ ПРЕДЛОЖИТЕ МНЕ КОД ДЛЯ ТРЕТЬЕГО ФИЛЬТРА   -  person mustangDC    schedule 19.07.2015
comment
i AM NEW TO JAVA AND I AM CURRENTLY TRYING TO EXPAND MY KNOWLEDGE. — начните с изучения того, как создать SSCCE, чтобы продемонстрировать проблему. Смысл SSCCE в том, чтобы упростить задачу. Итак, создайте фрейм с таблицей (и несколькими строками жестко заданных данных) и тремя кнопками. Первая кнопка будет простой фильтр по ключевому слову. Вторая кнопка будет фильтровать по диапазону дат. Третья кнопка объединит первый и второй фильтры в фильтр и отфильтрует по 3 условиям. Покажите нам усилия, которые вы приложили, и мы можем внести предложения. Вы не научитесь, если мы напишем код для вас.   -  person camickr    schedule 19.07.2015
comment
Сначала настройте фильтры, работающие с условиями жесткого кода. Это жесткий код строки фильтра. Как только вы поймете, что базовая концепция работает, вы можете перейти к созданию динамического фильтра, получив строку фильтра из JList. То же и с датами. Используйте жестко закодированные даты, а затем предоставьте компонент Swing, чтобы пользователь мог изменить диапазон данных.   -  person camickr    schedule 19.07.2015
comment
размещение SSCCE как можно скорее   -  person mustangDC    schedule 19.07.2015
comment
главное, я не могу добавить третий фильтр. В любом случае я буду публиковать свой код,   -  person mustangDC    schedule 19.07.2015
comment
Обновил код, как вы предложили. Пожалуйста, смотрите. @camickr   -  person mustangDC    schedule 20.07.2015


Ответы (2)


Почему вы пытаетесь получить TableModel после поиска строки? Я сказал, что ты не можешь этого сделать unless you want to copy all the data and create a new TableModel.

TableModel не меняется, когда вы выполняете фильтрацию JTable. Все данные по-прежнему хранятся в TableModel. Что меняется, так это View. JTable отображает только отфильтрованные строки.

Почему ваш код фильтра не похож на код из руководства Swing по фильтрации? В своем коде вы создаете новый TableRowSorter и добавляете его в таблицу. В учебнике Swing они просто сбрасывают фильтр в TableRowSorter, используя метод setRowFilter(...). Это незначительно, но это демонстрирует мне, что вы не читали учебник, а если и читали, то почему вы изменили код, чтобы сделать его более сложным?

В своих комментариях я предложил you have an "andFilter" with 3 conditions. я пытался объяснить это несколькими способами, сравнивая его с оператором if с 3 условиями. Почему ваш «andFilter» имеет только два условия, когда вы выполняете «поиск даты/строки»?

Я скопировал код из «поиска по дате» и внес следующие изменения, чтобы создать фильтр по дате/строке:

List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(3);
String selected = "Nissan SUV";
filters.add(RowFilter.regexFilter("(?i)" + selected)); // added the string filter
filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.AFTER, startDate));
filters.add(RowFilter.dateFilter(RowFilter.ComparisonType.BEFORE, endDate));
RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
rowSorter.setRowFilter(rf);

Теперь у вас есть "andFilter" с тремя условиями.

Однако лучше было бы создать такие методы, как getStartDateFilter(), getEndDateFilter(), getStringFilter(), чтобы не дублировать код. Затем вы можете построить фильтр следующим образом:

List<RowFilter<Object, Object>> filters = new ArrayList<RowFilter<Object, Object>>(3);
filters.add(getStringFilter());
filters.add(getStartDateFilter());
filters.add(getEndDateFilter();
RowFilter<Object, Object> rf = RowFilter.andFilter(filters);
rowSorter.setRowFilter(rf);
person camickr    schedule 20.07.2015
comment
О, извините за ошибку, я попробовал 3 andfilters, и все, что вы сказали, конечно, правильно. Клиент требует разработать такой код. Таким образом, он может видеть таблицу тремя разными способами. - person mustangDC; 21.07.2015
comment
Еще одна вещь, которую я ошибочно разместил в этом коде, когда пытался узнать, почему таблица не может дать мне текущую модель, тогда как она дает мне текущее количество строк. В public void dateString_Search(){} я дал JOptionPane, чтобы показать текущее количество строк. Но в любом случае теперь я узнал, что это будет DefaultTableModel всегда. До меня еще далеко. Но огромное спасибо - person mustangDC; 21.07.2015
comment
@mustangDC, требование 3 фильтров нормально. Как устроен код, решать вам. Повторно используемый код проще в обслуживании и обеспечивает гибкость. Отфильтрованная таблица просто хранит список (или, возможно, массив) индексов в реальной TableModel. То же, что и при изменении порядка столбцов. TableModel не меняется. Таблица просто отслеживает порядок столбцов. Вот как работает конструкция Model-View-Controller. Модель хранит данные, а в Swing the View (который представляет собой комбинированный View-Controller) отображает данные. Представление может отображать данные, как хочет - person camickr; 21.07.2015

К сожалению, дизайн функциональности JTable рассматривает TableSorter вместе с лежащим в его основе RowFilter как немодельную функциональность. В результате он не создает обертывающий экземпляр TableModel. Вместо этого JTable работает напрямую с сортировщиком для правильного отображения строк.

В качестве хака вы можете создать свою собственную TableModel, которая обертывает всю базовую JTable, слушает ее обновления и возвращает значения ячеек, как они появляются в JTable. В зависимости от того, где вы собираетесь использовать такую ​​модель, это может быть ужасной или блестящей идеей. Взгляните на пример ниже, чтобы понять, о чем я говорю. Обратите внимание, что функции прослушивания и запуска событий в приведенном ниже примере не выполняются должным образом. Требуется гораздо больше работы, чтобы правильно слушать и реагировать на различные события модели и пользовательского интерфейса, поэтому дата в модели всегда отражает содержимое JTable. С архитектурной точки зрения эту модель нельзя считать надлежащим классом модели, но она позволяет другим таблицам отображать данные синхронно с базовым JTable.

public class UIBasedTableModel extends AbstractTableModel {
    private final JTable _underlyingTable;

    public UIBasedTableModel(JTable underlyingTable) {
        _underlyingTable = underlyingTable;
        _underlyingTable.addPropertyChangeListener("sorter", new PropertyChangeListener() {

            @Override
            public void propertyChange(PropertyChangeEvent evt) {
               fireTableDataChanged();
            }
        });
        _underlyingTable.getModel().addTableModelListener(new TableModelListener() {

            @Override
            public void tableChanged(TableModelEvent e) {
                fireTableDataChanged();
            }
        });
    }

    @Override
    public int getRowCount() {
        return _underlyingTable.getRowCount();
    }

    @Override
    public int getColumnCount() {
        return _underlyingTable.getColumnCount();
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        return _underlyingTable.getValueAt(rowIndex, columnIndex);
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        return _underlyingTable.getColumnClass(columnIndex);
    }

    @Override
    public String getColumnName(int columnIndex) {
        return _underlyingTable.getColumnName(columnIndex);
    }
}

Другой альтернативой может быть реализация аналогичной функции сортировки/фильтрации самостоятельно. Это также может быть хорошей и плохой идеей, поскольку вам нужно будет правильно интегрировать сортировку в TableUI.

Я был бы рад уточнить больше, но должен знать ваши требования.

person ATrubka    schedule 20.07.2015