The Source for Java Technology Collaboration

Home » java.net Forums » Java Desktop Technologies » SwingLabs

Thread: Bug or feature: JXTable repaint on cell update

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 5 - Last Post: Sep 22, 2008 5:29 AM by: Paul Taylor
Kleopatra
Bug or feature: JXTable repaint on cell update
Posted: Sep 5, 2008 3:10 AM
  Click to reply to this thread Reply


We have had a bunch of complaints about a certain sluggishness with
frequent cell updates. Part of the problem is the coarse-grained event
notification from filter/sorters. This will not be addressed (as SwingX
sorting/filtering is EOL and 1.6 take over after final). But there's a
slightly worrying part of it, which will not go away: currently, the
table is completely repainted even without filters/sorters attached. The
underlying reason is that internally, there's _always_ a pipeline
installed which has a single pass-through filter. It does nothing ...
except unconditionally firing a pipeline event on refresh (which is
called on receiving a tableChanged). Which smells like a misbehaviour.
Nevertheless, it has a (maybe?) beneficial side-effect: highlighters
with predicates based on the content of "other" cells are automagically
working. Below is an example (needs SwingX test infrastructure to run)
which highlights the complete row if the text in the first column starts
with "a". The left table has the default pipeline, the right has a
filter which doesn't fire if there's no sorter active. The left feels
better (complete row is updated), the right behaves strict to the rules
(only the cell is updated). Moreover, the latter is how 1.6 behaves
(there's a 1.6 - incomplete - table implementation in my incubator).

Now the question is what do we do?

- "fix" the smelly update: this will visually break all client code
which merrily relies on the repaint. Then those applications would have
to be changed to make the model fire a row-changed. Which is not exactly
recommended (most limited event usually is the-right-thing-to-fire).
Alternatively, developers could add a custom tableModelListener which
triggers a repaint .. haha, hearing the outcry :-)
- do nothing: this will move the postpone the breaking point until after
switching to 1.6.
- ??

Scratching my head ... usually I'm strictly against keeping backwards
bug-compatibility ... but ... hmmm ... Opinions, please?


Jeanette







package org.jdesktop.swingx;
 
import java.awt.Color;
import java.awt.Component;
 
import org.jdesktop.swingx.decorator.ColorHighlighter;
import org.jdesktop.swingx.decorator.ComponentAdapter;
import org.jdesktop.swingx.decorator.Filter;
import org.jdesktop.swingx.decorator.FilterPipeline;
import org.jdesktop.swingx.decorator.HighlightPredicate;
 
/**
 *
 */
