2013-02-26 4 views
1

커스텀 RowSorter를 사용하여 정렬 가능한 열을 가진 JTable을 가지고 있습니다. RowSorter 클래스는 자동으로 사용자 정의 마우스 청취 코드를 추가하지 않고 정렬을 자동으로 수행하므로 테이블의 ColumnHeader에 MouseListener로 자동 추가됩니다. 이것은 완벽하게 작동합니다.더블 클릭시 JTable 자동 정렬 금지

사용자가 열 머리글에서 두 번 클릭하여 테이블 열의 크기를 조정할 수있는 코드 (this example 기준)를 추가했습니다 (Excel의 동작을 모방합니다). 문제는 사용자가 열의 크기를 조정하기 위해 머리글을 두 번 클릭하면 해당 열도 정렬된다는 것입니다. 헤더를 한 번 클릭하면 열 정렬 만하고 싶습니다.

첫 번째 방법은 Java 인터페이스 프록시를 사용하여 JTable의 기존 MouseListeners를 모두 바꾸고 이벤트를 가로 채고 단 한번의 클릭과 관련된 이벤트 만 전달하는 것이 었습니다. 그래도 잔인한 것처럼 보입니다. 더 좋은 방법이 있습니까?

답변

2

내 첫 번째 방법은 Java 인터페이스 프록시를 사용하여 JTable의 기존 MouseListeners를 모두 바꾸고 이벤트를 가로 채고 단 한번의 클릭과 관련된 이벤트 만 전달하는 것이 었습니다.

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