|
Replies:
5
-
Last Post:
Sep 22, 2008 5:29 AM
by: Paul Taylor
|
|
|
|
|
|
|
Bug or feature: JXTable repaint on cell update
Posted:
Sep 5, 2008 3:10 AM
|
|
|
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
|
|
|
|
|
|
|
Re: Bug or feature: JXTable repaint on cell update
Posted:
Sep 5, 2008 3:32 AM
in response to: Kleopatra
|
|
|
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
|
|
|
|
|
|
|
|
Re: Bug or feature: JXTable repaint on cell update
Posted:
Sep 5, 2008 4:37 AM
in response to: Paul Taylor
|
|
|
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
|
|
|
|
|
|
|
|
Re: Bug or feature: JXTable repaint on cell update
Posted:
Sep 5, 2008 5:17 AM
in response to: Kleopatra
|
|
|
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
|
|
|
|
|
|
|
|
Re: Bug or feature: JXTable repaint on cell update
Posted:
Sep 22, 2008 5:29 AM
in response to: Kleopatra
|
|
|
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
|
|
|
|
|
|
|
|
Re: Bug or feature: JXTable repaint on cell update
Posted:
Sep 5, 2008 6:37 AM
in response to: Kleopatra
|
|
|
> 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
|
|
|
|
|