【问题标题】:How can you disable all sorting code in JTable in 1.6如何在 1.6 中禁用 JTable 中的所有排序代码
【发布时间】:2010-07-22 20:07:29
【问题描述】:

我有一个自 Java 1.3/1.4 以来一直在项目中使用的 JTable 扩展,它通过单击列来提供列重新排序和排序等功能。我们正在升级到 Java 1.6,新的 JTable 使旧的排序代码停止工作。将所有内容都适应新的 JTable API 将需要大量的返工。在那之前有没有办法完全禁用 JTable 中的这些添加?

编辑:经过进一步调查,问题集中在标题上的鼠标事件在 1.6 中被 Swing 吞噬,并且没有传递给表实现,即使它设置了自己的标题渲染。吹嘘的 Java 向后兼容性就到此为止了。

那么有没有办法让 JTable 1.6 停止?我一直没办法。即使覆盖表格和表格标题上的 UI 也无济于事。

【问题讨论】:

  • 我在 Sun 示例上对此进行了测试,并且 table.setRowSorter(null) 正在工作。你能输入你的代码示例,以便每个人都可以测试它吗?

标签: java swing jtable jdk1.6 java-6


【解决方案1】:

你试过JTable.setRowSorter(null)吗?

编辑:setAutoCreateRowSorter? (1. 创建表,2. 行排序器为空,3. 自动创建排序器为 false,4. 设置模型)。

