如何在 1.6 中禁用 JTable 中的所有排序代码

发布于 2024-09-11 00:39:40 字数 339 浏览 5 评论 0原文

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

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

那么有没有办法让 JTable 1.6 停止呢?我没能做到。即使覆盖表格和表格标题上的用户界面也没有帮助。

I have a JTable extension that has been in use since Java 1.3/1.4 in the project that provided things like column reordering and sorting by clicking on the column. We are upgrading to Java 1.6, and the new JTable stops the old sorting code from working. It would be somewhat extensive rework to fit everything to the new JTable API. Until then is there a way to completely disable those additions in JTable?

Edit: After the further investigation, the problem is centered around the fact that the mouse events on the header are swallowed by Swing in 1.6, and not passed on to the table implementation, even though it sets its own header rendered. So much for vaunted Java backwards compatibility.

So is there a way to get JTable 1.6 to stop? I haven't been able to. Even overriding the UI on the table and the table header didn't help.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

心凉 2024-09-18 00:39:40

您是否尝试过 JTable.setRowSorter(null)

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

Have you tried JTable.setRowSorter(null) ?

edit : and setAutoCreateRowSorter ? (1. create table, 2. row sorter to null, 3. autocreate sorter to false, 4. set model).

装纯掩盖桑 2024-09-18 00:39:40

我在 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

I use this in my JTable subclass and it catches mouse events just fine:

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

The SortColumnListener is implemented like so:

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
        }
    }
}

This catches mouse events in the SortColumnListener just fine and I can do whatever I want with those events. I have no RowSorter implementation set on the JTable and this works perfectly in Java 5 and Java 6.

For full sourcecode of this class, see: QueueTable.java

猫卆 2024-09-18 00:39:40

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

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

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

As I understand it you have two problems here:

  1. Because of the new sorting code in JTable, your sorting does not work.
  2. Even if you disable sorting by setRowSorter(null) or by overriding the setRowSorter(TableRowsorter) to do nothing, it does not work because the events on header are not passed to your JTable.

In that case I think the option for you is to just have your sorting code implemented as TableRowSorter. I am not aware how complex your sorting code is and whether it can map the TableRowSorter API, but this seems to be one more alternative you can try.

£冰雨忧蓝° 2024-09-18 00:39:40
JTable.setAutoCreateRowSorter(false);

除非在某个地方设置了 TableRowSorter,否则我认为您不必调用 setRowSorter(null)

JTable.setAutoCreateRowSorter(false);

Unless the TableRowSorter is set somewhere, I don't think that you have to call setRowSorter(null)

花间憩 2024-09-18 00:39:40

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

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

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

A way to disable sorting when clicking on the header, is to remove all the table header's listeners:

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

Then in case you want some other specific action (like column resizing) you could just add a specific listener for that particular action.

月亮坠入山谷 2024-09-18 00:39:40

我在 Sun 表排序示例 他们都在工作。

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

I tested all possibilities mentioned here on Sun table sort example and they all are working.

Unfortunately there are still many bugs in table sorting. There can not be much done until you post your code here. One possibility is to try out SwingX solution.

失去的东西太少 2024-09-18 00:39:40

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

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

希望这有帮助

I solved your problem in your edit:

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

}

This works perfect in Linux, so I suppose also on OSX and Windows. I also tested it after resizing the columns: it still know which columns was pressed. But after reordering the columns, the column which was first "column 0" became "column 1".
But you can always disallow the user to move the columns with this:

table.getTableHeader().setReorderingAllowed(false);

Hope this helps

神经大条 2024-09-18 00:39:40

试试这个:

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;
    }
    ..
}

Try this:

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;
    }
    ..
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文