2013-02-26 57 views
1

我有一個JTable,它具有使用自定義RowSorter的可排序列。我假設RowSorter類自動將它自己作爲MouseListener添加到表的ColumnHeader中,因爲它會自動執行排序,而無需添加任何自定義鼠標偵聽代碼。這工作完美。防止JTable在雙擊時自動排序

我還添加了一些代碼(基於this example),允許用戶通過在列標題中雙擊它們之間的空格(模擬Excel的行爲)來調整表列的大小。問題是當用戶雙擊標題來調整列的大小時,它也會對該列進行排序。 我希望只有單擊標題時才能對列進行排序。

我的第一種方法是使用Java接口代理來代替JTable的所有現有MouseListener,攔截事件並僅傳遞與單擊相關的事件。雖然這看起來好像過火了。有沒有更好的辦法?

回答

2

我的第一種方法是使用Java接口代理來代替JTable的所有現有鼠標監聽器,攔截事件並僅傳遞與單擊相關的事件。

,基本上是如何工作的:

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

+0

+1 MouseEvent.dispatchEvent(),可能通過直接使用consume() – mKorbel 2013-02-26 17:53:56