当前位置: 首页 > 面试题库 >

释放鼠标时对JTable进行排序

王棋
2023-03-14
问题内容

我有一个JTable,其属性AutoCreateRowSorter设置为true。单击时效果很好,但如果单击时仅将鼠标移动1px,则不会出现排序,这在某些情况下不舒服。如何解决这个问题?

UPD我只想在释放鼠标时显示排序。


问题答案:

肮脏的方法(请阅读: 如果您不是绝对地绝望,请确切地知道自己在做什么!请不要这样做
),方法是挂接到uiDelegate安装的MouseListener并将排序触发器移到已发布的方法中。这涉及

  • 一个自定义的MouseListener,它将除clicked之外的所有事件委托给原始安装的对象,并在传递发布的对象之前进行排序
  • 用自定义替换原件
  • 更改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);


 类似资料:
  • 所以我有下面的jQuery: 当我将项目拖到这个排序表中的“坏”地方(在那里它们不能被排序,例如在可排序区域之外)时,克隆会恢复到它在可排序表中的最后一个好位置。当这个动画完成时,停止函数会关闭“停止”。 是否有一个我可以使用的事件,它会在鼠标按钮释放后立即触发?(或在此还原动画开始之前?)

  • 我花了几天的时间来尝试正确地进行JTable排序。我知道我必须使用的代码,但似乎不能得到它‘适合’和工作到我的代码。我从数据库获取TableModel数据,因此如果在初始化模型时调用getColumnClass(),我会得到一个NullPointerException(当然),但似乎无法让getColumnClass(int)在其他任何地方(如model.getColumnClass(column

  • 当添加到JTable(包含表单元格中不同的JCombo Box)中的排序器/autoRowSorter用列标题排序时,Jcomo Box不会用相应的行排序。 单击JCombo框可以更改它在显示组合框的模型值而不是视图值(与行相关的值)中结束的数据。 在互联网上找到的例子,用同样的方法来说明问题。我刚刚添加了setAutoCreateRowSorter(真) 代码参考: 如何在Swing中的JTab

  • 问题内容: 有没有办法以编程方式对JTable进行排序? 我的JTable排序工作正常(使用setRowSorter),以便当用户按任意列时,表将被排序。 我知道,SWingX JXTable可能可以工作,但我不想麻烦,因为其他所有事情现在都可以正常工作,而且我不知道NetBeans的可视化编辑器如何处理JXTable等。 编辑: 选定的答案是指我的声明(现已删除),该声明对Sun的页面的答案不起

  • 我的目标是通过拖放对tableview进行排序。我举了一个例子:http://docs.oracle.com/javafx/2/fxml_get_started/fxml_tutorial_intermediate.htm 对于拖放,我通过Scene Builder添加了fxml 制造了控制器 但是在drag Drop,我无法得到我扔下物体的那排位置。我得到的只是手机信息<代码>文本[Text=“

  • 我有以下课程: 在活动中,我观察会话并对每个更改执行网络操作: 现在我有一个Okhttp请求拦截器,当网络响应不是200代码时,我将会话实例从有效设置为无效。 事情是这样的: < li >在初始订阅会话存储时,执行< code>getThingForValid()并失败。 < li>OkHttp截获失败并设置新的会话。 < li >会话存储发出一个新的现在无效的会话。 < li >新发射执行< c