【问题标题】:Sort JTable when mouse released释放鼠标时对 JTable 进行排序
【发布时间】:2013-01-21 11:21:29
【问题描述】:

我有一个 JTable,其属性 AutoCreateRowSorter 设置为 true。单击时它可以正常工作,但是如果我在单击期间仅移动鼠标 1px,则不会出现排序,这在某些情况下会让人不舒服。如何解决这个问题?

UPD 我只想在鼠标松开时显示排序。

【问题讨论】:

  • 你的意思是拖动鼠标开始拖动列?
  • 组件认为你要拖列;它只是还没有开始为拖动设置动画。延迟因平台而异。你可以看看如何disable dragging
  • @trashgod 我写过这个:devicesTable.getTableHeader().setReorderingAllowed(false) 和 devicesTable.getTableHeader().setResizingAllowed(false)
  • 默认情况下,在 mouseClicked 上触发排序(很可能也取决于平台/LAF)。除了极端的黑客攻击之外别无他法。

标签: java swing events sorting jtable


【解决方案1】:

一个肮脏的(阅读:如果你不是绝对绝望并且确切地知道你在做什么,不要这样做!)方法是挂钩到由 uiDelegate 安装的 MouseListener 并将排序触发器移动到发布的方法。这涉及到

  • 一个自定义的 MouseListener,它将除单击之外的所有事件委托给最初安装的事件,并在传递释放之前进行排序
  • 用自定义替换原来的
  • 每当 LAF 更改时更新替换(因为原始由 ui 控制)。这需要 JTableHeader 的子类化并在 updateUI 中进行布线

自定义监听器:

public static class EventHook implements MouseListener {

    private JTableHeader header;
    private MouseListener delegate;

    public EventHook(JTableHeader header) {
        this.header = header;
        installHook();
    }

    protected void installHook() {
        MouseListener[] listeners = header.getMouseListeners();
        for (int i = 0; i < listeners.length; i++) {
            MouseListener l = listeners[i];
            if (l.getClass().getName().contains("TableHeaderUI")) {
                this.delegate = l;
                listeners[i] = this;
            }
            header.removeMouseListener(l);
        }
        for (MouseListener l : listeners) {
            header.addMouseListener(l);
        }
    }

    public void uninstallHook() {
        MouseListener[] listeners = header.getMouseListeners();
        for (int i = 0; i < listeners.length; i++) {
            MouseListener l = listeners[i];
            if (l == this) {
                listeners[i] = delegate;
            }
            header.removeMouseListener(l);
        }
        for (MouseListener l : listeners) {
            header.addMouseListener(l);
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // sort before calling super
        sort(e);
        delegate.mouseReleased(e);
    }

    private void sort(MouseEvent e) {
        if (!header.isEnabled()) {
            return;
        }
        // do nothing if dragged
        if (header.getDraggedDistance() != 0) {
            return;
        }
        if (e.getClickCount() % 2 == 1 &&
                SwingUtilities.isLeftMouseButton(e)) {
            JTable table = header.getTable();
            RowSorter sorter;
            if (table != null && (sorter = table.getRowSorter()) != null) {
                int columnIndex = header.columnAtPoint(e.getPoint());
                if (columnIndex != -1) {
                    columnIndex = table.convertColumnIndexToModel(
                            columnIndex);
                    sorter.toggleSortOrder(columnIndex);
                }
            }
        }
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        // swallow the clicked - want to trigger sort on released
    }

    @Override
    public void mousePressed(MouseEvent e) {
        delegate.mousePressed(e);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        delegate.mouseEntered(e);
    }

    @Override
    public void mouseExited(MouseEvent e) {
        delegate.mouseExited(e);
    }

}

子类化的 JTableHeader

public static class MyTableHeader extends JTableHeader {
    private EventHook hook;
    public MyTableHeader(TableColumnModel model) {
        super(model);
    }
    @Override
    public void updateUI() {
        if (hook != null) {
            hook.uninstallHook();
            hook = null;
        }
        super.updateUI();
        hook = new EventHook(this);
    }

}

使用方法,要么继承 JTable 并覆盖 createDefaultTableHeader 要么手动设置表头:

// either subclass
JTable table = new JTable(new AncientSwingTeam()) {

    @Override
    protected JTableHeader createDefaultTableHeader() {
        return new MyTableHeader(getColumnModel());
    }

};
table.setAutoCreateRowSorter(true);

【讨论】:

  • 谢谢您的回答,我会考虑的。我不确定我的问题是否重要到足以做出如此大的改变。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-23
  • 1970-01-01
  • 2011-05-10
  • 2011-10-08
  • 1970-01-01
相关资源
最近更新 更多