Skip to main content

JXTable does not work with Glazed Lists anymore (since SwingX 1.6)

4 replies [Last post]
kameit00
Offline
Joined: 2007-12-20

Hello,

I have a problem with JXTable & Glazed Lists. Since I updated SwingX from 1.0 to 1.6.1 I get IndexOutOfBoundsException's at places, that were fine before.
I get the problem with 1.6.1 and 1.6 but not with 1.0.

I switched of sorting, like mentioned on the Glazed Lists homepage. But I figured out, that I also have to set the default RowSorter to null to avoid the exceptoin.

- What's the difference here in JXTable >=1.6 and JXTable 1.0?
- What is the "right way" of doing things now? Setting the RowSorter to null?

Another thing that confuses me...
EventList.remove(...) works, EventList.clear() results in the exception. Both worked in SwingX's 1.0 JXTable.

Sorry, if I'm at the wrong place here, but for me it seems more like a SwingX issue at the moment, than like a Glazed Lists one. Correct me, if I'm wrong :-)

Here is some code to reproduce the problem (versions: SwingX 1.6.1, Glazed Lists 1.8.0, Java 1.6.0_21, Windows XP):

<br />
import javax.swing.SwingUtilities;</p>
<p>import org.jdesktop.swingx.JXTable;</p>
<p>import ca.odell.glazedlists.BasicEventList;<br />
import ca.odell.glazedlists.EventList;<br />
import ca.odell.glazedlists.SortedList;<br />
import ca.odell.glazedlists.gui.TableFormat;<br />
import ca.odell.glazedlists.swing.EventTableModel;</p>
<p>public class ErrorTest {</p>
<p>	private static final class StringTableFormat implements TableFormat {<br />
		@Override<br />
		public int getColumnCount() {<br />
			return 1;<br />
		}</p>
<p>		@Override<br />
		public String getColumnName(int column) {<br />
			return "Strings";<br />
		}</p>
<p>		@Override<br />
		public Object getColumnValue(String baseObject, int column) {<br />
			return baseObject;<br />
		}<br />
	}</p>
<p>	public static void main(String[] args) {<br />
		SwingUtilities.invokeLater(new Runnable() {<br />
			@Override<br />
			public void run() {<br />
				final EventList eventList = new BasicEventList();<br />
				eventList.add("1");<br />
				eventList.add("2");<br />
				eventList.add("3");<br />
				final SortedList sortedList = new SortedList(eventList);</p>
<p>				final TableFormat tableFormat = new StringTableFormat();<br />
				final EventTableModel tableModel = new EventTableModel(sortedList, tableFormat);</p>
<p>				final JXTable table = new JXTable(tableModel);</p>
<p>				// for using Glazed Lists<br />
				table.setSortable(false);</p>
<p>				// ==>> No crash with RowSorter set to null<br />
				// table.setRowSorter(null);</p>
<p>				// fine<br />
				eventList.remove(0);</p>
<p>				// crashes if RowSorter wasn't set to null<br />
				eventList.clear();<br />
			}<br />
		});<br />
	}<br />
}<br />

and the StackTrace:

<br />
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range<br />
	at javax.swing.DefaultRowSorter.rowsDeleted(Unknown Source)<br />
	at org.jdesktop.swingx.sort.DefaultSortController.rowsDeleted(DefaultSortController.java:398)<br />
	at javax.swing.JTable.notifySorter(Unknown Source)<br />
	at javax.swing.JTable.sortedTableChanged(Unknown Source)<br />
	at javax.swing.JTable.tableChanged(Unknown Source)<br />
	at org.jdesktop.swingx.JXTable.tableChanged(JXTable.java:1529)<br />
	at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)<br />
	at ca.odell.glazedlists.swing.EventTableModel.handleListChange(EventTableModel.java:189)<br />
	at ca.odell.glazedlists.swing.EventTableModel.listChanged(EventTableModel.java:170)<br />
	at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:412)<br />
	at ca.odell.glazedlists.event.ListEventAssembler$ListEventFormat.fire(ListEventAssembler.java:409)<br />
	at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher$SubjectAndListener.firePendingEvent(SequenceDependenciesEventPublisher.java:445)<br />
	at ca.odell.glazedlists.event.SequenceDependenciesEventPublisher.fireEvent(SequenceDependenciesEventPublisher.java:344)<br />
	at ca.odell.glazedlists.event.ListEventAssembler.commitEvent(ListEventAssembler.java:316)<br />
	at ca.odell.glazedlists.BasicEventList.clear(BasicEventList.java:199)<br />
	at ErrorTest$1.run(ErrorTest.java:55)<br />
	at java.awt.event.InvocationEvent.dispatch(Unknown Source)<br />
	at java.awt.EventQueue.dispatchEvent(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)<br />
	at java.awt.EventDispatchThread.pumpEvents(Unknown Source)<br />
	at java.awt.EventDispatchThread.run(Unknown Source)<br />

Regards
Kai

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
kameit00
Offline
Joined: 2007-12-20

Thank you for the fast answer Jeanette! That helps :)

kleopatra
Offline
Joined: 2003-06-11

The difference between SwingX 1.0 and 1.6 is target jdk version: the latter uses core sort/filtering mechanism

The difference between JXTable and core JTable sort/filter is that the former's autoCreateRowSorter defaults to true (plus it controls the sorte's properties) which causes the exception

To disable:

[code]
JXTable table = new JXTable();
table.setAutoCreateRowSorter(false);
table.setRowSorter(null);
table.setModel(myModel);
[/code]

HTH
Jeanette

cmadsen_dk
Offline
Joined: 2005-09-29

Doing the table.setRowSorter(null) makes my tables behave again after updating to 1.6 but I have some code (borrowed from somewhere) that saves the state of the jxtable that no longer works because getRowSorter returns null:
public static class XTableProperty implements SessionStorage.Property {
@Override
public Object getSessionState(Component c) {
checkComponent(c);
JXTable table = (JXTable) c;
List<ColumnState> columnStates = new ArrayList<ColumnState>();
List<TableColumn> columns = table.getColumns(true);
List<TableColumn> visibleColumns = table.getColumns();
for (TableColumn column : columns) {
columnStates.add(new ColumnState((TableColumnExt) column,
visibleColumns.indexOf(column)));
}
XTableState tableState = new XTableState(columnStates
.toArray(new ColumnState[columnStates.size()]));
tableState.setHorizontalScrollEnabled(table
.isHorizontalScrollEnabled());
final List<? extends RowSorter.SortKey> keys = table.getRowSorter()
.getSortKeys();
RowSorter.SortKey sortKey = null;
for (RowSorter.SortKey key : keys) {
if (!SortOrder.UNSORTED.equals(key.getSortOrder())) {
sortKey = key;
break;
}
}
if (sortKey != null) {
tableState.setSortKey(sortKey);
}
return tableState;
}
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at org.jdesktop.appframework.swingx.XProperties$XTableProperty.getSessionState(XProperties.java:116)
at org.jdesktop.application.SessionStorage.saveTree(SessionStorage.java:251)
at org.jdesktop.application.SessionStorage.save(SessionStorage.java:320)
So how do I access and the sorting state of the JXtable provided Glazed Lists?

kleopatra
Offline
Joined: 2003-06-11

fix the error in the borrowed code (which is not formally supported, though still in my incubator section :-) which is to guard against null when accessing the getRowSorter.

RowSorter sorter = table.getRowSorter();

if (sorter != null) {
  List sortKeys = sorter.getSortKeys();
  ,,,, 
}

CU
Jeanette