Skip to main content

JXTable model to view conversion ...

42 replies [Last post]
dags
Offline
Joined: 2003-06-10

Hi,
I am working with a JXTable, single selection mode, which have a related jtextfield where to input text to be used as a filter base:

<br />
String text1 = jTextField1.getText();<br />
String text2 = ".*" + text1 + ".*";<br />
matchFlags   = java.util.regex.Pattern.CASE_INSENSITIVE + java.util.regex.Pattern.UNICODE_CASE;<br />

this pattern is then used to make a Filter :
<br />
try {<br />
    jXTable1.setFilters(new FilterPipeline(new Filter[] { new PatternFilter(text2, matchFlags, col) } ));<br />
} catch(java.util.regex.PatternSyntaxException pse) {<br />
    System.out.println(pse);<br />
}<br />

if there is a selected row before setting the filter, how can I preserve this selection after filter is applied ?. I tried getting selected row before applying the filter and restoring selection after, is row is visible:
<br />
// store selected row before applying filter<br />
viewRow = jXTable1.getSelectedRow();<br />
modelRow = viewRow >= 0 ? jXTable1.convertRowIndexToModel(viewRow) : -1;<br />

After setting the filter :
<br />
// convert former selected row back to view index, if any<br />
viewRow = modelRow >= 0 ? jXTable1.convertRowIndexToView(modelRow) : -1;</p>
<p>if (viewRow >= 0) {<br />
    // here is the trouble !!!.<br />
    jXTable1.setRowSelectionInterval(viewRow, viewRow);<br />
}

The fact is I select a row and get modelRow = 2279 which, of course, is the same as viewRow before applying filter. After applying filter, these modelRow (= 2279) maps to a viewRow = 1487. But when calling setRowSelectionInterval(viewRow, viewRow) I get the following :
<br />
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 1712, Size: 1712<br />
        at java.util.ArrayList.RangeCheck(ArrayList.java:547)<br />
        at java.util.ArrayList.get(ArrayList.java:322)<br />
        at org.jdesktop.swingx.decorator.PatternFilter.mapTowardModel(Unknown Source)<br />
        at org.jdesktop.swingx.decorator.Filter.convertRowIndexToModel(Unknown Source)<br />
        at org.jdesktop.swingx.decorator.FilterPipeline.convertRowIndexToModel(Unknown Source)<br />
        at org.jdesktop.swingx.decorator.Selection.convertToModel(Unknown Source)<br />
        at org.jdesktop.swingx.decorator.Selection.updateFromViewSelectionChanged(Unknown Source)<br />
        at org.jdesktop.swingx.decorator.Selection$2.valueChanged(Unknown Source)<br />
        at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:187)<br />
        at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)<br />
        at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:214)<br />
        at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:408)<br />
        at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:417)<br />
        at javax.swing.DefaultListSelectionModel.setSelectionInterval(DefaultListSelectionModel.java:441)<br />
        at javax.swing.JTable.setRowSelectionInterval(JTable.java:1370)<br />
        at com.adminsa.beans.ATable.setRowSelectionInterval(ATable.java:167)<br />

I verified and viewRow = 1487. Where this value (1487) become 1712 (row count of filtered table or view) ?. Numbers are not relevant but shows that viewRow is changed somewhere.
What am I doing wrong ?.

Follow complete method code :

<br />
    private void textFilter() {<br />
        int viewRow, modelRow;<br />
        int matchFlags;</p>
<p>        int col = jXTable1.getColumn("Titulo").getModelIndex();</p>
<p>        String text2 = ".*" + jTextField1.getText() + ".*";<br />
        matchFlags   = java.util.regex.Pattern.CASE_INSENSITIVE + java.util.regex.Pattern.UNICODE_CASE;</p>
<p>        // store selected row before applying filter<br />
        viewRow = jXTable1.getSelectedRow();<br />
        modelRow = viewRow >= 0 ? jXTable1.convertRowIndexToModel(viewRow) : -1;</p>
<p>        // clear selection to avoid troubles if new filtered table does not include selected values ...<br />
        // must be reviewed later<br />
        jXTable1.clearSelection();</p>
<p>        try {<br />
            jXTable1.setFilters(new FilterPipeline(new Filter[] { new PatternFilter(text2, matchFlags, col) } ));<br />
        } catch(java.util.regex.PatternSyntaxException pse) {<br />
            System.out.println(pse);<br />
        }</p>
<p>        rowsLabel.setText("Mostrando " + jXTable1.getRowCount() + " de " + model.getRowCount() + " renglones ");</p>
<p>        // try to select former selected row, if showing in filtered table ...<br />
        viewRow = modelRow >= 0 ? jXTable1.convertRowIndexToView(modelRow) : -1;</p>
<p>        if (viewRow >= 0) {<br />
            jXTable1.setRowSelectionInterval(viewRow, viewRow);<br />
        }<br />
    }<br />

ATable just extends JXTable to add some default HighLighters.

Regards,
Diego.

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
rturnbull
Offline
Joined: 2005-08-27

[i]>Here are two test methods:
- JXTableIssues.testSelectionAndRemoveRowOfMisbehavingModel
- JXTableUnitTest.testSelectionRemoveRowsReselect

could you please have a look and make them fail?[/i]

I copied JXTableIssues.testSelectionAndRemoveRowOfMisbehavingModel into a test class and replaced lines:
table.setSorter(0);
table.setSorter(0);

