Фильтрация JTable в двух столбцах

Я хотел бы внедрить 2 разных фильтра строк в свой JTable. Я реализовал один, который, кажется, работает безупречно, но мой второй, похоже, не работает. В следующем коде я закомментировал несколько частей данных и вставил примеры данных, чтобы он работал без других файлов.

import javax.swing.*;
import java.awt.*;
import java.io.*;
import java.lang.*;
import java.awt.event.*;
///////////
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;
import javax.swing.text.Document;
import javax.swing.table.TableRowSorter;

public class CompFrame extends JFrame implements ActionListener
{
/*AthleteList a = new AthleteList();
TrainingRList r= new TrainingRList();
TrainingSList s= new TrainingSList();
TrainingCList c= new TrainingCList();
TrainingPList p= new TrainingPList();
*/
JFrame myMainWindow = new JFrame("This is my title");

JPanel  firstPanel = new JPanel(); //a panel for first tab

//first panel components
JScrollPane myScrollTable;
/*JLabel Logol = new JLabel();
ImageIcon imgAddAthleteLogo = new ImageIcon("AddAthletelogo.png"); //Declares as an ImageIcon
Image tempOriginal = imgAddAthleteLogo.getImage(); //Declares the ImageIcon as an Image
Image smallerLogo = tempOriginal.getScaledInstance(1280,120,0); //Rescales the Image to specified size
ImageIcon smalltest= new ImageIcon(smallerLogo); //Creates a new ImageIcon with the rescaled image
JLabel Logo = new JLabel(smalltest); //Puts the new ImageIcon inside a JLabel so that it can be displayed */
JButton btnAdminOnly = new JButton();
JButton btnTPersonal = new JButton();
JButton btnTRunning = new JButton();
JButton btnTCycling = new JButton();
JButton btnTSwimming = new JButton();
//end first panel
JTextField filterAthID;
JTextField filterForeName;
TableRowSorter sorter;
JLabel AthleteID = new JLabel();
JLabel ForeName = new JLabel();
///////////////

public void runGUI()
{
    /*//////////////
    a.readAthleteDataFromFile();
    c.readCycling();
    p.readPersonal();
    r.readRunning();
    s.readSwimming();
    //////////////
    a.athData();
    //c.tcData();
    //p.tpData();
    //r.trData();
    //s.tsData();
    //////////////*/

    myMainWindow.setBounds(10, 10, 1296, 756); //set position, then dimensions
    myMainWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    myMainWindow.setLayout(new GridLayout(1,1));

    createFirstPanel(); //call method to create each panel

    myMainWindow.getContentPane().add(firstPanel); //adds the tabbedpane to mainWindow

    myMainWindow.setVisible(true); //make the GUI appear
}

public void createFirstPanel()
{
    firstPanel.setLayout(null);
    /*
    Logo.setLocation(0,0); //Sets the location
    Logo.setSize(1280,120); //Sets the size
    firstPanel.add(Logo); //Adds it to the panel
    */
    AthleteID.setLocation(200,120); //Sets the location
    AthleteID.setSize(150,26); //Sets the size
    AthleteID.setText("Athlete ID Search:");
    firstPanel.add(AthleteID); //Adds it to the panel

    ForeName.setLocation(731,120); //Sets the location
    ForeName.setSize(150,26); //Sets the size
    ForeName.setText("Athlete Name Search:");
    firstPanel.add(ForeName); //Adds it to the panel

    btnAdminOnly.setLocation(0,120);
    btnAdminOnly.setSize(200,50);
    btnAdminOnly.setText("Display Athlete Data Admin");
    btnAdminOnly.addActionListener(this);
    firstPanel.add(btnAdminOnly);

    btnTPersonal.setLocation(0,170);
    btnTPersonal.setSize(200,50);
    btnTPersonal.setText("Display Athlete Data");
    btnTPersonal.addActionListener(this);
    firstPanel.add(btnTPersonal);

    btnTRunning.setLocation(0,220);
    btnTRunning.setSize(200,50);
    btnTRunning.setText("Display Running Data");
    btnTRunning.addActionListener(this);
    firstPanel.add(btnTRunning);

    btnTCycling.setLocation(0,270);
    btnTCycling.setSize(200,50);
    btnTCycling.setText("Display Cycling Data");
    btnTCycling.addActionListener(this);
    firstPanel.add(btnTCycling);

    btnTSwimming.setLocation(0,320);
    btnTSwimming.setSize(200,50);
    btnTSwimming.setText("Display Swimming Data");
    btnTSwimming.addActionListener(this);
    firstPanel.add(btnTSwimming);

    String[] sHeaders = {"Athlete ID","Forename","Surname"}; 
    String[][] sSampleData = new String[3][3]; //rows,cols 
    sSampleData[0][0] = "JS96"; 
    sSampleData[0][1] = "John"; 
    sSampleData[0][2] = "Smith";
    sSampleData[1][0] = "DB67"; 
    sSampleData[1][1] = "David"; 
    sSampleData[1][2] = "Bower";
    sSampleData[2][0] = "LL87"; 
    sSampleData[2][1] = "Lex"; 
    sSampleData[2][2] = "Luthor";


    JTable athTable = new JTable(sSampleData,sHeaders);
    /*JTable tpTable = new JTable(a.compTableData,aHeaders);
    JTable trTable = new JTable(a.compTableData,aHeaders);
    JTable tcTable = new JTable(a.compTableData,aHeaders);
    JTable tsTable = new JTable(a.compTableData,aHeaders);
    */
    athTable.setAutoCreateRowSorter(true);

    myScrollTable = new JScrollPane(athTable); 
    myScrollTable.setSize(1082,600); 
    myScrollTable.setLocation(200,145); 
    System.out.println("Creating compare table");

    ///////////////

    sorter = new TableRowSorter(athTable.getModel());
    athTable.setRowSorter(sorter);

    filterAthID = new JTextField(10);
    filterAthID.setSize(425,26); 
    filterAthID.setLocation(306,120);
    filterAthID.setToolTipText("Enter Athlete ID");
    firstPanel.add(filterAthID);

    filterForeName = new JTextField(10);
    filterForeName.setSize(425,26); 
    filterForeName.setLocation(857,120);
    filterForeName.setToolTipText("Enter Athlete Name");
    firstPanel.add(filterForeName);

    //////////////////////

    Document doc = filterAthID.getDocument();
    DocumentListener listener = new DocumentListener() {

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

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

        @Override
        public void changedUpdate(DocumentEvent e) 
        {
            newFilter();
        }
    };
    doc.addDocumentListener(listener);

    ///////////////
    Document docb = filterForeName.getDocument();
    DocumentListener listenerb = new DocumentListener() {

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

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

        @Override
        public void changedUpdate(DocumentEvent e) 
        {
            newFilterb();
        }
    };
    docb.addDocumentListener(listenerb);
    ///////////////

    firstPanel.add(myScrollTable);

}

private void newFilter()
{
    RowFilter rf = null;
    try 
    {
        rf = RowFilter.regexFilter(filterAthID.getText(), 0);
    } 
    catch (java.util.regex.PatternSyntaxException e) 
    {
        return;
    }
    sorter.setRowFilter(rf);
}

private void newFilterb()
{
    RowFilter rf = null;
    try 
    {
        rf = RowFilter.regexFilter(filterAthID.getText(), 1);
    } 
    catch (java.util.regex.PatternSyntaxException e) 
    {
        return;
    }
    sorter.setRowFilter(rf);
}

public void actionPerformed(ActionEvent e)
{
    if(e.getSource() == btnAdminOnly)
    {
        firstPanel.remove(myScrollTable);
        firstPanel.add(myScrollTable);
        firstPanel.repaint();
        System.out.println("Changing table to athTable");
    }

    if(e.getSource() == btnTPersonal)
    {
        firstPanel.remove(myScrollTable);
        firstPanel.repaint();
        System.out.println("Changing table to tpTable");
    }

    if(e.getSource() == btnTRunning)
    {
        firstPanel.remove(myScrollTable);
        firstPanel.repaint();
        System.out.println("Changing table to trTable");
    }

    if(e.getSource() == btnTCycling)
    {
        firstPanel.remove(myScrollTable);
        firstPanel.repaint();
        System.out.println("Changing table to tcTable");
    }

    if(e.getSource() == btnTSwimming)
    {
        firstPanel.remove(myScrollTable);
        firstPanel.repaint();
        System.out.println("Changing table to tsTable");
    }
}


public static void main(String[] args)
{
    CompFrame cf = new CompFrame();
    cf.runGUI();
}
}