public class JXTableUpdate extends InteractiveTestCase {
     public static void main(String[] args) {
        JXTableUpdate test = new JXTableUpdate();
        try {
            test.runInteractiveTests();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
   
     public void interactiveRepaintOnUpdateSingleCell() {
         JXTable table =  new JXTable(10, 5);
         // highlight complete row if first cell starts with a
         HighlightPredicate predicate = new HighlightPredicate() {
 
             public boolean isHighlighted(Component renderer,
                     ComponentAdapter adapter) {
                 return adapter.getString(0).startsWith("a");
             }
            
         };
         ColorHighlighter highlighter = new ColorHighlighter(predicate, 
Color.MAGENTA, null, Color.MAGENTA, null);
         table.addHighlighter(highlighter);
         JXTable other = new JXTable(table.getModel());
         other.setFilters(new FilterPipeline(new IdentityFilter()));
         other.addHighlighter(highlighter);
         JXFrame frame = wrapWithScrollingInFrame(table, other, "repaint 
on update in first");
         addMessage(frame, "edit first cell in left table (start 
with/out a)");
         show(frame);
     }
    
     public class IdentityFilter extends Filter {
        
         /**
          * PENDING JW: fires always, even without sorter ..
          * Could do better - but will break behaviour of apps which 
relied on
          * the (buggy) side-effect of repainting on each change.
          *
          */
         @Override
         public void refresh() {
             if ((pipeline == null) ||
               (pipeline.getSortController().getSortKeys().size() == 0)) 
return;
             super.refresh();
         }
 
         @Override
         protected void init() {
 
         }
 
         @Override
         protected void reset() {
 
         }
 
         @Override
         protected void filter() {
 
         }
 
         @Override
         public int getSize() {
             return this.getInputSize();
         }
 
         @Override
         protected int mapTowardModel(int row) {
             return row;
         }
 
         @Override
         protected int mapTowardView(int row) {
             return row;
         }
     }
 
}
 


---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Paul Taylor
Re: Bug or feature: JXTable repaint on cell update
Posted: Sep 5, 2008 3:32 AM   in response to: Kleopatra
  Click to reply to this thread Reply

Hi

Slow vertical scrolling in my application is one of my biggest
headaches, and this is exasberated by having two synchronized tables
(recno and main table) . Ive spent alot of time optimizing my cell
renderers but it didnt make much difference ,and I think the problem is
the one you describe. So please provide a fix , it could be optional and
disabled by default to preserve backwards compatibility. The majority of
my customers are Mac users , and since Java 1.6 is only available on Mac
OSX 10.5 AND on Intel machines only I'm not going to be able to drop
java 1.5 support anytime soon.

BTW, did you ever find a solution to having to use two tables if you
want a fixed row header, and main table. And if not is there ever going
to be a solution in Java 6 or 7 ?

Paul

Kleopatra wrote:
>
> We have had a bunch of complaints about a certain sluggishness with
> frequent cell updates. Part of the problem is the coarse-grained event
> notification from filter/sorters. This will not be addressed (as
> SwingX sorting/filtering is EOL and 1.6 take over after final). But
> there's a slightly worrying part of it, which will not go away:
> currently, the table is completely repainted even without
> filters/sorters attached. The underlying reason is that internally,
> there's _always_ a pipeline installed which has a single pass-through
> filter. It does nothing ... except unconditionally firing a pipeline
> event on refresh (which is called on receiving a tableChanged). Which
> smells like a misbehaviour. Nevertheless, it has a (maybe?) beneficial
> side-effect: highlighters with predicates based on the content of
> "other" cells are automagically working. Below is an example (needs
> SwingX test infrastructure to run) which highlights the complete row
> if the text in the first column starts with "a". The left table has
> the default pipeline, the right has a filter which doesn't fire if
> there's no sorter active. The left feels better (complete row is
> updated), the right behaves strict to the rules (only the cell is
> updated). Moreover, the latter is how 1.6 behaves (there's a 1.6 -
> incomplete - table implementation in my incubator).
>
> Now the question is what do we do?
>
> - "fix" the smelly update: this will visually break all client code
> which merrily relies on the repaint. Then those applications would
> have to be changed to make the model fire a row-changed. Which is not
> exactly recommended (most limited event usually is
> the-right-thing-to-fire). Alternatively, developers could add a custom
> tableModelListener which triggers a repaint .. haha, hearing the
> outcry :-)
> - do nothing: this will move the postpone the breaking point until
> after switching to 1.6.
> - ??
>
> Scratching my head ... usually I'm strictly against keeping backwards
> bug-compatibility ... but ... hmmm ... Opinions, please?
>
>
> Jeanette
>
>
>
>
>
>
>
>
> package org.jdesktop.swingx;
>
> import java.awt.Color;
> import java.awt.Component;
>
> import org.jdesktop.swingx.decorator.ColorHighlighter;
> import org.jdesktop.swingx.decorator.ComponentAdapter;
> import org.jdesktop.swingx.decorator.Filter;
> import org.jdesktop.swingx.decorator.FilterPipeline;
> import org.jdesktop.swingx.decorator.HighlightPredicate;
>
> /**
> *
> */
> public class JXTableUpdate extends InteractiveTestCase {
>     public static void main(String[] args) {
>        JXTableUpdate test = new JXTableUpdate();
>        try {
>            test.runInteractiveTests();
>        } catch (Exception e) {
>            e.printStackTrace();
>        }
>    }
>       public void interactiveRepaintOnUpdateSingleCell() {
>         JXTable table =  new JXTable(10, 5);
>         // highlight complete row if first cell starts with a
>         HighlightPredicate predicate = new HighlightPredicate() {
>
>             public boolean isHighlighted(Component renderer,
>                     ComponentAdapter adapter) {
>                 return adapter.getString(0).startsWith("a");
>             }
>                    };
>         ColorHighlighter highlighter = new ColorHighlighter(predicate, 
> Color.MAGENTA, null, Color.MAGENTA, null);
>         table.addHighlighter(highlighter);
>         JXTable other = new JXTable(table.getModel());
>         other.setFilters(new FilterPipeline(new IdentityFilter()));
>         other.addHighlighter(highlighter);
>         JXFrame frame = wrapWithScrollingInFrame(table, other, 
> "repaint on update in first");
>         addMessage(frame, "edit first cell in left table (start 
> with/out a)");
>         show(frame);
>     }
>        public class IdentityFilter extends Filter {
>                /**
>          * PENDING JW: fires always, even without sorter ..
>          * Could do better - but will break behaviour of apps which 
> relied on
>          * the (buggy) side-effect of repainting on each change.
>          *
>          */
>         @Override
>         public void refresh() {
>             if ((pipeline == null) ||
>               (pipeline.getSortController().getSortKeys().size() == 
> 0)) return;
>             super.refresh();
>         }
>
>         @Override
>         protected void init() {
>
>         }
>
>         @Override
>         protected void reset() {
>
>         }
>
>         @Override
>         protected void filter() {
>
>         }
>
>         @Override
>         public int getSize() {
>             return this.getInputSize();
>         }
>
>         @Override
>         protected int mapTowardModel(int row) {
>             return row;
>         }
>
>         @Override
>         protected int mapTowardView(int row) {
>             return row;
>         }
>     }
>
> }
>
> 

>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
> For additional commands, e-mail: jdnc-help@jdnc.dev.java.net
>
>
>


---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Kleopatra
Re: Bug or feature: JXTable repaint on cell update
Posted: Sep 5, 2008 4:37 AM   in response to: Paul Taylor
  Click to reply to this thread Reply

Paul Taylor schrieb:
> Hi
>
> Slow vertical scrolling in my application is one of my biggest
> headaches, and this is exasberated by having two synchronized tables
> (recno and main table) . Ive spent alot of time optimizing my cell
> renderers but it didnt make much difference ,and I think the problem
> is the one you describe. So please provide a fix , it could be
> optional and disabled by default to preserve backwards compatibility.
> The majority of my customers are Mac users , and since Java 1.6 is
> only available on Mac OSX 10.5 AND on Intel machines only I'm not
> going to be able to drop java 1.5 support anytime soon.
>

good point. Could you please try if the using the fixed IdentityFilter
really helps in your context? I'm not entirely sold on that the
scrolling will be improved (no updates, no repaints), my guess (wild, of
course, you know better :-) culprit would be synchronization ...
> BTW, did you ever find a solution to having to use two tables if you
> want a fixed row header, and main table. And if not is there ever
> going to be a solution in Java 6 or 7 ?
>
no, never found anything. Currently I think that we would need a
compound component (not being a table but having two tables), but didn't
look into it for a while.

Cheers
Jeanette


---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Paul Taylor
Re: Bug or feature: JXTable repaint on cell update
Posted: Sep 5, 2008 5:17 AM   in response to: Kleopatra
  Click to reply to this thread Reply

Kleopatra wrote:
> Paul Taylor schrieb:
>> Hi
>>
>> Slow vertical scrolling in my application is one of my biggest
>> headaches, and this is exasberated by having two synchronized tables
>> (recno and main table) . Ive spent alot of time optimizing my cell
>> renderers but it didnt make much difference ,and I think the problem
>> is the one you describe. So please provide a fix , it could be
>> optional and disabled by default to preserve backwards compatibility.
>> The majority of my customers are Mac users , and since Java 1.6 is
>> only available on Mac OSX 10.5 AND on Intel machines only I'm not
>> going to be able to drop java 1.5 support anytime soon.
>>
>
> good point. Could you please try if the using the fixed IdentityFilter
> really helps in your context? I'm not entirely sold on that the
> scrolling will be improved (no updates, no repaints), my guess (wild,
> of course, you know better :-) culprit would be synchronization ...
Yes I'll look but it will have to be next week, family up for the
weekend - due in the next half hour

Paul

---------------------------------------------------------------------
To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net
For additional commands, e-mail: jdnc-help@jdnc.dev.java.net


Paul Taylor
Re: Bug or feature: JXTable repaint on cell update
Posted: Sep 22, 2008 5:29 AM   in response to: Kleopatra
  Click to reply to this thread Reply

Kleopatra wrote: > Paul Taylor schrieb: >> Hi >> >> Slow vertical scrolling in my application is one of my biggest >> headaches, and this is exasberated by having two synchronized tables >> (recno and main table) . Ive spent alot of time optimizing my cell >> renderers but it didnt make much difference ,and I think the problem >> is the one you describe. So please provide a fix , it could be >> optional and disabled by default to preserve backwards compatibility. >> The majority of my customers are Mac users , and since Java 1.6 is >> only available on Mac OSX 10.5 AND on Intel machines only I'm not >> going to be able to drop java 1.5 support anytime soon. >> > > good point. Could you please try if the using the fixed IdentityFilter > really helps in your context? I'm not entirely sold on that the > scrolling will be improved (no updates, no repaints), my guess (wild, > of course, you know better :-) culprit would be synchronization ... Sorry for the delay, looking at my code my problem is slightly different in that I initialize my FilterPipline with all the filters I use, but I was supposing they didnt have any effect until the user actually did something that required filtering, I did it this way because there is no way to just add a filter back into an existing FilterPipleine. If I remove the filters vertical scrolling and reordering table columns performance improves dramatically, although it still isnt as good as it could be, if I remove the filters and add your IdentityFilter there is a further improvement, but not as dramatic as before. I see the issue with the highlighter in your test, it was suprising that the addition of any kind of filter should be effecting how highlighters work. But I need my filters to hide rows based on certain conditions (the row table synchronizarion is done via extending the FilterPipeline class and listening to PipelineEvent.CONTENTS_CHANGED and for changed son the sort keys). If I have five filters in a pipeline does each one do a refresh on any change, I would really like it to just issue a refresh if a cell has changed. There may be a problem with my filter because whether a row should be displayed doesnt just depend on the value in that row but on values in other rows, so the way by filter works is its not meant to have any effect until the setMatchingRows() method is called, from that point on only rows in that list should be displayed. The calculation of matching rows is done by a sepertae thread when relevet chnages are made. I've listed the code in below hoping you could give it a quick scan thanks Paul {code} import com.jthink.jaikoz.data.JaikozFieldName; import org.jdesktop.swingx.decorator.Filter; import java.util.ArrayList; import java.util.List; /** * Only show records which have a model index listed in matching rows */ public class RowsKnownFilter extends Filter { //Only rows with model index in this list should be shown //TODO is this the most efficient storage device private List<Integer> matchingRows; private ArrayList<Integer> toPrevious; /** * Instantiate empty filter */ public RowsKnownFilter(int modelColumnId) { super(modelColumnId); } public RowsKnownFilter(int modelColumnId,List<Integer> matchingRows) { super(modelColumnId); setMatchingRows(matchingRows); } public void setMatchingRows(List<Integer> matchingRows) { if(this.matchingRows==null && matchingRows == null) { //Do nothing, nothing has changed return; } this.matchingRows = matchingRows; refresh(); } public List<Integer> getMatchingRows() { return matchingRows; } /** * Resets the internal row mappings from this filter to the previous filter. */ @Override protected void reset() { toPrevious.clear(); int inputSize = getInputSize(); fromPrevious = new int[inputSize]; // fromPrevious is inherited protected for (int i = 0; i < inputSize; i++) { fromPrevious =] *

* PENDING JW: why is this public? called from a protected method? * * @param row the row to test * @return true if the row should be added, false if not. */ public boolean test(int row) { //Pass through if(matchingRows==null) { return true; } //PT ask the adapter if the column should be includes //We disable because for row header filter fails because JXTable.isTestable() returns false //if the column is not in the column model //if (!adapter.isTestable(getColumnIndex())) //{ // return false; //} //Find the model row no by looking at the recno column Integer value = (Integer)getInputValue(row, JaikozFieldName.RECNO.ordinal()); return matchingRows.contains(value); } /** * {@inheritDoc} */ @Override public int getSize() { return toPrevious.size(); } /** * {@inheritDoc} */ @Override protected int mapTowardModel(int row) { if(row>=toPrevious.size()) { return row; } return toPrevious.get(row); } /** * {@inheritDoc} */ @Override protected void init() { toPrevious = new ArrayList<Integer>(); } } {code} --------------------------------------------------------------------- To unsubscribe, e-mail: jdnc-unsubscribe@jdnc.dev.java.net For additional commands, e-mail: jdnc-help@jdnc.dev.java.net

kschaefe

Posts: 1,662
Re: Bug or feature: JXTable repaint on cell update
Posted: Sep 5, 2008 6:37 AM   in response to: Kleopatra
  Click to reply to this thread Reply

> Now the question is what do we do?
>
> - "fix" the smelly update: this will visually break
> all client code
> which merrily relies on the repaint. Then those
> applications would have
> to be changed to make the model fire a row-changed.
> Which is not exactly
> recommended (most limited event usually is
> the-right-thing-to-fire).
> Alternatively, developers could add a custom
> tableModelListener which
> triggers a repaint .. haha, hearing the outcry :-)
> - do nothing: this will move the postpone the
> breaking point until after
> switching to 1.6.

We could also provide some kind of way for a Highlighter to declare itself as requiring external data. When the Highlighter is registered, we automatically add externally requiring Highlighters to some TableModelListener that automatically upgrade the request from cell to row, etc. I'd favor a client property for backward compatibility that always embellishes the request.

Karl




 XML java.net RSS