with
Filter[] filters = new Filter[] {new ShuttleSorter(0, true)};
FilterPipeline filterPipe = new FilterPipeline(filters);
table.setFilters(filterPipe);

and it failed.

Kleopatra

Hi Ray,

> [i]>Here are two test methods:
> - JXTableIssues.testSelectionAndRemoveRowOfMisbehavingModel
> - JXTableUnitTest.testSelectionRemoveRowsReselect
>
> could you please have a look and make them fail?[/i]
>
> I copied JXTableIssues.testSelectionAndRemoveRowOfMisbehavingModel into a test class and replaced lines:
> table.setSorter(0);
> table.setSorter(0);
>
> with
> Filter[] filters = new Filter[] {new ShuttleSorter(0, true)};
> FilterPipeline filterPipe = new FilterPipeline(filters);
> table.setFilters(filterPipe);
>
> and it failed.

Thanks - will look into it asap!

Jeanette

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

kleopatra
Offline
Joined: 2003-06-11

Hi Folks,

just to keep you informed - after yesterday's commit, all examples in this thread are running smoothly, no exceptions any longer :-). So I assume the issues (#172/#173-swingx) are solved.

Cheers
Jeanette

dags
Offline
Joined: 2003-06-10

Jeanette:

I will check it as soon as possible. Now, I am behind a very restrictive firewall and can't use CVS (at least as I know) :(

Thanks,
Diego.

dags
Offline
Joined: 2003-06-10

Jeanette:

I retrieved yesterday's CVS checkout from my home computer (http proxy tunnel to sshd listening on 443 ;) ) and now JXTableTest.java, the test code posted earlier, works OK. :)

I will try later, at home, some other tests that used to fail.

Thanka again.
Diego.

kleopatra
Offline
Joined: 2003-06-11

oops - edited to removed the duplicate...

Jeanette

dags
Offline
Joined: 2003-06-10

This seems similar to my issue. The fact is that Nicola and I were getting exceptions only when some row is selected. If no row is selected, filter work as expected and no exception is thrown. Which is related to mey first post.

Try to comment out line :
[code] table.getSelectionModel().setSelectionInterval( 0, 0 );
[/code]

and will see. I am trying to follow the code.

In Selection.java, in restoreSelection method the original selected model index is converted to the NEW view index ?. If that is what is supposed to happens, it fails because view index is the same as model index.

Maybe restoreSelection is called before filtering actually happens ?.

Regards,
Diego.

kleopatra
Offline
Joined: 2003-06-11

> This seems similar to my issue. The fact is that
> Nicola and I were getting exceptions only when some
> row is selected. If no row is selected, filter work
> as expected and no exception is thrown. Which is
> related to mey first post.
>

the ultimate trigger for throwing the exception is similar - the conversion methods are messaged with an illegal index to convert. But the reasons leading to that situation is different, that's why I filed yet another bug for it:

https://swingx.dev.java.net/issues/show_bug.cgi?id=173

>
> In Selection.java, in restoreSelection method the
> original selected model index is converted to the NEW
> view index ?. If that is what is supposed to happens,
> it fails because view index is the same as model
> index.
>

that's correct behaviour - if model and view coordinates are the same the index conversion is an identity mapping :-) As I mentioned earlier in this thread, the lead/anchor selections are not updated corrected which leads to illegal view indices reported from the view selectionModel. That's covered by another issue:

https://swingx.dev.java.net/issues/show_bug.cgi?id=172

One thread and two P2-Issues to tackle . Thanks!

Jeanette

rturnbull
Offline
Joined: 2005-08-27

[i]>As I mentioned earlier in this thread, the lead/anchor selections are not updated corrected which leads to illegal view indices reported from the view selectionModel. That's covered by another issue:[/i]

Is anything happening with this issue

https://swingx.dev.java.net/issues/show_bug.cgi?id=172

I have a JXTable with a Filter added - a ShuttleSorter on the first column.
I get this error (ArrayIndexOutOfBoundsException) when after deleting the last row (in view coordinates) I try to reset the selection to the new last row.

I've tracked it down (as much as I can - things are getting a bit complicared for me) to what appears to be the same problem you identified in javax.swing.DefaultListSelectionModel().

Message was edited by: rturnbull

I also get the same error if I don't programatically set the selection, but manually click on any other row to select it.

Kleopatra

Hi Ray,
>
> Is anything happening with this issue
>
> https://swingx.dev.java.net/issues/show_bug.cgi?id=172

it's on the to-solve list for swingx1.0 :-)

>
> I have a JXTable with a Filter added - a ShuttleSorter on the first column.

is this the same context as your other thread (JXTable redrawing on
saving the DataTable)? Just want to want to find out if it's the same
issue (ultimately caused by the clearSelection() triggered by a
structureChanged) or something else.

Thanks
Jeanette

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

rturnbull
Offline
Joined: 2005-08-27

[i]>is this the same context as your other thread (JXTable redrawing on
saving the DataTable)? Just want to want to find out if it's the same
issue (ultimately caused by the clearSelection() triggered by a
structureChanged) or something else.[/i]

I don't think it is the same issue. The redrawing problem was happening before I added the sorter.
I think you found part of the cause of this earlier -
the problem in javax.swing.DefaultListSelectionModel.fireValueChanged().
Thats what my debugging suggested is the case here.

By the way, I have got around the problem for the time being by puting a try/catch block around the setSelectionInterval() command, and ignoring the error.
Not very elegant, but everything seems to work OK.