Может ли кто-нибудь сказать мне, в чем проблема, и сказать мне, как это исправить? Также, как только это сработает, если кто-то искал что-то в filterAthID, а затем начал вводить что-то в filterForeName, сработает ли это? Под работой я подразумеваю дальнейшую фильтрацию оставшихся результатов по введенным данным. Если нет, то есть ли способ преодолеть это? И если есть способ преодолеть это, не могли бы вы объяснить, как?


person Dan    schedule 17.03.2015    source источник
comment
Я хочу убедиться, что понимаю. Вы хотите отфильтровать по идентификатору, а затем по повторяющимся идентификаторам отфильтровать по имени? Почему дублируются идентификаторы?   -  person Gilbert Le Blanc    schedule 17.03.2015
comment
Нет, я не хочу дублировать удостоверения личности, и я не уверен, где я упоминал их, если честно. Где я их упоминал?   -  person Dan    schedule 18.03.2015


Ответы (1)


В следующем коде я закомментировал несколько частей данных и вставил примеры данных, чтобы он работал без других файлов.

Не просто закомментируйте код, уберите его из публикации, он нам не интересен.

Кроме того, почему вы включили весь код кнопок? Кнопки не имеют отношения к проблеме, поэтому мы не хотим читать весь код. Чем меньше кода нужно прочитать, тем больше вероятность, что мы сможем найти проблему.

