2013-11-14 59 views
3

我有一个JTable,它是可排序的(通过在初始化时调用setAutoCreateRowSorter(true)进行排序)。我以编程方式对此表进行排序,并且希望禁用表头中的缺省事件处理,以便可以以编程方式对表进行排序只有。如何实现它?仅以编程方式进行JTable排序

的代码工作件将是:

public class SortTable extends JDialog { 

    private JTable table; 

    DefaultRowSorter<TableModel, String> sorter; 

    public SortTable() { 
     JScrollPane scrollPane = new JScrollPane(); 
     setBounds(0, 0, 300, 200); 
     getContentPane().setLayout(new BorderLayout()); 
     getContentPane().add(scrollPane, BorderLayout.CENTER); 

     //-------most important stuff------------------- 
     table = new JTable(); 
     table.setAutoCreateRowSorter(true); //enabling sorting 
     table.setModel(createModel()); 
     sorter = (DefaultRowSorter<TableModel, String>)table.getRowSorter(); //store sorter to sort programatically later on 
     //----------------------------------------------- 

     scrollPane.setViewportView(table); 
     JPanel buttonPane = new JPanel(); 
     buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); 
     getContentPane().add(buttonPane, BorderLayout.SOUTH); 
     buttonPane.add(new JButton(getSortAction())); 
    } 

    private AbstractAction getSortAction() { 
     return new AbstractAction("Sort") { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       sorter.setSortKeys(Arrays.asList(new SortKey(0,SortOrder.ASCENDING))); 
       sorter.sort(); //sorting programatically 

      } 
     }; 
    } 

    private DefaultTableModel createModel() { 
     return new DefaultTableModel(
      new Object[][] { 
       {"1", "3"}, 
       {"5", "2"}, 
       {"4", null}, 
      }, 
      new String[] { 
       "A", "B" 
      } 
     ); 
    } 
} 

这个例子是含有一个JTable与排序按钮一个JDialog。按下该按钮将导致列A按升序排序。但是,该按钮并不是排序表的唯一方法 - 我们只需单击表头即可更改排序。我的问题是如何使按钮成为排序表的唯一方法。 知道如何摆脱排序改变时出现的箭头也是很好的。

+2

similair问题都是在这和上个月几次,搜索BZ点击RowSorter的标签,或TableRowSorter还 – mKorbel

+1

@mKorbel darn,我应该偶尔读一下api文档;-) – kleopatra

回答

4

阅读类似问题(如@mKorbel建议)的帖子并尝试自己我已经设法找到解决方案。 主要问题的答案是:使用DefaultRowSorter的setSortable(int index, boolean sortable)方法。似乎很明显,但有趣的是,此方法在使用RowSorter的toggleSortOrder(int index)时禁用了对列的排序,但在使用DefaultRowSorter的sort()方法时将忽略它。这是一种不一致吗?无论如何,这让门开着一个窍门。现在我可以这样做:

 for (int i=0 ; i<table.getColumnCount() ; i++) { 
      sorter.setSortable(i, false); 
     } 

...和voila - 无法通过单击表格标题对表格进行排序,但它可以通过编程方式进行排序。 如果有人面对隐藏像我这样的排序顺序指示符图标的奇怪要求,那么有办法。首先会产生全局效果,我不喜欢它 - 将相应的属性设置为UIManager。

 UIManager.put("Table.ascendingSortIcon", new EmptyIcon()); 
     UIManager.put("Table.descendingSortIcon", new EmptyIcon()); 

最好的一个是装饰的tableHeader的默认渲染器:

 final TableCellRenderer defaultRenderer = table.getTableHeader().getDefaultRenderer(); 
     table.getTableHeader().setDefaultRenderer(new TableCellRenderer() { 

      @Override 
      public Component getTableCellRendererComponent(JTable table, 
        Object value, boolean isSelected, boolean hasFocus, 
        int row, int column) { 
       JLabel label = (JLabel)defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); 
       label.setIcon(null); 
       return label; 
      } 

     }); 
+1

_Is that a inconsistency_ no,it's designed(and documented)。精确地解决你的需求:-) – kleopatra

+0

是的,你是对的,我错过了。另一方面,JTableHeader类具有此方法setReorderingAllowed,它可以禁用列重新排序。说实话,我认为setRowSortingAllowed或者smth也会更直观。这更自然地意味着标题正在监听鼠标事件。实际的排序引擎(RowSorter)根本不会涉及。 – macias

+0

完全同意,很好的论点:-)其实,我忘记了可排序属性的确切含义,并建议绕过(删除)。也许在SwingX的sortController中有一个错误,它有另外的用于编程排序的API(setSortOrder),如果该列不可排序,它什么也不做。 – kleopatra

相关问题