防止JTable在双击时自动排序 [英] Prevent JTable from Auto-Sorting on Double Click

查看:82
本文介绍了防止JTable在双击时自动排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a JTable that has sortable columns using a custom RowSorter. I assume the RowSorter class automatically adds itself as a MouseListener to the table's ColumnHeader, because it automatically performs the sort without my having added any custom mouse listening code. This works perfectly.

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

I also added some code (based off of this example) that allows the user to resize the table columns by double-clicking on the space between them in the column header (mimicking that behavior of Excel). The issue is that when a user double-clicks the header to resize a column, it also sorts that column. I want to only have the columns sort if the header is single-clicked.

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

My first approach was to use Java interface Proxy's to replace all of the existing MouseListeners of the JTable, intercept the events, and only pass on events related to single clicks. This seems like overkill, though. Is there a better way?

推荐答案

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

My first approach was to use Java interface Proxy's to replace all of the existing MouseListeners of the JTable, intercept the events, and only pass on events related to single clicks.

这基本上是这样工作的:

That is basically how this works:

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在双击时自动排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