【问题标题】:Prevent JTable from Auto-Sorting on Double Click防止 JTable 在双击时自动排序
【发布时间】:2013-02-12 04:51:40
【问题描述】:

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

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

我的第一个方法是使用Java接口Proxy来替换JTable现有的所有MouseListener,拦截事件,只传递与单击相关的事件。不过,这似乎有点矫枉过正。有没有更好的办法?

【问题讨论】:

    标签: java swing jtable


    【解决方案1】:

    我的第一个方法是使用Java接口Proxy的来替换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);
        }
    }
    

    此代码也使用Table Column Adjuster

    【讨论】:

    • +1 MouseEvent.dispatchEvent(),可能直接使用consume()
    猜你喜欢
    • 2010-12-23
    • 2013-12-28
    • 1970-01-01
    • 2019-02-05
    • 2011-09-11
    • 1970-01-01
    • 2011-02-10
    • 1970-01-01
    • 2015-02-09
    相关资源
    最近更新 更多