Фильтрация - Как заставить JTable отображать x количество полей

У меня есть JTable, который использует RowFilter для фильтрации полей, но я хочу, чтобы эти результаты были сужены до суммы x, например, например. 5


person Rated    schedule 18.02.2014    source источник
comment
Функциональность, которая вам понадобится, чтобы определить это, поддерживается в private методах в DefaultRowSorter... это должно понравиться   -  person MadProgrammer    schedule 19.02.2014
comment
хм.. что ты имеешь в виду? 5 rows (как интерпретировал и ответил @MadProgrammer)? И если да, то как вы хотите определить, какие 5 строк?   -  person kleopatra    schedule 19.02.2014


Ответы (1)


Это очень весело.

По сути, RowFilter не может знать, где RowSorter захочет проверить наличие включенных строк, поэтому вы не можете поместить какой-то «счетчик» в RowFilter и просто начать возвращать false по истечении заданного предела. RowSorter также не гарантирует, что он действительно будет искать включенные строки в любом порядке или как целую группу... например, он может проверять случайные строки...

Что вы можете сделать, так это создать свой собственный RowSorter и переопределить его метод sort, который обычно вызывается всякий раз, когда базовая модель каким-либо образом изменяется или изменяется сама ссылка на модель. Здесь вы можете сказать RowFilter, что ему нужно сбросить счетчик.

Сортировщик строк

По сути, это реализация TableRowSorter, которая ищет специальный тип RowFilter и вызывает свой метод reset всякий раз, когда он вызывается, это предназначено для сброса количества строк, которые были отфильтрованы, до 0.

public class MyRowSorter extends TableRowSorter<TableModel> {

    public MyRowSorter(TableModel model) {
        super(model);
    }

    @Override
    public void sort() {
        RowFilter<? super TableModel, ? super Integer> filter = getRowFilter();
        if (filter instanceof LimitedRowFilter) {
            LimitedRowFilter lrf = (LimitedRowFilter) filter;
            lrf.reset();
        }
        super.sort(); 
    }

}

LimitedRowFilter

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

Он также предоставляет метод reset, используемый RowSorter

Это может использовать некоторые дополнительные функции, такие как includeAndIncrement, которые могут возвращать true, если строка должна быть включена, или false, если она превышает лимит количества строк, и автоматически увеличивает lineCount...

public abstract class LimitedRowFilter<M, I> extends RowFilter<M, I> {

    private int lineLimit;
    private int lineCount;

    public void reset() {
        lineCount = 0;
    }

    public int getLineCount() {
        return lineCount;
    }

    public void incrementLineCount() {
        lineCount++;
    }

    public int getLineLimit() {
        return lineLimit;
    }

    public void setLineLimit(int lineLimit) {
        this.lineLimit = lineLimit;
    }

    public LimitedRowFilter(int lineLimit) {
        this.lineLimit = lineLimit;
    }

    public LimitedRowFilter() {
    }

}

Пример реализации LimitedRowFilter

Это простой пример LimitedRowFilter в действии, он в основном будет возвращать true для каждой строки до максимально допустимого предела...

public class MyRowFilter extends LimitedRowFilter<TableModel, Integer> {

    public MyRowFilter() {
        super();
    }

    public MyRowFilter(int limit) {
        super(limit);
    }

    @Override
    public boolean include(Entry<? extends TableModel, ? extends Integer> entry) {

        boolean included = true;
        // Do you own checking here to determine if the row should be included or
        // not
        if (included) {
            if (getLineCount() < getLineLimit()) {
                incrementLineCount();
            } else {
                included = false;
            }
        }

        return included;

    }

}

Работающий пример

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.swing.DefaultRowSorter;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowFilter;
import javax.swing.RowSorter;
import javax.swing.SortOrder;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

public class LimitedTableRowFilter {

    public static void main(String[] args) {
        new LimitedTableRowFilter();
    }

    public LimitedTableRowFilter() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }
                DefaultTableModel model = new DefaultTableModel(new Object[]{"A"}, 0);
                for (int index = 0; index < 100; index++) {
                    model.addRow(new Object[]{index});
                }
                JTable table = new JTable(model);
                MyRowSorter sorter = new MyRowSorter(model);
                MyRowFilter filter = new MyRowFilter(10);

                sorter.setRowFilter(filter);
                table.setRowSorter(sorter);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(table));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}

Отказ от ответственности

Я буду первым, кто признает, что это далеко не идеальное решение, но оно лучше, чем копирование всего исходного кода для DefaultRowSorter и TableRowSorter только для того, чтобы мы могли получить доступ к методам private, которые нам понадобятся для реализации функциональности. непосредственно в самом сортировщике.

Я провел лишь ограниченное тестирование, так что вам, возможно, придется сделать некоторые собственные настройки...

person MadProgrammer    schedule 19.02.2014
comment
@mKorbel О какой части (моего ответа) вы говорите? - person MadProgrammer; 19.02.2014
comment
для улучшения LimitedRowFilter - person mKorbel; 19.02.2014
comment
с трудом понимаю ответ (на самом деле, это больше похоже на то, что трудно понять вопрос ;-) - вы реализуете какую-то странную разбивку на страницы? - person kleopatra; 19.02.2014
comment
@mKorbel Ах, да, отличные примеры. Я предполагал, что, поскольку ОП сказал, что у них уже есть RowFilter, я не стал полностью реализовывать логику в своем собственном: P - person MadProgrammer; 19.02.2014
comment
@kleopatra Не собирался. По сути, когда вызывается sort, он сбрасывает фильтр, когда фильтр успешно обработал n количество строк, он просто возвращает false на каждый другой запрос, это некрасиво, не уверен на 100%, что он работает в 100% случаев. , но моей альтернативой было сделать копию DefaultRowSorter... и примерно там я решил попробовать что-то еще... - person MadProgrammer; 19.02.2014
comment
@kleopatra Насколько я понимаю, OP хочет отобразить до n количества совпадений ... не все совпадающие строки, но что я знаю: P - person MadProgrammer; 19.02.2014
comment
ваше решение выглядит хорошо, но оно кажется странным требованием: чтобы пользователь сортировал и видел различный контент? Боже мой... пахнет плохим пользовательским интерфейсом, @Rated - person kleopatra; 19.02.2014
comment
фактически ничего не закодировав: я бы попытался сбросить фильтр в RowSorterListener .. хм. - person kleopatra; 19.02.2014
comment
@kleopatra Мне пришлось бы протестировать это дальше, так как у меня были очень простые тестовые данные, но когда я их отсортировал, я получил те же результаты, поэтому кажется, что сначала они отфильтрованы, а затем отсортированы на основе отфильтрованных результатов, но это сойдет к реализации сортировщика... - person MadProgrammer; 19.02.2014
comment
@kleopatra ‹face plant› - даже не подумал о поддержке слушателей :P - person MadProgrammer; 19.02.2014
comment
да, вы правы: фильтрация происходит по модели до сортировки и происходит сверху вниз. Что является деталью реализации... - person kleopatra; 19.02.2014