Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » NatTable » Filter converted data
Filter converted data [message #1816206] Wed, 23 October 2019 15:55 Go to next message
Tom Wheeler is currently offline Tom WheelerFriend
Messages: 17
Registered: June 2018
Junior Member
In my NatTable, I have a column of java.util.Calendar objects. Using a DisplayConverter, I convert such objects into strings to display them in this format, "2019-10-23 12:08:05+0200" using Java's SimpleDateFormat.

I would like to filter these strings in my FilterEditor. I have read and tried the advice in https://www.eclipse.org/forums/index.php/m/1700786/?srch=filter#msg_1700786 and in https://www.eclipse.org/forums/index.php?t=msg&th=1098416&goto=1805186&#msg_1805186 but it does not seem to work for me.

From what I understand, the intension with FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER is that the string that the user enters in FilterRowEditor shall be converted to the object held in the column, i.e. a Calendar object. It just doesn't make sense to me how a to convert a FilterEditor string like "12" into a Calendar object.

Therefore my question is: Is it possible to have it working the other way around, i.e. having the filter work against the strings that I see in my table instead of the Calendar instances that are held in the TransformedList?
Re: Filter converted data [message #1816207 is a reply to message #1816206] Wed, 23 October 2019 17:33 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
I would say the default is the filtering on the string representation. Think in our examples it works this way without special configuration.
Re: Filter converted data [message #1816225 is a reply to message #1816207] Thu, 24 October 2019 11:46 Go to previous messageGo to next message
Tom Wheeler is currently offline Tom WheelerFriend
Messages: 17
Registered: June 2018
Junior Member
After a lot of single-stepping, here's what I have found:

Without applying the FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER, the cells holding a java.util.Calendar object are converted to Strings using toString(). This can be observed by setting a breakpoint in these methods and definitely not sufficient for a complex object such as the Calendar:

DefaultGlazedListsFilterStrategy.getTextFilterator().TextFilterator
...
Object displayValue = converter.canonicalToDisplayValue(cellData);

DefaultDisplayConverter.canonicalToDisplayValue()
...
return sourceValue != null ? sourceValue.toString() : "";

When applying a custom converter via FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER on the column labeled "FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + aColumnIndex", the converter's DisplayConverter.canonicalToDisplayValue() method is used both for the filter row cell and when filtering each of the rest of the cells in the table column.

This means that the same converter is used for a cell that holds a String entered by the user and for cells that holds instances of java.util.Calendar.

This doesn't seem right to me. It should be possible to provide different converters: One for the filter row cell and another for the rest of the column's cells. What do you think?
Re: Filter converted data [message #1816226 is a reply to message #1816225] Thu, 24 October 2019 12:21 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
I don't get what you mean. In the filter row cell you are entering a string. And that should be used to filter the content based on values in the column. So what happens is by default that the object value in the data model is converted to string by the configured converter. And based on that value the filter is applied.

What is wrong with that approach from your side?

Not sure about the details as I am currently not sitting in front of the code. But IIRC everything is consistent. But probably the code is not trivial to understand. I had similar troubles with understanding in the beginning.
Re: Filter converted data [message #1816228 is a reply to message #1816226] Thu, 24 October 2019 13:37 Go to previous messageGo to next message
Tom Wheeler is currently offline Tom WheelerFriend
Messages: 17
Registered: June 2018
Junior Member
Thanks for your reply. I might misunderstand something. However, using the following hack, I have made it work:

The following converter is added like this:
configRegistry.registerConfigAttribute( //
    FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER, //
    aNormalDisplayConverter, //
    DisplayMode.NORMAL, //
    FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + aColumnIndex);

public class CalenderTimeToTextConverter extends DisplayConverter {

    private static final String BITE_TIME_FORMAT = "yyyy'-'MM'-'dd' 'HH':'mm':'ssZ";
    private final SimpleDateFormat aSimpleDateFormat;

    public CalenderTimeToTextConverter() {
        aSimpleDateFormat = new SimpleDateFormat(BITE_TIME_FORMAT);
    }

    @Override
    public Object canonicalToDisplayValue(Object canonicalValue) {

        String res = "";

        if (canonicalValue instanceof Calendar) {
            Calendar cal = (Calendar) canonicalValue;
            res = aSimpleDateFormat.format(cal.getTime());
        }
        else {
            if (null == canonicalValue) {
                res = "*null*";
            }
            else if (canonicalValue instanceof String) {
                res = (String) canonicalValue;
            }
            else {
                System.out.println("'canonicalValue' is neither a Calendar nor a String: \"" + canonicalValue + "\"");
                res = canonicalValue.toString();
            }
        }

        return res;
    }

    @Override
    public Object displayToCanonicalValue(Object displayValue) {

        Calendar res = null;

        if (displayValue instanceof String) {
            String stringValue = (String) displayValue;
            try {
                Date date = aSimpleDateFormat.parse(stringValue);
                Calendar.Builder cb = new Calendar.Builder();
                cb.setInstant(date);
                res = cb.build();
            }
            catch (ParseException e) {
                System.out.println("Failed to parse the string \"" + stringValue + "\" into a Calendar instance.");
            }
        }
        return res;
    }
}

I consider it a hack because of the different "if instanceof" statements in the DisplayConverter.
When my code runs, both the String entered by the user in the FilterRowEditor as well as the java.util.Calendar are passed through the CalenderTimeToTextConverter.canonicalToDisplayValue() in my code example.

My point is that it should be possible to register a converter that only applies to the data from the data model represented by the TransformedList. Since the user enters a String in the filter row, there should be no need to transform that.

What do you think when looking at this example?
Re: Filter converted data [message #1816271 is a reply to message #1816228] Fri, 25 October 2019 05:01 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
In my opinion it is incorrect and not necessary with regards to your use case. IIUC you want to convert the data shown in the column with your SimpleDateFormat. And you want to filter textual based on the converted String representation.

Like I tried to say before, there is no need to have a converter in the filter row for the date column in your use case. And you can see this in our examples also. The converters in the filter row are needed for example if you want to use regular expressions or use cases where you want to support expressions like "greater than" or "lower than" for example for number values.

The _814_EditableSortableGroupByWithFilterExample also has a converter for the birthday column and it supports text based filtering in that column WITHOUT a converter in the filter row. So I am not sure what issue you are trying to solve with your implementation.
Re: Filter converted data [message #1816463 is a reply to message #1816271] Tue, 29 October 2019 17:00 Go to previous messageGo to next message
Tom Wheeler is currently offline Tom WheelerFriend
Messages: 17
Registered: June 2018
Junior Member
To illustrate my issue, I have attached a modified _6032_GlazedListsFilterCustomTypesExample.java in which I have added an extra "Date" column that will hold a java.util.Calendar object.

In it, I have pasted my aforementioned converter, "CalenderTimeToTextConverter", to get the desired output in the cells of the Date column.

On top of that, I have configured the TEXT_MATCHING_MODE:
configRegistry.registerConfigAttribute(
    FilterRowConfigAttributes.TEXT_MATCHING_MODE,
    TextMatchingMode.CONTAINS, DisplayMode.NORMAL,
    FilterRowDataLayer.FILTER_ROW_COLUMN_LABEL_PREFIX + 5);

Now I would like to use the FilterRow cell in the Date column to search for the strings that I see in the Date column, but as you can see from this screenshot, in reality it searches the output of Calendar.toString(). Otherwise it would not have matched the string, "GregorianCalendar":

index.php/fa/36674/0/

Please see my two attached files: "Modified_6032_GlazedListsFilterCustomTypesExample.java" and "string_search_in_date_column.png".

What should I do to make my FilterRow work against the formatted strings that I see in the Date column?
Re: Filter converted data [message #1816492 is a reply to message #1816463] Wed, 30 October 2019 06:36 Go to previous messageGo to next message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
OK, now I get the point.

After digging in the sources I found out that the display converter registered via FilterRowConfigAttributes.FILTER_DISPLAY_CONVERTER unfortunately has a dual role.

The first role is to convert the input in the filter editor to the column value. This is used in cases of filter combos or regular expressions for example (e.g. if you want to filter values "> 10").
The second role is to convert the column value to string to be able to make string comparisons. This is actually what you need, while the first role is not needed. This is needed because the filter row does not know anything about the converter registered in the body.

To use the same converter for the body as well as for the filter row, the solution you have found should be correct. Yes an unfortunate instanceof check, but the only other solution would be to introduce a new configuration attribute that tells the filter row which display converter is used for the body. Something like FILTER_CONTENT_DISPLAY_CONVERTER. Not sure if this could be introduced without breaking existing code in the field.
Re: Filter converted data [message #1816495 is a reply to message #1816492] Wed, 30 October 2019 07:33 Go to previous messageGo to next message
Tom Wheeler is currently offline Tom WheelerFriend
Messages: 17
Registered: June 2018
Junior Member
Thank you for your advice on this issue. It is much appreciated. I will go on with my CalenderTimeToTextConverter, then.
Re: Filter converted data [message #1816538 is a reply to message #1816495] Wed, 30 October 2019 17:24 Go to previous message
Dirk Fauth is currently offline Dirk FauthFriend
Messages: 2902
Registered: July 2012
Senior Member
I have created the following ticket and introduced a new config attribute FilterRowConfigAttributes#FILTER_CONTENT_DISPLAY_CONVERTER to be able to register the same converter as in the body. I implemented it backwards compatible, so if no value is registered for that config attribute, the old mechanism still applies.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=552575
Previous Topic:How to track drown RowSelectionEvents
Next Topic:Comboboxcelleditor combo values based on cell value
Goto Forum:
  


Current Time: Thu Apr 18 02:00:57 GMT 2024

Powered by FUDForum. Page generated in 0.02523 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top