|
View:
New views
15 Messages
—
Rating Filter:
Alert me
|
|
|
EventListJXTableSortingI am attempting to create a table using JXTable and glazedLists. My problem is the sorting. Things seem to work fine UNLESS I call
EventListJXTableSorting.install( imageTable, sortedList ); When I add that call, the table is not sorted until I select one of the headers. Here is the method that creates the table: private JScrollPane getFilteredList() { JScrollPane scrollImageTable = null; imageList.getReadWriteLock().writeLock().lock(); try { SortedList< ImageSignature > sortedList = new SortedList< ImageSignature >( imageList, new ImageSizeComparator() ); EventTableModel< ImageSignature > tableModel = new EventTableModel< ImageSignature >( sortedList, new ImageTableFormat() ); JXTable imageTable = new DroppableTable( tableModel ); EventListJXTableSorting sorting = EventListJXTableSorting.install( imageTable, sortedList ); sorting.setMultipleColumnSort( false ); scrollImageTable = new JScrollPane( imageTable ); imageTable.setHighlighters( HighlighterFactory.createAlternateStriping(), new RolloverHighlighter( Color.BLACK, Color.white ) ); imageTable.setRolloverEnabled( true ); imageTable.setHorizontalScrollEnabled( true ); imageTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); imageTable.setColumnControlVisible( true ); TableSelectionListener selectionListener = new TableSelectionListener( imageTable ); imageTable.getSelectionModel().addListSelectionListener( selectionListener ); } finally { imageList.getReadWriteLock().writeLock().unlock(); } return scrollImageTable; } |
|
|
Re: EventListJXTableSortingSteve,
I'm unsure of what your exact problem is. In GL, tables stay unsorted until you click on the header once. We don't have the concept of a default table order (yet). What is incorrect about not sorting the table until the header is clicked? James On 7/25/07, Steve Newell <newellista@...> wrote:
|
|
|
Re: EventListJXTableSortingActually, my list IS initially sorted, which is what I expected. I thought that since I was passing the sortedList to my EventTableModel, it would sort initially. Is that not correct?
My application creates a list of images and displays them in the JXTable. I would like the image list to be sorted by size initially. That is what happens when I don't call EventListJXTableSorting.install( ... ). Also, if I add a FilterList to the table, everything appears to work until I change the filter. Once the I change the filter, I only get one entry, no matter what else I try.
|
|
|
Re: EventListJXTableSorting2. Jesse needs to weigh in on EventListJXTableSorting since he authored it. 3. If your FilterList is not behaving correctly then either a) your Matcher logic isn't doing the right thing b) your MatcherEditor (if any) is firing the wrong kind of MatcherEditor.Event because you are calling the fire method. i.e. make sure you're calling fireConstrained, fireRelaxed, etc at the appropriate times. 4. The best way for me to make headway on your EventListJXTableSorting bug is for you to produce a test class that demonstrates it. I can promise a speedy resolution if you can do that. James
On 7/27/07, Steve Newell <newellista@...
> wrote:
|
|
|
Re: EventListJXTableSortingI have created a test case that demonstrates the problems I am having. To summarize:
1. JTable works exactly as I would expect. 2. JXTable without EventListJXTableSorting does the following: a. If I don't set a breakpoint on the pack() call in the constructor, the program hangs. It seems to hang attempting to get a ReadLock. Here is the stack trace: ![]() b. If I do set the breakpoint on the pack() call, and run past that, things seem to work, except when you click on the column header to sort a column, I get two up/down arrows. ![]() 3. JXTable with EventListJXTableSorting does the following: a. Same problem with the readlock as described above b. List is not in sorted order initially, even though I specify a Comparator in the SortedList constructor c. Clicking on the column header does cause the sort to occur, but there are two up/down arrows in the header, as above, but one is pointing up, and the other is pointing down. ![]() Here is the source that demonstrates the problem. I am using glazedlists_java1.5.jar, the latest swingx.jar. I am running on Mac OS X with Java 1.5.0_07. If I can do anything more to help debug/isolate the problem, let me know. Thanks again for all your help. Steve package problem; import java.awt.BorderLayout; import java.awt.Color; import java.util.Comparator; import java.util.Random; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import org.jdesktop.swingx.JXTable; import org.jdesktop.swingx.decorator.HighlighterFactory; import org.jdesktop.swingx.decorator.RolloverHighlighter; import ca.odell.glazedlists.BasicEventList; import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.SortedList; import ca.odell.glazedlists.gui.AbstractTableComparatorChooser; import ca.odell.glazedlists.gui.TableFormat; import ca.odell.glazedlists.swing.EventListJXTableSorting; import ca.odell.glazedlists.swing.EventTableModel; import ca.odell.glazedlists.swing.TableComparatorChooser; public class GlazedListJXTableProblem extends JFrame { public GlazedListJXTableProblem() { initialize( "JTable" ); } public GlazedListJXTableProblem( String whichList ) { initialize( whichList ); } private void initialize( String whichList ) { JPanel panel = new JPanel( new BorderLayout() ); panel.add( getList( whichList ), BorderLayout.CENTER ); getContentPane().setLayout( new BorderLayout() ); getContentPane().add( panel, BorderLayout.CENTER ); pack(); } private JScrollPane getList( String whichList ) { if( whichList.equals( "JTable" ) ) { return getJTable(); } else if( whichList.equals( "JXTableGLSorting" ) ) { return getJXTableGLSorting(); } else if( whichList.equals( "JXTableJXSorting" ) ) { return getJXTableJXSorting(); } return null; } private JScrollPane getJXTableGLSorting() { JScrollPane scrollImageTable = null; EventList< ImageSignature > imageList = new BasicEventList< ImageSignature >(); SortedList< ImageSignature > sortedList = new SortedList< ImageSignature >( imageList, new ImageSizeComparator() ); EventTableModel< ImageSignature > tableModel = new EventTableModel< ImageSignature >( sortedList, new ImageTableFormat() ); JXTable imageTable = new JXTable( tableModel ); TableComparatorChooser.install( imageTable, sortedList, AbstractTableComparatorChooser.SINGLE_COLUMN ); scrollImageTable = new JScrollPane( imageTable ); imageTable.setHighlighters( HighlighterFactory.createAlternateStriping(), new RolloverHighlighter( Color.BLACK, Color.white ) ); imageTable.setRolloverEnabled( true ); imageTable.setHorizontalScrollEnabled( true ); imageTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); imageTable.setColumnControlVisible( true ); insertTestData( imageList ); return scrollImageTable; } private JScrollPane getJTable() { JScrollPane scrollImageTable = null; EventList< ImageSignature > imageList = new BasicEventList< ImageSignature >(); SortedList< ImageSignature > sortedList = new SortedList< ImageSignature >( imageList, new ImageSizeComparator() ); EventTableModel< ImageSignature > tableModel = new EventTableModel< ImageSignature >( sortedList, new ImageTableFormat() ); JTable imageTable = new JTable( tableModel ); TableComparatorChooser.install( imageTable, sortedList, AbstractTableComparatorChooser.SINGLE_COLUMN ); scrollImageTable = new JScrollPane( imageTable ); imageTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); insertTestData( imageList ); return scrollImageTable; } private JScrollPane getJXTableJXSorting() { JScrollPane scrollImageTable = null; EventList< ImageSignature > imageList = new BasicEventList< ImageSignature >(); SortedList< ImageSignature > sortedList = new SortedList< ImageSignature >( imageList, new ImageSizeComparator() ); EventTableModel< ImageSignature > tableModel = new EventTableModel< ImageSignature >( sortedList, new ImageTableFormat() ); JXTable imageTable = new JXTable( tableModel ); TableComparatorChooser.install( imageTable, sortedList, AbstractTableComparatorChooser.SINGLE_COLUMN ); EventListJXTableSorting sorting = EventListJXTableSorting.install( imageTable, sortedList ); sorting.setMultipleColumnSort( false ); scrollImageTable = new JScrollPane( imageTable ); imageTable.setHighlighters( HighlighterFactory.createAlternateStriping(), new RolloverHighlighter( Color.BLACK, Color.white ) ); imageTable.setRolloverEnabled( true ); imageTable.setHorizontalScrollEnabled( true ); imageTable.setSelectionMode( ListSelectionModel.SINGLE_SELECTION ); imageTable.setColumnControlVisible( true ); insertTestData( imageList ); return scrollImageTable; } private void insertTestData(EventList< ImageSignature > imageList ) { Random dice = new Random( System.currentTimeMillis() ); imageList.getReadWriteLock().writeLock().lock(); try { for( int i = 0; i < 100; i++ ) { ImageSignature is = new ImageSignature(); is.setDirectory( "Directory" + ( i % 10 ) ); is.setFilename( "filename" + i ); is.setFilesize( Math.abs( dice.nextInt() ) ); imageList.add( is ); } } finally { imageList.getReadWriteLock().writeLock().unlock(); } } class ImageSizeComparator implements Comparator< ImageSignature > { public int compare( ImageSignature sig1, ImageSignature sig2 ) { return ( int ) ( sig2.getFilesize() - sig1.getFilesize() ); } } public static void main( String[] args ) { GlazedListJXTableProblem frame = null; if( args.length > 0 ) { frame = new GlazedListJXTableProblem( args[ 0 ] ); } else { System.out.println( "specify List as first parameter: { JTable | JXTableJXSorting | JXTableGLSorting }"); System.exit( 0 ); } frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.setVisible( true ); } protected static class ImageSignature { private String directory; private String filename; private long fileSize; public String getDirectory() { return directory; } public void setDirectory( String directory ) { this.directory = directory; } public String getFilename() { return filename; } public void setFilename( String filename ) { this.filename = filename; } public long getFilesize() { return fileSize; } public void setFilesize( long fileSize ) { this.fileSize = fileSize; } } protected static class ImageTableFormat implements TableFormat< ImageSignature > { public static final int DIRECTORY = 0; public static final int FILENAME = 1; public static final int SIZE = 2; protected String[] headers; public ImageTableFormat() { headers = new String[] { "Directory", "Filename", "Size" }; } public int getColumnCount() { return 3; } public String getColumnName( int col ) { return headers[ col ]; } public Object getColumnValue( ImageSignature imageSignature, int col ) { switch( col ) { case FILENAME: return imageSignature.getFilename(); case SIZE: return imageSignature.getFilesize(); case DIRECTORY: return imageSignature.getDirectory(); } return null; } } }
|
|
|
Re: EventListJXTableSortingTo followup -- I downloaded the latest glazedlists jar (glazedlists-1.7.0_java15.jar) and the problems still exists exactly as described above. Steve |
|
|
Re: EventListJXTableSortingSteve,
1. Your test class fails to work reliably because you're not building / showing your Swing components on the EDT. Wrap everything in your main method in a Runnable and post it to the EDT like so: SwingUtilities.invokeLater (new Runnable() { public void run() { GlazedListJXTableProblem frame = null; if( args.length > 0 ) { frame = new GlazedListJXTableProblem( args[ 0 ] ); } else { System.out.println( "specify List as first parameter: { JTable | JXTableJXSorting | JXTableGLSorting }"); System.exit( 0 ); } frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); frame.setVisible( true ); } }); 2. I read the class doc for EventListJXTableSorting and it explains how to use it: a) Create a {@link SortedList} and {@link EventTableModel} that depends on that {@link SortedList}. b) Create a {@link JXTable} using the {@link EventTableModel} as its model. c) Run the {@link EventListJXTableSorting#install} method to bind the {@link JXTable}'s headers to the {@link SortedList}'s {@link Comparator}. Notice that it says nothing about TableComparatorChooser. In fact, later in the class doc it even mentions this: "The behaviour of multiple column sorting in JXTable is not particularly flexible. For different configuration options, consider using a {@link TableComparatorChooser} instead of {@link EventListJXTableSorting}." 3. Removing the call to TableComparatorChooser.install seems to produce the behaviour you are looking for. 4. I was using the latest jar of GL and the latest jar of swingx and I never saw two sort icons like the snapshots you pointed at. That said, I'd guess they are caused by having two different table sorting mechanisms in play (TableComparatorChooser and EventListJXTableSorting). Hope this helps, James On 7/30/07, Steve Newell <newellista@...> wrote:
|
|
|
Re: EventListJXTableSortingJames,
Thanks for you response. Indeed, your #1 below solved the lockup problem, and #3 seemed to solve my other problems, EXCEPT... Even though I specified a Comparator in the SortedList constructor, when I install an EventListJXTableSorting the list is unsorted initially. If I do not install it, the list is sorted properly. That leads me to the $64K question... Do I need the EventListJXTableSorting installed if I use a JXTable? From my reading of the wiki, I understood that if I was going to use a JXTable instead of a JTable, and I wanted sorting, I had to either install EventListJXTableSorting OR use a TableComparatorChooser. My experience leads me to believe that this is not the case. It appears that if I create an EventTableModel with a SortedList and create a JXTable with the EventTableModel, everything works. I'm sure I'm missing something, and I appreciate your help in clarifying all this. Steve
|
|
|
Re: EventListJXTableSortingSteve,
1. I am not seeing your results. My table is always ordered by size initially (regardless of whether I use EventListJXTableSorting.install or not), as should be the case with the ImageSizeComparator passed to the constructor of SortedList. The jars I am using are exactly these: https://glazedlists.dev.java.net/servlets/ProjectDocumentList?folderID=3916&expandFolder=3916&folderID=0 (download glazedlists_java15.jar) https://swingx.dev.java.net/files/documents/2981/62446/swingx-2007_07_22-bin.zip (download and extract swingx2007_07_22.jar) 2. Note that EventListJXTableSorting is a way to bind a JXTable header to a SortedList. It is NOT NECESSARY for sorting a JXTable. JXTable and GL both do table sorting, but use different mechanisms to accomplish it. JXTable does all of its sorting in the view, and as such can work with an EventTableModel normally (and without the need for a SortedList or an EventListJXTableSorting object). If all you are looking for is table sorting, you can use JXTable sorting without any problems. EventListJXTableSorting was invented because GL is able to preserve row selections when the table sort order changes (as is also the case with TableComparatorChooser). We do this via a special selection model: EventSelectionModel. But, to use this functionality, GL must *also* control the sorting functionality (with a SortedList). EventListJXTableSorting is a way to wire up the JXTable sorting mechanism to the GL SortedList (which can actually impose the sort order) 3. Perhaps the wiki / class doc should be changed to make it clear *why* you *may* want to use EventListJXTableSorting. It doesn't do that, and perhaps gives you the impression that you *must* do that. 4. GL has a lot of convenience factory methods that make use of reflection to reduce your implementation burdens. You could, for example, replace your TableFormat implementation with the following code: String[] propertyNames = {"directory", "filename", "filesize"}; String[] columnLabels = {"Directory", "Filename", "Size"}; TableFormat tf = GlazedLists.tableFormat(propertyNames, columnLabels); EventTableModel<ImageSignature> tableModel = new EventTableModel<ImageSignature>(sortedList, tf); and save yourself some tedious coding, if you like. James On 7/30/07, Steve Newell <newellista@...> wrote:
|
|
|
Re: EventListJXTableSortingJames,
Thanks for the explaination. I am using the same jars you are, but when I use EventListJXTableSorting.install, the list is not ordered by size initially. I'll give it a try on Linux and/or Windows and see if it is a Mac only problem. Thanks again for your help. Steve |
|
|
Re: EventListJXTableSortingSteve,
I guess it's not impossible that this is an os-specific bug, though GL would not be introducing it. For posterity I'm running JDK 1.6 on Windows XP. James
On 7/30/07, Steve Newell <newellista@...> wrote:
|
|
|
Re: EventListJXTableSortingHi people. Did you ever get to the bottom of this? I'm having the exact same problem. And I can confirm that it is the EventListJXTableSorting.install(table, sortedList); call that is causing the problem.
If you run the simple program below you will see that after I add my ListObject objects they are sorted. When I add them to the EventJXTableModel they are still sorted. After the call to EventListJXTableSorting.install(table, sortedList);, they are no longer sorted. Once the application is visible, I can click on any of the column headers, and as expected, the table and the sorted list are then sorted. There is a workaround in that I can call table.setSortOrder(0, org.jdesktop.swingx.decorator.SortOrder.ASCENDING); after the call to EventListJXTableSorting.install(table, sortedList);, but I would like to get to the bottom of the problem. Thanks, Nick. import ca.odell.glazedlists.BasicEventList; import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.SortedList; import ca.odell.glazedlists.gui.TableFormat; import ca.odell.glazedlists.swing.EventJXTableModel; import ca.odell.glazedlists.swing.EventListJXTableSorting; import ca.odell.glazedlists.swing.EventTableModel; import org.jdesktop.swingx.JXTable; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Comparator; public class JXTableSorting extends JFrame { public JXTableSorting() { EventList<ListObject> eventList = new BasicEventList<ListObject>(); final SortedList<ListObject> sortedList = new SortedList<ListObject>(eventList, new Comparator<ListObject>() { @Override public int compare(ListObject o1, ListObject o2) { return o1.name.compareTo(o2.name); } }); sortedList.add(new ListObject("b", 3, 4.7)); sortedList.add(new ListObject("a", 5, 8.7)); sortedList.add(new ListObject("c", 1, 6.7)); sortedList.add(new ListObject("d", 2, 1.7)); System.out.println("1"); System.out.println(sortedList); EventTableModel<ListObject> eventTableModel = new EventJXTableModel<ListObject>(sortedList, new ListObjectTableFormat()); JXTable table = new JXTable(eventTableModel); table.setColumnControlVisible(true); table.setFillsViewportHeight(true); System.out.println("2"); System.out.println(sortedList); EventListJXTableSorting.install(table, sortedList); System.out.println("3"); System.out.println(sortedList); JButton showSortedListButton = new JButton("Show sorted list"); showSortedListButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.out.println(sortedList); } }); JScrollPane scrollPane = new JScrollPane(table); scrollPane.setPreferredSize(new Dimension(500, 400)); add(scrollPane, BorderLayout.CENTER); add(showSortedListButton, BorderLayout.SOUTH); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); pack(); setVisible(true); } private class ListObject { private final String name; private final int number; private final double fraction; private ListObject(String name, int number, double fraction) { this.name = name; this.number = number; this.fraction = fraction; } @Override public String toString() { return "\nListObject{name='" + name + "\', number=" + number + ", fraction=" + fraction + '}'; } } private class ListObjectTableFormat implements TableFormat<ListObject> { private final String[] columns = new String[]{"Name", "number", "fraction"}; @Override public int getColumnCount() { return columns.length; } @Override public String getColumnName(int column) { return columns[column]; } @Override public Object getColumnValue(ListObject baseObject, int column) { switch (column) { case 0: return baseObject.name; case 1: return baseObject.number; case 2: return baseObject.fraction; default: return "UNKNOWN"; } } } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new JXTableSorting(); } }); } }
|
|
|
Re: EventListJXTableSortingJust a bit more info. It appears the call to EventListJXTableSorting.install(table, sortedList); is setting my comparator to null, which I suppose is what we expect if the list becomes unsorted.
Thanks, Nick.
|
|
|
Re: EventListJXTableSortingBoomah,
I'll try to get a bit of time to dig into your test app (thanks very much for producing that). I don't have a lot of experience with JXTable, but we'll get to the bottom of it... James On Mon, May 11, 2009 at 9:25 AM, Boomah <nickdarcy@...> wrote:
|
|
|
|
| Free embeddable forum powered by Nabble | Forum Help |