Changing filter to "contains"-filter

75 views
Skip to first unread message

KS

unread,
Oct 27, 2016, 10:08:36 AM10/27/16
to tablefilter-swing
Hi all,

I`m trying to change the standart column search filter to a more standart version, that will show all rows containing the expression. Sadly, i`m kind of lost in the code and for now my best approach is:

- create a custom parser model and custom parser
- change the public RowFilter parseText() function


public RowFilter parseText(String expression) throws ParseException {

       RowFilter<Object, Object> containsFilter = new RowFilter<Object, Object>() {

           @Override

           public boolean include(RowFilter.Entry<? extends Object, ? extends Object> entry) {

               for (int i = entry.getValueCount() - 1; i >= 0; i--) {

                   if (entry.getStringValue(i).contains(expression)) {

                       return true;

                   }

               }

               return false;

           }

       };

       return containsFilter;

   }


Still it doesnt seem to work, the table is just not getting filtered at all. So i want to ask you, how is contains-filtering to implement in TableFilter? Am i looking to the right spot or have i overseen something?

Thanks for the feedback, and best regards,

Karl

coderazzi

unread,
Nov 4, 2016, 7:05:12 AM11/4/16
to tablefilter-swing
Hi, Karl,

You COULD get what you are looking for by just implementing a new
IParseModel (and setting it on the FilterSettings instance). The code
for the new parser model would look like:

package net.coderazzi.filters.examples.in_parser;

import net.coderazzi.filters.IParser;
import net.coderazzi.filters.gui.IFilterEditor;
import net.coderazzi.filters.gui.ParserModel;
import net.coderazzi.filters.parser.Parser;

import javax.swing.*;
import java.text.Format;
import java.text.ParseException;
import java.util.Comparator;


public class InParserModel extends ParserModel{

@Override
public IParser createParser(IFilterEditor editor) {
boolean ignoreCase = editor.isIgnoreCase();
Class cl = editor.getModelClass();
Format fmt = (cl == String.class) ? null : editor.getFormat();
Comparator cmp = (fmt == null) ? null : editor.getComparator();

return new Parser(fmt, cmp, getStringComparator(ignoreCase), ignoreCase,
editor.getModelIndex()){

@Override
public RowFilter parseText(String expression) throws
ParseException {
return super.parseText("*" + expression);
}

@Override
public InstantFilter parseInstantText(String expression)
throws ParseException {
return super.parseInstantText("*" + expression);
}
};
}


}


Now, even if this parser does what you need, you will lose the generic
functionality (for example, if a column has integers, you can use
normally a filter such as '> 34'). With the offered ParserModel, that
would stop working,

I will check if the library allows for an easy modification to include
your request,

Best regards,

Luis
> --
> You received this message because you are subscribed to the Google Groups
> "tablefilter-swing" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to tablefilter-sw...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

andreali...@gmail.com

unread,
Nov 8, 2016, 11:54:35 AM11/8/16
to tablefilter-swing, l...@coderazzi.net
Hi, I have the same need: I am using swingtools JTable at https://github.com/thirdy/swingtools which filters columns with Coderazzi library.
I need a "contains" without complex regex.

I have an included coderazzi library which however has no net.coderazzi.filters.IParser; just to start with.
Also I don't know how to set the new filter in the FilterSettings instance.
Can you post a more complete code example?

thank you

andreali...@gmail.com

unread,
Nov 8, 2016, 12:15:07 PM11/8/16
to tablefilter-swing
Ok I solved by using another answer you posted: https://groups.google.com/forum/#!topic/tablefilter-swing/8Vn1GDAtCZI

I did:


import net.coderazzi.filters.IParser;
import net.coderazzi.filters.gui.IFilterEditor;
import net.coderazzi.filters.gui.ParserModel;

public class MyParserModel extends ParserModel

{
    @Override
    public IParser createParser(IFilterEditor editor)
    {
        return new MyParser(super.createParser(editor));
    }
}




import java.text.ParseException;
import java.util.Arrays;
import javax.swing.RowFilter;
import net.coderazzi.filters.IParser;

public class MyParser implements IParser
{

    private final IParser parser;

    public MyParser(IParser parser)
    {
        this.parser = parser;
    }

    @Override

    public RowFilter parseText(String expression) throws
            ParseException
    {
        if(expression != null)
        {
            expression = "*"+expression+"*";
            return parser.parseText(expression);
        }
        else
        {
            return parser.parseText(expression);

        }
    }

    @Override
    public InstantFilter parseInstantText(String expression)
            throws ParseException
    {
        return parser.parseInstantText(expression);
    }

    @Override
    public String escape(String s)
    {
        return parser.escape(s);
    }

    @Override
    public String stripHtml(String string)
    {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}


and in the class BaseTable of tabletools I set setFilterHeaderEnabled(boolean filterHeaderEnabled) to:

tableFilterHeader.setParserModel(new MyParserModel());

seems to be working so far. I basically add * to the beginning and end of the string.

coderazzi

unread,
Nov 10, 2016, 5:03:09 PM11/10/16
to tablefilter-swing
Hi, I have updated the library (version 5.3.0) to support by default
the 'contain' mode.
The default behaviour was to display only entries that would start
with the provided filter, but I do not recall the reason for such
behaviour. The 'contain' behaviour makes more sense.
In addition, I have included a new ParserModel (LooseParserModel),
that dispenses the user of the wildcard characters. That is, if a user
enters the text 'ABC', the filter would show entries containing text
'ABC', and the filter itself would display as '*ABC*'. With the
LooseParserModel, it just displays 'ABC' (see
http://coderazzi.net/tablefilter/howto.html#loose)

Best,

Lu/
Reply all
Reply to author
Forward
0 new messages