kleopatra
Offline
Joined: 2003-06-11

>
> I don't think it is the same issue. The redrawing
> problem was happening before I added the sorter.

sorry for not having been clearer - the redrawing problem is clearly related to a sub-optimal event propagation through the adapter levels.

But I can't reproduce the outofbounds exception on selection after removeRow - even when trying to simulate such a misbehaving model. So obviously I'm missing something ;-) Here are two test methods:

- JXTableIssues.testSelectionAndRemoveRowOfMisbehavingModel
- JXTableUnitTest.testSelectionRemoveRowsReselect

could you please have a look and make them fail?

Thanks
Jeanette

rturnbull
Offline
Joined: 2005-08-27

[i]>Here are two test methods:
- JXTableIssues.testSelectionAndRemoveRowOfMisbehavingModel
- JXTableUnitTest.testSelectionRemoveRowsReselect

could you please have a look and make them fail?
[/i]

Sorry for the delay - I ran into trouble with my ISP download limit last month.

I'm afraid I'm not to familiar with the behind the scenes setup - could you give me a few more instructions on how to find these.

Patrick Wright

Hi Ray

> [i]>Here are two test methods:
> - JXTableIssues.testSelectionAndRemoveRowOfMisbehavingModel
> - JXTableUnitTest.testSelectionRemoveRowsReselect
>
> could you please have a look and make them fail?
> [/i]
>
> Sorry for the delay - I ran into trouble with my ISP download limit last month.
>
> I'm afraid I'm not to familiar with the behind the scenes setup - could you give me a few more instructions on how to find these.

Not sure how up to date you are--unit tests are coded using JUnit and
are always under src/test. Generally, the test classes will be in the
same package under src/test as the class they are testing. Sync with
CVS, then open src/test/org/jdesktop/swingx/JXTableUnitTest and
JXTableIssues. The *Issues* classes are not set to run automatically
when unit tests are run, but are still JUnit tests so can be run from
an IDE or by tweaking the properties files--the way I've done that is
to modify my local build-impl.xml and search for *Test.java; this is
in "-init-macrodef-junit". Change to

probably other ways to do it. Note that the "Issues" tests are not
supposed to all pass--they are in that sense deferred as the code can
be checked in without them passing--so many may fail.

HTH
Patrick

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

nicfagn
Offline
Joined: 2003-06-14

> hmm ... on the surface I wouldn't expect it to be a
> problem in the general case because at the moment of
> selection.setFilters(..) the filter is not yet
> assigned to the componentAdapter (that's done in the
> use()). But as it makes a difference in your context,
> I'm probably missing something :-) Could you please
> show a small runnable example that's showing the
> problem which is fixed by changing the sequence of
> method calls?
>

Ok, I tried to keep as simple as possible:

package example;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.regex.Pattern;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import org.jdesktop.swingx.JXTable;
import org.jdesktop.swingx.decorator.Filter;
import org.jdesktop.swingx.decorator.FilterPipeline;
import org.jdesktop.swingx.decorator.PatternFilter;

public class Frame extends JFrame {

public static void main(String[] args) {
new Frame();
}

private JXTable table;
private JTextField textField;
Object[][] model;

public Frame() {
model = new Object[][]{
{ "Richard" },
{ "Patrick" },
{ "Jeannette" },
{ "Amy" },
{ "Ramesh" }
};
Object[] columnNames = { "Name" };
table = new JXTable( model, columnNames );
table.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
updateTextField();
}
}
);

textField = new JTextField();

JButton button = new JButton( "Push me!" );
button.addActionListener( new ActionListener() {
public void actionPerformed(ActionEvent e) {
applyFilter();
}
});

add( button, BorderLayout.NORTH );
add( new JScrollPane( table ), BorderLayout.CENTER );
add( textField, BorderLayout.SOUTH );

table.getSelectionModel().setSelectionInterval( 0, 0 );

pack();
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setVisible( true );
}

void updateTextField() {
int row = table.getSelectedRow();
String name = null;
if( row != -1 ) {
row = table.convertRowIndexToModel( row );
name = (String) model[ row ][ 0 ];
}
textField.setText( name );
}

void applyFilter() {
Filter filter =
new PatternFilter( "^R.*", Pattern.CASE_INSENSITIVE, 0 );
FilterPipeline pipeLine =
new FilterPipeline( new Filter[]{ filter } );
table.setFilters( pipeLine );
}

}