【讨论】:

  • 是的,不幸的是它没有帮助:(
  • 不幸的是,这也没有帮助。我什至不得不破解那个组件,因为它总是调用传递模型的 super,所以它稍后会调用 set model。还是没有骰子:(
【解决方案2】:

我在我的 JTable 子类中使用它,它可以很好地捕捉鼠标事件:

class QueueTable extends JTable {
    public QueueTable() {
        ...
        getTableHeader().addMouseListener(new SortColumnListener(1));
    }
}

SortColumnListener 是这样实现的:

class SortColumnListener extends MouseAdapter {
    SortColumnListener(int column) { ... }

    public void mouseClicked(MouseEvent e) {
        TableColumnModel colModel = QueueTable.this.getColumnModel();
        int columnModelIndex = colModel.getColumnIndexAtX(e.getX());

        if(columnModelIndex == column) {
            // Do stuff
        }
    }
}

这可以很好地捕获SortColumnListener 中的鼠标事件,我可以对这些事件做任何我想做的事情。我在 JTable 上没有设置 RowSorter 实现,这在 Java 5 和 Java 6 中完美运行。

该类的完整源代码见:QueueTable.java

【讨论】:

  • 是的,我也观察到了——您可以添加自己的监听器。但在 Java 1.5 中,我认为关键在于标题或表格上的鼠标事件在标题上没有特殊侦听器的情况下同样传播。至少我是这么认为的。
  • 他们很可能已经做到了,但我认为这是一个实现细节,而不是 API 的承诺。向 TableHeader 添加 MouseListener 一直是执行此操作的“方法”。
  • 不幸的是,即使显式添加了一个侦听器并通过该组件泵送鼠标(我对其进行了调试 - 它认为这是一个常规鼠标事件)仍然没有得到表对其进行排序。叹息。
  • 顺便说一句,谢谢你的代码。关于您的 SortColumnListner,您不应该使用 JTable.columnAtPoint 吗?除非您假设表格上的列永远不会重新排列。
  • 这些列确实从未在此特定表上重新排列。布局是固定的。
【解决方案3】:

据我了解,这里有两个问题:

  1. 由于 JTable 中的新排序代码,您的排序不起作用。
  2. 即使您禁用按setRowSorter(null) 排序或通过覆盖setRowSorter(TableRowsorter) 不执行任何操作,它也不起作用,因为标题上的事件不会传递给您的JTable。

在这种情况下,我认为您的选择是将您的排序代码实现为 TableRowSorter。我不知道您的排序代码有多复杂以及它是否可以映射 TableRowSorter API,但这似乎是您可以尝试的另一种选择。

【讨论】:

    【解决方案4】:
    JTable.setAutoCreateRowSorter(false);
    

    除非 TableRowSorter 设置在某处,否则我认为您不必致电 setRowSorter(null)

    【讨论】:

      【解决方案5】:

      单击表头时禁用排序的一种方法是删除所有表头的侦听器:

              for(MouseListener listener : table.getTableHeader().getMouseListeners()){
              table.getTableHeader().removeMouseListener(listener);
          }
      

      然后,如果您想要一些其他特定操作(如调整列大小),您可以为该特定操作添加特定侦听器。

      【讨论】:

        【解决方案6】:

        我在Sun table sort example 上测试了这里提到的所有可能性,它们都在工作。

        不幸的是,还有many bugs in table sorting。除非您在此处发布代码,否则无法完成太多工作。一种可能是尝试SwingX solution

        【讨论】:

        • 谢谢,不幸的是,损坏的组件是专有的,虽然我们购买了源代码,但我不能在这里发布。
        【解决方案7】:

        我在您的编辑中解决了您的问题:

        package jtableheadermouseevent;
        
        import java.awt.event.MouseAdapter;
        import java.awt.event.MouseEvent;
        import javax.swing.JFrame;
        import javax.swing.JScrollPane;
        import javax.swing.JTable;
        import javax.swing.table.DefaultTableModel;
        
        /**
         *
         * @author martijn
         */
        public class Main {
        
            /**
             * @param args the command line arguments
             */
            public static void main(String[] args) {
                JFrame fr = new JFrame("JTable Header Mouse Listener");
                fr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                final JTable table = new JTable();
                JScrollPane pane = new JScrollPane(table);
        
                String[][] data = {{"Foo", "Bar"}, {"Baz", "Coffee"}};
                String[] columns = {"Header 0", "Header 1"};
        
                DefaultTableModel model = new DefaultTableModel(data, columns);
                table.setModel(model);
                fr.add(pane);
                table.getTableHeader().addMouseListener(new MouseAdapter() {
        
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        super.mouseClicked(e);
                        System.out.println("Header clicked : (X: " + e.getX() + ", Y: " + e.getY() + ") With button " + e.getButton() );
                        int header = table.getTableHeader().columnAtPoint(e.getPoint());
                        System.out.println("This means header " + header + " is clicked!");
                    }
        
                });
                fr.pack();
                fr.setSize(800, 300);
                fr.setVisible(true);
            }
        
        }
        

        这在 Linux 中完美运行,所以我想在 OSX 和 Windows 上也是如此。我也在调整列大小后对其进行了测试:它仍然知道按下了哪些列。但是在对列重新排序后,第一个“第 0 列”的列变成了“第 1 列”。
        但是你总是可以禁止用户移动列:

        table.getTableHeader().setReorderingAllowed(false);
        

        希望对你有帮助

        【讨论】:

        • 是的,这允许我添加一个额外的监听器。不幸的是,它并没有解决这个问题。
        【解决方案8】:

        试试这个:

        public abstract class BaseTable extends JTable {
            public BaseTable() {
                init();
                ..
            }
        
            protected boolean sortableDisable() {
                return false;
            }
        
            private void init() {
                TableRowSorter<BaseTableModel> sorter =
                    new TableRowSorter<BaseTableModel>(tableModel);
                if (sortableDisable()) {
                    setAutoCreateRowSorter(false);
                    for (int c = 0; c < tableModel.getColumnCount(); c++) {
                        sorter.setSortable(c, false);
                    }
                }
                setRowSorter(sorter);
                ..
            }
        }
        
        public class TableX extends BaseTable() {
        
            @Override
            protected boolean sortableDisabled() {
                return true;
            }
            ..
        }
        

        【讨论】:

          猜你喜欢
          • 2014-09-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-01-02
          • 2021-03-04
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多