6

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

编辑:经过进一步调查,问题集中在标题上的鼠标事件在 1.6 中被 Swing 吞噬,并且没有传递给表实现,即使它设置了自己的标题。对于自吹自擂的 Java 向后兼容性来说就这么多。

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

4

8 回答 8

4

你试过JTable.setRowSorter(null)吗?

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

于 2010-07-22T20:58:38.587 回答
3

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

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

于 2010-07-25T21:27:03.140 回答
2

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

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

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

于 2010-08-01T05:12:13.833 回答
1

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

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

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

于 2010-09-07T12:23:30.480 回答
1
JTable.setAutoCreateRowSorter(false);

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

于 2010-07-23T21:28:08.367 回答
0

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

不幸的是,表格排序中仍然存在许多错误。在您将代码发布到此处之前,您无能为力。一种可能性是尝试SwingX 解决方案

于 2010-08-01T07:02:34.493 回答
0

尝试这个:

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;
    }
    ..
}
于 2011-06-30T10:34:06.163 回答
0

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

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);

希望这可以帮助

于 2010-08-01T10:27:33.267 回答