With the current swingx code, this sample generates on my system (Mac OS X 10.4.2, Java 1.5.0_05) the following exception, if you push the button when there is a selection on the table:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at org.jdesktop.swingx.decorator.PatternFilter.mapTowardModel(PatternFilter.java:127)
at org.jdesktop.swingx.decorator.Filter.convertRowIndexToModel(Filter.java:101)
at org.jdesktop.swingx.decorator.FilterPipeline.convertRowIndexToModel(FilterPipeline.java:329)
at org.jdesktop.swingx.JXTable.convertRowIndexToModel(JXTable.java:743)
at example.Frame.updateTextField(Frame.java:70)
at example.Frame$1.valueChanged(Frame.java:41)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:187)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:167)
at javax.swing.DefaultListSelectionModel.fireValueChanged(DefaultListSelectionModel.java:214)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:408)
at javax.swing.DefaultListSelectionModel.changeSelection(DefaultListSelectionModel.java:417)
at javax.swing.DefaultListSelectionModel.addSelectionInterval(DefaultListSelectionModel.java:475)
at org.jdesktop.swingx.decorator.Selection.restoreSelection(Selection.java:92)
at org.jdesktop.swingx.decorator.Selection.setFilters(Selection.java:78)
at org.jdesktop.swingx.JXTable.setFilters(JXTable.java:935)
at example.Frame.applyFilter(Frame.java:81)
at example.Frame$2.actionPerformed(Frame.java:51)
at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1882)
at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2202)
at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:420)
at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:258)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:234)
at java.awt.Component.processMouseEvent(Component.java:5554)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3126)
at java.awt.Component.processEvent(Component.java:5319)
at java.awt.Container.processEvent(Container.java:2010)
at java.awt.Component.dispatchEventImpl(Component.java:4021)
at java.awt.Container.dispatchEventImpl(Container.java:2068)
at java.awt.Component.dispatchEvent(Component.java:3869)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4256)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3936)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3866)
at java.awt.Container.dispatchEventImpl(Container.java:2054)
at java.awt.Window.dispatchEventImpl(Window.java:1774)
at java.awt.Component.dispatchEvent(Component.java:3869)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:463)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(EventDispatchThread.java:275)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:190)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:182)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:110)

This is not the case if use( filters ) is called before upadting the selection in the setFilters method of the JXTable.
Thanks to you for the good work :-)

Ciao

Nicola

P.S.: Sorry for indentation, but it is eaten when I post the message.

Kleopatra

Nicola,

>
> Ok, I tried to keep as simple as possible:
>
>
> package example;
>

[ example snipped ]

> This is not the case if use( filters ) is called before
> upadting the selection in the setFilters method of the JXTable.

I seee ... looks like I need to have another round on state manegement :-)

Thanks a lot - examples like this are tremendously helpful to find the
rough spots!

>
>
> P.S.: Sorry for indentation, but it is eaten when I post the message.

it's okay on the mailing list, in the forum you can surround code blocks
by [code]...[/code] to keep the formatting.

Cheers
Jeanette

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

dags
Offline
Joined: 2003-06-10

It seems that I don't have commit access to jdnc-incubator. It is that "incubator" that you told me, isn't it?.

I am listed as signer of swinglabs JCA and not listed as signer of jdnc-incubator JCA.

I don't have commit access to swinglabs.

I tried to add a src/dags directory in jdnc-incubator but get rejected.

Regards,
Diego.

kleopatra
Offline
Joined: 2003-06-11

> It seems that I don't have commit access to
> jdnc-incubator. It is that "incubator" that you told
> me, isn't it?.
>
> I am listed as signer of swinglabs JCA and not listed
> as signer of jdnc-incubator JCA.

hmm, you should automatically have gained commit access for the incubator .. I'll ping Richard, maybe there's something else to do.

Jeanette

Frederic Lavigne

jdnc-interest@javadesktop.org wrote:
>> There are some other .properties in swingx project,
>> like TipOfTheDay. Can I translated it too ?.
>>
>
> Would be great! (Fred, any objections?)

Go ahead! I'll look at the other RBs and provide French translations.

-fred

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

dags
Offline
Joined: 2003-06-10

JDNC_JCA signed and sended this morning by fax.

Regards,
Diego.

Kleopatra

jdnc-interest@javadesktop.org wrote:
> JDNC_JCA signed and sended this morning by fax.
>

received - great! The spanish properties are committed - with one minor
change: packing on selected will be on one column only, so I changed the
plural to singular.

Which reminds me: the usability of the action is a bit weird, need to
cleanup in JXTable...

Thanks!
Jeanette

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

dags
Offline
Joined: 2003-06-10

There are some other .properties in swingx project, like TipOfTheDay. Can I translated it too ?.

How will be the procedure to maintain these translations ?. I guess I can't commit these files myself.

Regards,
Diego.

kleopatra
Offline
Joined: 2003-06-11

> There are some other .properties in swingx project,
> like TipOfTheDay. Can I translated it too ?.
>

Would be great! (Fred, any objections?) One thing I noticed is that the spanish .properties (as well as my german) aren't encoded correctly - need to pass them through native2ascii tool. Forgot the details of the how-to, though, been a long time since I last had to ;-)

> How will be the procedure to maintain these
> translations ?. I guess I can't commit these files
> myself.

We don't yet have a procedure, need to come up with something. For a start, you could commit/maintain them to/in the incubator and we'll take them from there? Opinions?

Jeanette

dags
Offline
Joined: 2003-06-10

Jeannete:

The first time I tried the spanish translation, before sending it to you, I made a new swingx.jar and tried it with some demo forms. I realized then that was something wrong with encoding. After that, I edited the properties files with Netbeans editor, tried again and seems to be OK. Maybe "cut and paste" into web form may have affected it ?.

Anyway, I will maintain these files in incubator. Please check later and tell me if encoding is correct.

Netbeans use a separated [b]translatedfiles[/b] project to hold all translations. We, translators, are granted access to this project only. Maybe in a future it could be nice to implement something like that.

Regards,
Diego.

kleopatra
Offline
Joined: 2003-06-11

> Jeannete:
>
> The first time I tried the spanish translation,
> before sending it to you, I made a new swingx.jar and
> tried it with some demo forms. I realized then that
> was something wrong with encoding. After that, I
> edited the properties files with Netbeans editor,
> tried again and seems to be OK. Maybe "cut and paste"
> into web form may have affected it ?.
>