однако мой второй, похоже, не работает.

Мне кажется, у вас опечатка:

//rf = RowFilter.regexFilter(filterAthID.getText(), 1);

Вы должны использовать имя фильтра (а не идентификатор):

rf = RowFilter.regexFilter(filterForeName.getText(), 1);

Редактировать:

Пример фильтра по двум столбцам одновременно:

List<RowFilter<Object,Object>> filters = new ArrayList<RowFilter<Object,Object>>(2);
filters.add(RowFilter.regexFilter(textField1.getText(), 0));
filters.add(RowFilter.regexFilter(textField2.getText(), 1));
rf = RowFilter.andFilter(filters);
person camickr    schedule 17.03.2015
comment
Я не понимаю, что вы имеете в виду, похоже, у меня опечатка. Первая строка кода rf = RowFilter.regexFilter(filterAthID.getText(), 0); фильтрует через первый столбец, а другой должен фильтровать через второй rf = RowFilter.regexFilter(filterForeName.getText(), 1); как показано 0 и 1 - person Dan; 18.03.2015
comment
Проблема в том, что ваш второй фильтр по-прежнему использует идентификатор фильтра, а НЕ ИМЯ. - person camickr; 18.03.2015
comment
Итак, как мне сделать так, чтобы имя работало. Потому что, когда первое текстовое поле пустое, второе все равно не работает. - person Dan; 18.03.2015
comment
Вы заменяете фильтр совершенно новым фильтром, поэтому процесс фильтрации начинается заново. Если вы хотите одновременно фильтровать и идентификатор, и имя, вам нужен более сложный фильтр. Смотрите редактирование: - person camickr; 18.03.2015
comment
При использовании List и ArrayList я не могу найти символ для каждого из них. Что мне нужно декларировать? @camickr - person Dan; 18.03.2015
comment
Document doc = filterAthID.getDocument(); DocumentListener listener = new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { newFilter(); } @Override public void removeUpdate(DocumentEvent e) { newFilter(); } @Override public void changedUpdate(DocumentEvent e) { newFilter(); } }; doc.addDocumentListener(listener); Это все еще нужно? - person Dan; 18.03.2015
comment
Буду признателен за помощь в другом вопросе: Изменение размера JFrame в одном измерении - person Dan; 09.05.2015