配置JTable,以便仅在MouseEvent没有修饰符的情况下才触发排序

时间:2019-01-09 08:59:57

标签: java swing

JTable.setAutoCreateRowSorter创建的TableRowSorter可以很好地*工作,除了以下几点:即使MouseEvent上有修饰符,它也会触发某种排序。只有在添加Rob的TableColumnManager之后,我才发现了这一点。当您在JTableHeader上单击(在macOS上为control + button1)时,您将看到在弹出列选择器弹出窗口之前进行排序。如果有任何修饰符,我根本不想触发排序。

是否只有MouseAdapter没有修饰符(特别是meta修饰符)时,才能使MouseEvent被触发?我不想将列选择器放在应用程序中不会很明显的其他地方。

下面是我的MCV示例(很抱歉没有发布Rob的课程,请参见上面的链接)。您无需参考TableColumnManager,就可以测试鼠标修饰符的行为(即证明行修饰符会忽略修饰符)。

import javax.swing.*;
public class SorterChooser {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("SorterChooser");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Object[][] data = { {"a", "1"}, {"b", "3"}, {"c", "2"}, {"d", "4"} };
        String[] colnames = { "c1", "c2" };
        JTable tab = new JTable(data, colnames);
        JScrollPane sp = new JScrollPane(tab);
        tab.setAutoCreateRowSorter(true);
        new TableColumnManager(tab, true); // comment this out to demo mouse behavior
        frame.getContentPane().add(sp);
        frame.pack();
        frame.setVisible(true);
    }
    public static void main (String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}
  • 好的,我的意思是它可以处理模型更改以及我需要的其他许多事情(例如,某些列不允许排序)。

1 个答案:

答案 0 :(得分:0)

我所做的是扩展BaseTableHeaderUI。我发现扩展它是我需要做的是困难的部分:

  1. RowSorterListener上添加了JTable.getRowSorter
  2. 在调用sorterChanged时打印调用堆栈
  3. 调用堆栈归咎于javax.swing.plaf.basic.BasicTableHeaderUI的排序事件
  4. 找到了BasicTableHeaderUI的源代码
  5. 仅由BasicTableHeaderUI.MouseInputHandler进行的排序
  6. BasicTableHeaderUI.MouseInputHandler扩展为仅在没有修饰符的情况下才调用其超级
  7. 将表格的JTableHeaderUI设置为新类

这是经过修改的SorterChooser.java

import javax.swing.*;
public class SorterChooser {
    private static void createAndShowGUI() {
        JFrame frame = new JFrame("SorterChooser");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Object[][] data = { {"a", "1"}, {"b", "3"}, {"c", "2"}, {"d", "4"} };
        String[] colnames = { "c1", "c2" };
        JTable tab = new JTable(data, colnames);
        tab.getTableHeader().setUI(new SorterChooserTableHeaderUI());  // new code
        JScrollPane sp = new JScrollPane(tab);

        tab.setAutoCreateRowSorter(true);
        new TableColumnManager(tab, true);

        frame.getContentPane().add(sp);
        frame.pack();
        frame.setVisible(true);
    }
    public static void main (String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }
        });
    }
}

这是扩展的BasicTableHeaderUI.java

import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.table.*;
import javax.swing.plaf.basic.BasicTableHeaderUI;

public class SorterChooserTableHeaderUI extends BasicTableHeaderUI {

    public class MouseInputHandler extends BasicTableHeaderUI.MouseInputHandler {
        public void mouseClicked (MouseEvent ev) {
            if (ev.getModifiersEx() == 0)
                super.mouseClicked(ev);
        }
    }

    @Override
    protected MouseInputListener createMouseInputListener () {
        return new MouseInputHandler();
    }

}