oh, sorry for being unclear: the outcome looks ok on my screen after setting the default locale to es. But I faintly remember that instead of having any non-ascii character (like f.i. "ü") in the properties there should be the unicode-escaped (not sure if that's the correct name for it and too lazy to look into the doc right now) \uXXXX. Fred's RBs are doing the right thing looking into them might give you an idea of what I meant :-)
The native2ascii does the conversion (again a faint memory)

Great to have various native speakers around!
Jeanette

PS: slightly embarassing - but what is the usual german translation for "wrap search"?

dags
Offline
Joined: 2003-06-10

OK. I got it and tried.

As soon as I get commit access, I will upload others translations.

Regards.
Diego.

rbair
Offline
Joined: 2003-07-08

> As soon as I get commit access, I will upload others
> translations.

You got it. Happy translating :)

Richard

Patrick Wright

Thought: would be nice to have a utility, ideally run from Ant, to
check that for a given translation file, all keys in a given class
have been translated. Might be able to do this with an AST-based
rule-checked like PMD or CheckStyle.

Tutorial on writing a rule in PMD
http://pmd.sourceforge.net/howtowritearule.html

and CheckStyle
http://checkstyle.sourceforge.net/writingchecks.html

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

nicfagn
Offline
Joined: 2003-06-14

> - selection: by default, the selection in view
> coordinates is kept in synch with selection in model
> coordinates automatically. There should be no need to
> do it manually, in fact I would rather expect the
> manual interference to come into the way of the
> automatics. That said: you might have hit a bug - the
> automatic synch is (meant to be guaranteed if the
> filter is updated (as opposed of setting a new
> filter), but from the top of my head, I don't recall
> what happens on setting a new filter.

I had an exception like Diego, when I tried to update my old swingx code to a recent build. I had a selection listener on a JXTable to keep in sync some controls with the current row.
After digging the code I focused my attention on the setFilters method of JXTable:

/** Sets the FilterPipeline for filtering table rows. */
public void setFilters(FilterPipeline pipeline) {
FilterPipeline old = getFilters();
Sorter sorter = null;
if (old != null) {
old.removePipelineListener(pipelineListener);
sorter = old.getSorter();
}
if (pipeline == null) {
pipeline = new FilterPipeline();
}
filters = pipeline;
filters.setSorter(sorter);
getSelection().setFilters(filters);
getRowSizing().setFilters(filters);
use(filters); <-- Pipeline updated after selection
}

The pipeline is updated with the new filters after the selection. But an update of the selection will trigger its listeners that will found an inconsistent state hence the exception.
I fixed this in my local code as follows:

use(filters); <-- Pipeline updated after selection
getSelection().setFilters(filters);
getRowSizing().setFilters(filters);
//use(filters); <-- Pipeline updated after selection

It' clearly a quick hack but it's working for me now, and it passed the existing tests.
Hope will help.

Bye

Nicola

kleopatra
Offline
Joined: 2003-06-11

Hi Nicola,

> After digging the code I focused my attention on the
> setFilters method of JXTable:
>

Sounds like your context is slightly different from Diego's initial example - there the exception is thrown in the jxTable1.setRowSelectionInterval(..) and your quick fix doesn't help.

I'm still not quite sure where to really fix it - but it seems to be related to a some (for me) unexpected behaviour in DefaultListSelectionModel: on clearSelection, the lead and anchor are kept and a following setSelectionInterval fires a selectionEvent covering the total range between the given index and the old lead. The class responsible for synching view <--> model selection indices (called Selection ... suggestions for a better name are welcome!) doesn't expect - yet - to get a _view_ index from the view selectionModel which is out of range of the view. The overall behaviour (throwing the exception) is clearly a bug, but I'm not sure if it's a bug of the synch or of the DefaultListSelectionModel - must check its api more thoroughly.

[...]

> The pipeline is updated with the new filters after
> the selection. But an update of the selection will
> trigger its listeners that will found an inconsistent
> state hence the exception.
> I fixed this in my local code as follows:
>
> use(filters); <-- Pipeline updated after
> ed after selection
> getSelection().setFilters(filters);
> getRowSizing().setFilters(filters);
> //use(filters); <-- Pipeline updated after
> ed after selection
>

hmm ... on the surface I wouldn't expect it to be a problem in the general case because at the moment of selection.setFilters(..) the filter is not yet assigned to the componentAdapter (that's done in the use()). But as it makes a difference in your context, I'm probably missing something :-) Could you please show a small runnable example that's showing the problem which is fixed by changing the sequence of method calls?

Thanks!
Jeanette

Kleopatra

Looks like an incomplete (or none at all :-) update of lead/anchor in
the view selectionModel. Probably eed to enhance Selection to take care
of it.

filed a bug:

https://swingx.dev.java.net/issues/show_bug.cgi?id=172

Thanks for bringing it to my attention!
Jeanette

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

dags
Offline
Joined: 2003-06-10

Jeanette:

I tried your suggestions and worked very well, with some minor changes:

[code]
int matchFlags = java.util.regex.Pattern.UNICODE_CASE;
int col = jXTable1.getColumn("Titulo").getModelIndex();
PatternFilter filter = new PatternFilter(".*", matchFlags, col);
jXTable1.setFilters(new FilterPipeline(new Filter[] { filtro } ) );
myFilterPanel.setPatternFilter(filtro);
[/code]
instead of
[code]
PatternFilter filter = new PatternFilter(col);
myTable.setFilters(new FilterPipeline(new Filter[] {filter)});
myFilterPanel.setPatternMatcher(filter);
[/code]

