Sort JTable when mouse is released

I have a JTable with the AutoCreateRowSorter property set to true. It works great when clicked, but if I move the mouse during a click for 1px only, sorting does not appear, which is inconvenient in some situations. How to fix it?

UPD I just want the sort to appear when the mouse is released.

0
java sorting events swing jtable
Jan 21 '13 at 11:21
source share
1 answer

A dirty (read: don't, if you are not completely desperate and know exactly what you are doing!) Approach is to connect to the MouseListener installed by uiDelegate and move the sort trigger to the released method. This includes

  • a custom MouseListener that delegates all events except clicking on the originally installed and sorting before passing released
  • replace original with custom
  • update replacement whenever LAF changes (as the original is controlled by ui). This requires subclassing JTableHeader and posting to updateUI

User Listener:

public static class EventHook implements MouseListener { private JTableHeader header; private MouseListener delegate; public EventHook(JTableHeader header) { this.header = header; installHook(); } protected void installHook() { MouseListener[] listeners = header.getMouseListeners(); for (int i = 0; i < listeners.length; i++) { MouseListener l = listeners[i]; if (l.getClass().getName().contains("TableHeaderUI")) { this.delegate = l; listeners[i] = this; } header.removeMouseListener(l); } for (MouseListener l : listeners) { header.addMouseListener(l); } } public void uninstallHook() { MouseListener[] listeners = header.getMouseListeners(); for (int i = 0; i < listeners.length; i++) { MouseListener l = listeners[i]; if (l == this) { listeners[i] = delegate; } header.removeMouseListener(l); } for (MouseListener l : listeners) { header.addMouseListener(l); } } @Override public void mouseReleased(MouseEvent e) { // sort before calling super sort(e); delegate.mouseReleased(e); } private void sort(MouseEvent e) { if (!header.isEnabled()) { return; } // do nothing if dragged if (header.getDraggedDistance() != 0) { return; } if (e.getClickCount() % 2 == 1 && SwingUtilities.isLeftMouseButton(e)) { JTable table = header.getTable(); RowSorter sorter; if (table != null && (sorter = table.getRowSorter()) != null) { int columnIndex = header.columnAtPoint(e.getPoint()); if (columnIndex != -1) { columnIndex = table.convertColumnIndexToModel( columnIndex); sorter.toggleSortOrder(columnIndex); } } } } @Override public void mouseClicked(MouseEvent e) { // swallow the clicked - want to trigger sort on released } @Override public void mousePressed(MouseEvent e) { delegate.mousePressed(e); } @Override public void mouseEntered(MouseEvent e) { delegate.mouseEntered(e); } @Override public void mouseExited(MouseEvent e) { delegate.mouseExited(e); } } 

JTableHeader Subclasses

 public static class MyTableHeader extends JTableHeader { private EventHook hook; public MyTableHeader(TableColumnModel model) { super(model); } @Override public void updateUI() { if (hook != null) { hook.uninstallHook(); hook = null; } super.updateUI(); hook = new EventHook(this); } } 

Use a JTable subclass and override createDefaultTableHeader or manually set the header:

 // either subclass JTable table = new JTable(new AncientSwingTeam()) { @Override protected JTableHeader createDefaultTableHeader() { return new MyTableHeader(getColumnModel()); } }; table.setAutoCreateRowSorter(true); 
+1
Jan 21 '13 at 13:22
source share



All Articles