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

防止JTable在双击时自动排序

酆晔
2023-03-14
问题内容

我有一个使用自定义RowSorter可排序列的JTable。我假设RowSorter类自动将自身作为MouseListener添加到表的ColumnHeader中,因为它无需执行任何自定义鼠标侦听代码即可自动执行排序。这很完美。

我还添加了一些代码(基于此示例),该代码允许用户通过双击列标题中的表之间的空间来调整表列的大小(模仿Excel的行为)。问题是,当用户双击标题以调整列的大小时,它也会对该列进行排序。
如果标题是单击的,我只希望对列进行排序。

我的第一种方法是使用Java接口代理替换JTable的所有现有MouseListener,拦截事件,并仅传递与单击相关的事件。不过,这似乎有些过分。有没有更好的办法?


问题答案:

我的第一种方法是使用Java接口代理替换JTable的所有现有MouseListener,拦截事件,并仅传递与单击相关的事件。

基本上就是这样工作的:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.table.*;

public class ResizeColumnListener implements MouseListener
{
    private static Cursor resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);

    private MouseListener uiListener;
    private JTableHeader header;
    private TableColumnAdjuster tca;

    public ResizeColumnListener(JTable table)
    {
        header = table.getTableHeader();
        tca = new TableColumnAdjuster( table );

        MouseListener[] listeners = header.getMouseListeners();

        for (MouseListener ml: listeners)
        {
            String className = ml.getClass().toString();

            if (className.contains("BasicTableHeaderUI"))
            {
                uiListener = ml;
                header.removeMouseListener(ml);
                header.addMouseListener( this );
            }
        }
    }

    @Override
    public void mouseClicked( MouseEvent e )
    {
        if (header.getCursor() != resizeCursor)
        {
            uiListener.mouseClicked( e );
            return;
        }

        //  Handle the double click event to resize the column
        //  Note: The last 3 pixels + 3 pixels of next column are for resizing,
        //  so we need to adjust the mouse point to get the actual column.

        if (e.getClickCount() == 2)
        {
            Point p = e.getPoint();
            p.x -= 3;
            int column = header.columnAtPoint( p );
            tca.adjustColumn( column );

            //  Generate event to reset the cursor

            header.dispatchEvent(new MouseEvent(
                header,
                MouseEvent.MOUSE_MOVED,
                e.getWhen(),
                e.getModifiers(),
                e.getX(),
                e.getY(),
                0,
                false));
        }
    }

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

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

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

    @Override
    public void mouseReleased( MouseEvent e )
    {
        uiListener.mouseReleased( e );
    }

    public static void main(String[] args)
    {
        try
        {
//          UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }
        catch (Exception e) { }

        DefaultTableModel model = new DefaultTableModel(5, 5);
        model.setValueAt("Row 0 : Column 0", 0, 0);
        model.setValueAt("Row 1 : Column 1", 1, 1);
        model.setValueAt("Row 2 : Column 2", 2, 2);
        model.setValueAt("Row 3 : Column 3", 3, 3);
        model.setValueAt("Row 4 : Column 4", 4, 4);

        JTable table = new JTable( model );
        table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
        table.setAutoCreateRowSorter(true);
        JScrollPane scrollPane = new JScrollPane( table );

        new ResizeColumnListener(table);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.add( scrollPane );
        frame.setSize(400, 200);
        frame.setVisible(true);
    }
}

此代码还使用“ 表列调整器”。



 类似资料:
  • 我在JTable上遇到了问题。当我以固定长度的文本字段作为编辑器在单元格中键入时,当达到长度时,我会自动跳到下一行。那样的话,我就可以继续写下去了。之后,当我想更改第一行中的一些文本并双击单元格时,文本将消失。 奇怪的是,当我按“Enter”转到下一行,双击第一行时,文本并没有消失。

  • 问题内容: 在angular中,我们可以设置一个按钮来发送ajax请求,如下所示: 并在控制器中: 因此,为防止重复提交,我可以在单击按钮时将标志设置为buttonclicked = true,而在ajax回调完成时将其取消设置。但是,即使这样,控制权仍会归还给有角力的人,他们将更新Dom。这意味着有一个很小的窗口,在原始按钮单击完全100%完成之前,可以再次单击该按钮。 这是一个小窗口,但仍然可

  • 问题内容: 如果转到页面a并滚动浏览,则刷新页面将在您离开页面的位置刷新。这很好,但是在URL中存在锚点位置的页面上也会发生这种情况。例如,如果您单击一个链接并在环顾四周后刷新页面,您将不会处于锚点,而页面会跳来跳去。有什么办法可以防止使用javascript吗?因此,无论如何,您始终可以导航到锚点。 问题答案: 由于浏览器行为的更改,不再建议使用此解决方案。查看其他答案。 基本上,如果使用锚,则

  • 我希望能够覆盖 doubleTap 运动事件,使其不执行任何操作,而不是缩放和取消缩放。我在另一篇文章中读到,有人能够通过创建自定义WebView类并覆盖其中的内容来使其工作,但是无论如何,我似乎都无法在DoubleTap上启动,并且无论如何双击缩放仍在发生。 到目前为止,我的进展是我可以正确触发onDown事件(我在调试输出窗口中看到了msg)。 这是我的代码,在我帖子的最底部有一个链接,指向我

  • 日安! 我有一个jTable,我正在用JButton监听器填充它。在通过鼠标双击填充jTable之后,我调用JoptionPane.ShowMessageDialog。在那个问题解决之后。再次单击JButton后,jTable将再次填充。如果我再次双击Row\Cell,它将显示JOptionPane的2条消息,而不是一条。据我所知,我需要刷新模型,但我没有成功。 我的代码: form.java 我

  • 我有一个包装了一个块,当点击它时,会打开一个新的场景(我使用的是react native router flux)。 除了快速点击之外,一切正常,场景可以渲染两次。 我想防止用户快速点击该按钮。 在本机中实现这一点的最佳方法是什么?我研究了手势应答器系统,但没有任何例子或类似的东西,如果你是新来的,像我一样,会让人困惑。