Because PatternFilter(int Column) constructor do not exist.

Options in JXSearchPanel combobox are not localized, even when include in swing_es.properties. I guess org.jdesktop.swingx.PatternModel.java should be fixed.

Besides that, now JXSearchPanel captions are in Spanish ! ;-).

Regards,
Diego.

kleopatra
Offline
Joined: 2003-06-11

Diego,

>
> I tried your suggestions and worked very well, with
> some minor changes:
>
> [code]
> int matchFlags =
> java.util.regex.Pattern.UNICODE_CASE;
> int col =
> jXTable1.getColumn("Titulo").getModelIndex();
> PatternFilter filter = new PatternFilter(".*",
> matchFlags, col);
> [/code]

alternatively you could (working around the missing constructor):

[code]
PatternFilter filter = new PatternFilter();
filter.setColumnIndex(col);
...
[/code]

> Options in JXSearchPanel combobox are not localized,
> even when include in swing_es.properties. I guess
> org.jdesktop.swingx.PatternModel.java should be
> fixed.
>

ehemmm... that's still TBD (though not in the PatternModel but in the ui using the PatternModel) - there's a carefully hidden code comment in JXSearchPanel to that extent .

BTW, while quickly implementing a custom filter panel, I found some slight quirks in the current AbstractPatternPanel - always good to excercise the base implementations, thanks for triggering me! Just if anybody is interested, here's the code (probably principally very similar to what you have):

[code]
/*
* Created on 28.09.2005
*
*/
package org.jdesktop.swingx;

import javax.swing.JButton;
import javax.swing.JLabel;

import org.jdesktop.swingx.decorator.PatternMatcher;

public class CustomFilterPanel extends AbstractPatternPanel {
private static final String CLEAR_FILTER_ACTION_COMMAND = "clearFilter";

private PatternMatcher patternMatcher;
private JButton clearButton;

public CustomFilterPanel() {
initComponents();
build();
initActions();
bind();
getPatternModel().setIncremental(true);
}

public void setPatternMatcher(PatternMatcher matcher) {
if (patternMatcher != null) {
patternMatcher.setPattern(null);
}
patternMatcher = matcher;
}

/**
* The callback method bound to the Action registered for
* CLEAR_FILTER_ACTION_COMMAND.
*
*/
public void clearFilterText() {
getPatternModel().setRawText("");
}

@Override
public void match() {
patternMatcher.setPattern(getPatternModel().getPattern());
}

// ----------------- bind
@Override
protected void bind() {
super.bind();
clearButton.setAction(getAction(CLEAR_FILTER_ACTION_COMMAND));
}

// -------------------- init ui
@Override
protected void initComponents() {
super.initComponents();
clearButton = new JButton();
}

@Override
protected void initExecutables() {
super.initExecutables();
getActionMap().put(CLEAR_FILTER_ACTION_COMMAND,
createBoundAction(CLEAR_FILTER_ACTION_COMMAND, "clearFilterText"));
}

protected void build() {
add(searchLabel);
add(new JLabel(":"));
add(new JLabel(" "));
add(searchField);
add(clearButton);

}

}

[/code]

> Besides that, now JXSearchPanel captions are in
> Spanish ! ;-).
>

great! For being legally on the safe side, I'll wait with including your resources until green light from above.

Jeanette

kleopatra
Offline
Joined: 2003-06-11

Hi Diego,

guessing from your code snippets, you might be using a rather old version (or a newer version with a slightly outdated approach - don't get me wrong, it's definitely *my* fault for not providing a better documentation of changes!).

A couple of comments:

- as a starting point for implementing custom filter/search widgets you might consider looking at the PatternModel/AbstractPatternPanel: the model is responsible for compiling a given rawtext into a pattern, the latter provides some reasonable default ui bindings. For a concrete implementation you might want to have a look at the JXSearchPanel (misleading name, I know, it's historical and implement a custom panel along those lines. To use and bind your custom panel to the table filtering you would do something like:

[code]
PatternFilter filter = new PatternFilter(col);
myTable.setFilters(new FilterPipeline(new Filter[] {filter)});
myFilterPanel.setPatternMatcher(filter);

[/code]

That's all - the PatternModel defaults to case-insensitive and "contains", your custom text field is bound to the pattern of the filter which in turn triggers the update of the table.

- selection: by default, the selection in view coordinates is kept in synch with selection in model coordinates automatically. There should be no need to do it manually, in fact I would rather expect the manual interference to come into the way of the automatics. That said: you might have hit a bug - the automatic synch is (meant to be guaranteed if the filter is updated (as opposed of setting a new filter), but from the top of my head, I don't recall what happens on setting a new filter.

HTH - if not, you are welcome to come back and nail me

Jeanette

dags
Offline
Joined: 2003-06-10

Jeanette:

I am using a frequently updated CVS checkout. Probably my mind doesn't go as fast as code changes :-).

I will try your hints and let you know.

Anyway, I still have a doubt : why if I call
[code]
if (viewRow >= 0) {
jXTable1.setRowSelectionInterval(viewRow, viewRow);
}
[/code]
where viewRow is = 1487 I get and Exception because at org.jdesktop.swingx.decorator.PatternFilter.mapTowardModel seems to be trying to get an out-of-bounds item (index = 1712 and rowCount = 1712 ?.

I will try to make a simple example to reproduce this behavior and post it.

Thanks for the wonderful job that you and the other swinglabs people are doing.

Please try to have in mind localization from the beginning (I speak spanish). I can do it myself but it means loosing code compatibility with your repository.

Regards,
Diego.

kleopatra
Offline
Joined: 2003-06-11

Diego,

> I am using a frequently updated CVS checkout.
> Probably my mind doesn't go as fast as code changes
> :-).
>

okay :-)

> I will try your hints and let you know.
>

Looking forward to hear from you!

> Anyway, I still have a doubt : why if I call
> [code]
> if (viewRow >= 0) {
> jXTable1.setRowSelectionInterval(viewRow,
> ow, viewRow);
> }
> [/code]
> where viewRow is = 1487 I get and Exception because
> at
> org.jdesktop.swingx.decorator.PatternFilter.mapTowardM
> odel seems to be trying to get an out-of-bounds item
> (index = 1712 and rowCount = 1712 ?.
>
> I will try to make a simple example to reproduce this
> behavior and post it.
>

you might well have hit a not-yet-known bug here - difficult to tell. A simple example would be great, then we can try to track it down.

> Thanks for the wonderful job that you and the other
> swinglabs people are doing.
>

Thanks! A slap on the back now and then keeps us going :-)

> Please try to have in mind localization from the
> beginning (I speak spanish). I can do it myself but
> it means loosing code compatibility with your
> repository.
>

Would you volunteer to contribute the spanish resources? There's a swingx.properties in plaf.resources which currently contains the default (english) base and a german version. It's loaded by default - on request of widgets which contain/use potentially localizable resources.

Thanks
Jeanette

dags
Offline
Joined: 2003-06-10

Jeanette:

Here is the code to reproduce what I am saying. I deleted some of netbeans generated code to make it smaller. Hope it helps. To reproduce the exception, first select row with "code 2279" which is, surprise!, row number 2279. After that, enter 2 in filter textfield. As soon as you enter 2, exception happens.

I use a similar bean to make some kind of "database navigator", where TableModel is populated from a postgresql database (any jdbc). That way, user can find and select Products (i.e.) very easily. I know, I must see databinding someday.

I will very happy to contribute with spanish resources. I am current spanish translator for pgadmin3 (www.pgadmin.org) and recently started translating netbeans (translatedfiles.netbeans.org). Just let me know what to do.

Regards,
Diego.

[code]
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.JLabel;
import java.util.Vector;

import org.jdesktop.swingx.decorator.Filter;
import org.jdesktop.swingx.decorator.FilterPipeline;
import org.jdesktop.swingx.decorator.PatternFilter;

public class JXTableTest extends javax.swing.JFrame implements DocumentListener {

public JXTableTest() {
initComponents();
this.setSize(640,240);
filterTextField.getDocument().addDocumentListener(this);
loadData();
}

private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
filterTextField = new javax.swing.JTextField();
clearFilterButton = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
jXTable1 = new org.jdesktop.swingx.JXTable();
rowsLabel = new javax.swing.JLabel();

FormListener formListener = new FormListener();

setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jLabel1.setText("Enter filter text");
jPanel1.add(jLabel1);

filterTextField.setColumns(15);
jPanel1.add(filterTextField);

clearFilterButton.setText("Clear Filter");
clearFilterButton.addActionListener(formListener);

jPanel1.add(clearFilterButton);

getContentPane().add(jPanel1, java.awt.BorderLayout.NORTH);

jXTable1.setVisibleRowCount(10);
jScrollPane1.setViewportView(jXTable1);

getContentPane().add(jScrollPane1, java.awt.BorderLayout.CENTER);

rowsLabel.setText("Showing ...");
getContentPane().add(rowsLabel, java.awt.BorderLayout.SOUTH);

pack();
}

private class FormListener implements java.awt.event.ActionListener {
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (evt.getSource() == clearFilterButton) {
JXTableTest.this.clearFilterButtonActionPerformed(evt);
}
}
}

private void clearFilterButtonActionPerformed(java.awt.event.ActionEvent evt) {
filterTextField.setText("");
}

private void loadData() {

Vector tableData;
Vector rowData;
Vector colNames;

colNames = new Vector(2);
colNames.add("Code");
colNames.add("Description");

tableData = new Vector(3000);

for (int i = 0; i < 3000; i++) {
rowData = new Vector(2);
rowData.add("code " + i);
rowData.add("description (modelIndex " + i + ") ");
tableData.add(rowData);
}

model = new DefaultTableModel(tableData, colNames);

jXTable1.setModel(model);
jXTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
jXTable1.getColumn("Description").setCellRenderer(new MyCellRenderer());

rowsLabel.setText("Showing " + jXTable1.getRowCount() + " of " + model.getRowCount() + " rows ");
jXTable1.revalidate();
jXTable1.packAll();
return;
}

public void removeUpdate(javax.swing.event.DocumentEvent e) {
textFilter();
}

public void insertUpdate(javax.swing.event.DocumentEvent e) {
textFilter();
}

public void changedUpdate(javax.swing.event.DocumentEvent e) {
textFilter();
}

