Question

i am new to this site and i need help with something i can't solve on my own. I already scanned tons of forums and spent heaps of hours trying to solve it but nothing seems to work properly. So heres my scenario:

I have a jtable, wich is filled with much data from a file. It contains values, and every value has a normal range. on clicking a checkbox, i want to show only those rows that contain the values that are out of the normal range. For that i added an extra column that contains an indicator for that (++,+,-,--). As i dont have to do further calculations with the values, i did set up the data model as an array of strings.

My code structure so far is:

in the public class the table, model and TableRowSorter are initialized.

public class Auswertung extends JFrame {

      TableModel model = new MyTableModel();


      TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);

      JTable  table = new JTable (model);

      JScrollPane scrollPane = new JScrollPane(table);
}

in the constructor class the row sorter is set, as well als the auto row sorter.

   public Auswertung(){
    table.setRowSorter(sorter);
    table.setAutoCreateRowSorter(true);
   }

The Abstract Table Model looks like this:

 class MyTableModel extends AbstractTableModel {

      String [] columnNames = {"param","unit", "old", "new","norm range", "1", "2", "3", "4", "indicator"};
      String [][] tableData = measurements;
      @Override
        public int getRowCount()
        {
            return tableData.length;
        }

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

        @Override
        public Object getValueAt(int row, int column)
        {        
            return tableData[row][column];
        }

        //Used by the JTable object to set the column names
        @Override
        public String getColumnName(int column) {
            return columnNames[column];
        }



        @Override
        public boolean isCellEditable(int row, int column)
        {
           if (column == 0 || column == 1)
       {
            return false;
       }
       else
       {
        return true;
       }
        }






 }

And it works fine - it hands over the data ( measurements [][] , this array is filled up in another method ) collected from the file over to the JTable -everything cool so far. so now i tried to sort out the not relevant rows when a checkbox is clicked.. so i wrote this class which is triggered by the actionPerformed of the checkbox:

public class sortRelevant implements  ActionListener {

    private void newFilter(String filter) {
        RowFilter<? super TableModel, ? super Integer> rf = null;
        //If current expression doesn't parse, don't update.
        try {
            rf = RowFilter.regexFilter(filter, 0);
        } catch (java.util.regex.PatternSyntaxException e) {
            return;

        }
        sorter.setRowFilter(rf);
    }

    public void actionPerformed(ActionEvent arg0) {

        // TODO Auto-generated method stub
        if(onlysortRelevant.isSelected()){
            //sort out the not relevant
            newFilter("+");

        }else{

            //Show all the rows again
        }

    }

}

As far as i understand this code shoud set up a regex filter which scans after a certain string in the JTable's data model. the rows in this data model that dont contain this string should be removed (for the start i would be happy just to sort out the rows that have a "+" in the last column ). The code i posted doesnt throw an exeption, and all the methods are triggered, but when i click the checkboxs, not a single pixel changes in the JTable.

I am sorry guys i am pretty much spamming my code here, but i really don't have an idea where the mistake could be. Just if you see something give me a little hint so i can work on it. Any ideas are much appreciated.

Best regards Falco Winkler

Was it helpful?

Solution

Some issues:

  1. When you do table.setAutoCreateRowSorter(true); it replaces the RowSorter you just created with a default one. Remove that line.

  2. + is a special character in a regular expression. Specifically it's a quantifier that means to match 1 or more of the preceding token. Since there is no preceding token, the regex pattern is invalid. If you weren't suppressing the PatternSyntaxException it would tell you that. To match a literal + in a regular expression, escape it with a backslash: \+. To encode a backslash in a string literal in Java source code, escape it with another backslash. I.e., change newFilter("+"); to newFilter("\\+");. Also, remove the try-catch for the PatternSyntaxException.

  3. The subsequent parameters to RowFilter.regexFilter are the indices of the columns it should perform filtering on. You've told it to perform filtering only using column 0, but I'm not sure that's the right column in your data, so that might need to be changed. If you want to perform filtering on all columns, just leave that blank. I.e., f = RowFilter.regexFilter(filter);.

  4. A RowFilter says which rows to include, but it sounds like you want to exclude the ones containing + (maybe?). You can use RowFilter.notFilter to invert the meaning if needed. I.e., rf = RowFilter.notFilter(RowFilter.regexFilter(filter));.

  5. The code to insert under //Show all the rows again would be sorter.setRowFilter(null);.

That should get it working. However, if for neatness, you'd prefer not have the column with the +/- signs displayed, you could remove that column from your table, and create a custom implementation of RowFilter that operates on the data in the model directly, that tests whether the values are in or out of range on the fly. I don't know what your data looks like so this is a toy example:

sorter.setRowFilter(new RowFilter<TableModel,Integer>() {
    @Override
    public boolean include(RowFilter.Entry<? extends TableModel,? extends Integer> row) {
        // only include rows that have a cat in column 0
        return row.getValue(0).toString().contains("cat");
    }
});

Hope this helps.

OTHER TIPS

As for setting up two filters, i found out that there is a function RowFilter.orFilter(filters), with which you can apply multiple filters. An example looks like this if you are interested:

 ArrayList<RowFilter<Object, Object>> filters = new   ArrayList<RowFilter<Object,Object>>(2);
        filters.add(RowFilter.regexFilter(filter1, 9));
        filters.add(RowFilter.regexFilter(filter2, 9));
        rf = RowFilter.orFilter(filters);

Ok - somewhere here you need to revalidate() your panel - scrollpane should be fine. If the components have changed and you want to repaint your screen that is what you use. So -

scrollpane.revalidate(); scrollpane.repaint();

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top