【问题标题】:Out-of-table column sorting with Glazed Lists and a JXTable使用 Glazed Lists 和 JXTable 进行表外列排序
【发布时间】:2011-05-12 09:31:19
【问题描述】:

我正在使用 Glazed Lists 对 JXTable 进行排序和过滤。

如何对表外值进行排序?也就是说,我希望能够以我自己的方式格式化列值,但对原始值进行排序。

我目前的相关代码:

EventList<Foo> foos = GlazedLists.threadSafeList(new BasicEventList<Foo>());
foos.add(new Foo("bar", 5000000));

ObservableElementList.Connector<Foo> fooConnector = GlazedLists.beanConnector(Foo.class);
EventList<Foo> observedFoos = new ObservableElementList<Foo>(foos, fooConnector);

SortedList<Foo> sortedFoos = new SortedList<Foo>(observedFoos, null);

EventTableModel tableModel = new EventTableModel(sortedFoos, someTableFormat);
JXTable t = new JXTable(tableModel);

new TableComparatorChooser<Foo>(t, sortedFoos, false);

在本例中,我想将第二列中的值格式化为5.0M 而不是5000000,但如果我在列表中使用此值,它将无法正确排序。

提前致谢。

【问题讨论】:

    标签: java sorting jtable glazedlists jxtable


    【解决方案1】:

    也许你必须禁用 JXTable 排序,所以它不会干扰 GL 排序?比如:

    jxtable.setSortable(false);
    jxtable.setAutoCreateRowSorter(false);
    jxtable.setRowSorter(null);
    

    ...然后在桌子上安装 GlazedLists TableComparatorChooser,如:

    TableComparatorChooser.install(jxtable, sortedFoos, TableComparatorChooser.SINGLE_COLUMN);
    

    或者你的意思是,你想在表格中而不是在列表中将 5000000 格式化为 5.0M?那么你只需要实现你的 TableFormat 的

    public Object getColumnValue(E yourObject, int column)
    

    返回 5000000 的 5.0M 表示。

    ...很可能,我没有完全理解这个问题,这些答案没有帮助;-)

    编辑:可运行示例...

    查看 main 方法中的代码——尤其是带有 START-END 注释的代码。 我自己做了一个非常简单的例子,但你应该明白我的意思。

    哦...抱歉类/变量的命名/... ;-)

    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.EventTableModel;
    import ca.odell.glazedlists.swing.TableComparatorChooser;
    import java.util.Comparator;
    import java.util.List;
    import javax.swing.ComboBoxEditor;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import org.jdesktop.swingx.JXTable;
    
    public class Tester {
    
        private static class MyObject implements Comparable<MyObject> {
    
            private final int number;
            private final String value;
    
            public MyObject(int number, String value) {
                this.number = number;
                this.value = value;
            }
    
            public int getNumber() {
                return number;
            }
    
            public String getValue() {
                return value;
            }
    
            @Override
            public int compareTo(MyObject t) {
                return value.compareTo(t.getValue());
            }
        }
    
        private static class MyTableFormat implements TableFormat<MyObject> {
    
            @Override
            public int getColumnCount() {
                return 2;
            }
    
            @Override
            public String getColumnName(int i) {
                switch (i) {
                    case 0:
                        return "FormattedNumber";
                    case 1:
                        return "String";
                    default:
                        throw new IllegalStateException();
                }
            }
    
            @Override
            public Object getColumnValue(MyObject e, int i) {
                switch (i) {
                    case 0:
                        return getNumberString(e.getNumber());
                    case 1:
                        return e.getValue();
                    default:
                        throw new IllegalStateException();
                }
            }
    
            private Object getNumberString(int number) {
                switch (number) {
                    case 1:
                        return "One";
                    case 2:
                        return "Two";
                    case 3:
                        return "Three";
                    default:
                        throw new IllegalStateException();
                }
            }
        }
    
        private static class MyComparator implements Comparator<MyObject> {
    
            @Override
            public int compare(MyObject t, MyObject t1) {
                return Integer.valueOf(t.getNumber()).compareTo(Integer.valueOf(t1.getNumber()));
            }
    
        }
    
        /**
         * @param args the command line arguments
         */
        public static void main(String[] args) {
            EventList<MyObject> list = new BasicEventList<MyObject>();
            list.add(new MyObject(1, "A"));
            list.add(new MyObject(2, "B"));
            list.add(new MyObject(3, "C"));
    
            SortedList<MyObject> sortedList = new SortedList<MyObject>(list);
    
            EventTableModel<MyObject> tableModel = new EventTableModel<MyObject>(sortedList, new MyTableFormat());
            JXTable jxtable = new JXTable(tableModel);
    
            /** 
             * START
             * - Deactivate JXTables build-in sorting
             * - Install GlazedLists sorting
             * - Set the comparator for the "string number" column
             */
    
            // deactivate sorting of JXTable
            jxtable.setSortable(false);
            jxtable.setAutoCreateRowSorter(false);
            jxtable.setRowSorter(null);
    
            // enable GlazedLists sorting
            TableComparatorChooser<MyObject> tcc = TableComparatorChooser.install(jxtable, sortedList, TableComparatorChooser.SINGLE_COLUMN);
    
            // set the comparator for your "string number" column
            List<Comparator> comparators = tcc.getComparatorsForColumn(0);
            comparators.clear();
            comparators.add(new MyComparator());
    
            /**
             * END
             */
    
            JFrame f = new JFrame("Tester");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.getContentPane().add(new JScrollPane(jxtable));
            f.pack();
            f.setVisible(true);
        }
    }
    

    【讨论】:

    • 感谢凯的回复。这是我想要实现的第二个选项。我已经尝试getColumnValue(Object baseObject, int column) 将值格式化为 5.0M,但它不会正确排序,因为我将 5.0M 格式化为字符串。所以它似乎是根据getColumnValue(Object baseObject, int column)而不是初始列表进行排序的。
    • 您是否尝试过切换JXTable的排序机制,然后安装Glazed列表的排序机制(TableComparatorChooser)?可能是,在单击表头时,您开始 JXTable 排序而不是 GlazedLists 排序...
    • 非常感谢凯提供这个非常完整的答案。问题是我在添加比较器之前没有调用comparators.clear()。从我最初的问题中无法确定这一点,做得很好:-) 希望其他人将来能找到你的答案。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-18
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    相关资源
    最近更新 更多