private void textFilter() {
int viewRow, modelRow;
int matchFlags;

int col = jXTable1.getColumn("Description").getModelIndex();

String text2 = ".*" + filterTextField.getText() + ".*";
matchFlags = java.util.regex.Pattern.CASE_INSENSITIVE + java.util.regex.Pattern.UNICODE_CASE;

// store selected row before applying filter
viewRow = jXTable1.getSelectedRow(); // this line should be deleted
modelRow = viewRow >= 0 ? jXTable1.convertRowIndexToModel(viewRow) : -1; // this line should be deleted

// clear selection to avoid troubles if new filtered table does not include selected values ...
// must be reviewed later
jXTable1.clearSelection(); // this line should be deleted

try {
jXTable1.setFilters(new FilterPipeline(new Filter[] { new PatternFilter(text2, matchFlags, col) } ));
} catch(java.util.regex.PatternSyntaxException pse) {
System.out.println(pse);
}
rowsLabel.setText("Showing " + jXTable1.getRowCount() + " of " + model.getRowCount() + " rows ");

// try to select former selected row, if showing in filtered table ...
viewRow = modelRow >= 0 ? jXTable1.convertRowIndexToView(modelRow) : -1; // this line should be deleted

if (viewRow >= 0) { // this line should be deleted
// I got the exception here ...
System.out.println("viewRow is " + viewRow);
jXTable1.setRowSelectionInterval(viewRow, viewRow); // this line should be deleted
} // this line should be deleted
}

class MyCellRenderer extends DefaultTableCellRenderer {
public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {

JLabel retValue;

retValue = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

// add viewIndex to rendered row
String text = retValue.getText() + " (viewIndex " + row + ") ";

retValue.setText(text);

return retValue;
}
}

public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new JXTableTest().setVisible(true);
}
});
}

javax.swing.JButton clearFilterButton;
javax.swing.JTextField filterTextField;
javax.swing.JLabel jLabel1;
javax.swing.JPanel jPanel1;
javax.swing.JScrollPane jScrollPane1;
org.jdesktop.swingx.JXTable jXTable1;
javax.swing.JLabel rowsLabel;
private DefaultTableModel model;
}

[/code]

kleopatra
Offline
Joined: 2003-06-11

Hi Diego,

thanks for the example - will come back to you as soon as I have a chance to look into it!

Great that you are volunteering for the spanish translation - I'll check if there's any legal hurdle.

Jeanette

dags
Offline
Joined: 2003-06-10

Jeanette:

Here is my swingx_es.properties. I guess I have to sign some sort of copyright stuff. But meanwhile here it is. If you tell me how, I can send you this file as an attachment.

Regards,
Diego.

[code]
# spanish properties for swingx
# JXSearchPanel

Search.matchCase=Coincidencia de mayúsculas/minúsculas
Search.contains=contiene
Search.equals=igual
Search.endsWith=termina con
Search.startsWith=empieza con

Search.wrapSearch=Búsqueda Circular
Search.backwardsSearch=Hacia Atrás
Search.match=Buscar
Search.close=Cerrar
Search.findNext=Buscar Siguiente
Search.findPrevious=Buscar Anterior
Search.searchFieldLabel=Buscar
Search.searchFieldLabel.mnemonic=B
Search.searchTitle=Buscar

XDialog.close=Cerrar
XDialog.cancel=Cancelar
XDialog.execute=Aceptar

# default properties for swingx
# JXTable column control entries
#
JXTable.column.horizontalScroll=Desplazamiento Horizontal
JXTable.column.packAll=Compactar Todas las Columnas
JXTable.column.packSelected=Compactar Las Columnas Seleccionadas

#
# default actions in context menues for TextComponents
#
DefaultEditorKit.cut-to-clipboard=Cortar
DefaultEditorKit.copy-to-clipboard=Copiar
DefaultEditorKit.paste-from-clipboard=Pegar
DefaultEditorKit.delete-next=Eliminar
DefaultEditorKit.select-all=Seleccionar Todo

#
# default actions for context menue for ScrollBars
#
JScrollBar.vertical.minScroll=Arriba
JScrollBar.vertical.maxScroll=Abajo
JScrollBar.vertical.negativeUnitIncrement=Desplazar hacia Arriba
JScrollBar.vertical.negativeBlockIncrement=Página Arriba
JScrollBar.vertical.positiveUnitIncrement=Desplazar hacia Abajo
JScrollBar.vertical.positiveBlockIncrement=Página Abajo

JScrollBar.horizontal.minScroll=Borde Izquierdo
JScrollBar.horizontal.maxScroll=Borde Derecho
JScrollBar.horizontal.negativeUnitIncrement=Desplazar a la Izquierda
JScrollBar.horizontal.negativeBlockIncrement=Página Izquierda
JScrollBar.horizontal.positiveUnitIncrement=Desplazar a la Derecha
JScrollBar.horizontal.positiveBlockIncrement=Página Derecha
[/code]

dags
Offline
Joined: 2003-06-10

Jeanette:

There is a wrong link to JDNC JCA pdf file. It is :

https://swinglabs.dev.java.net/documentation/JDNC_JCA.pdf

and should be :

https://jdnc.dev.java.net/documentation/JDNC_JCA.pdf

Regards,
Diego.

kleopatra
Offline
Joined: 2003-06-11

Oops - have to copy the pdf :-)

Did you sign and send it, anyway? Would like to include the spanish properties asap.

Thanks
Jeanette

dags
Offline
Joined: 2003-06-10

No. I will send it this afternoon, when I wil be near a fax machine.

Regards,
Diego.