[英]Displaying sort icons in JTable header without using the build in sort mechanism
有人知道在不使用内置排序功能的情况下在 JTable 的标题中显示排序图标的好方法吗?
排序是由表模型(实际上是一个数据库)完成的,而不是由 JTable 本身完成的。 这就是图标的自动显示不起作用的原因。 也许可以插入一个什么都不做的虚拟 RowSorter,但会显示排序图标?
我找到了更好的解决方案
我只是写了自己的RowSorter,这样排序没有任何效果,而是将排序请求重定向到模型。 这样,排序顺序由外观本身显示。 一些伪代码:
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import javax.swing.RowSorter;
import xyz.SortableTableModel;
public class MyRowSorter<M extends SortableTableModel> extends RowSorter<M> {
private M tableModel;
private List<? extends SortKey> sortKeys = new LinkedList<>();
public MyRowSorter(M tableModel) {
this.tableModel = tableModel;
}
@Override
public M getModel() {
return tableModel;
}
@Override
public void toggleSortOrder(int column) {
// redirecting sort request to model and modification of sortKeys
List<? extends SortKey> newSortKeys = ...;
setSortKeys(newSortKeys);
}
@Override
public int convertRowIndexToModel(int index) {
return index; // will always be the same
}
@Override
public int convertRowIndexToView(int index) {
return index; // will always be the same
}
@Override
public void setSortKeys(List<? extends SortKey> keys) {
if (keys == null) {
sortKeys = Collections.EMPTY_LIST;
} else {
sortKeys = Collections.unmodifiableList(keys);
}
fireSortOrderChanged();
}
@Override
public List<? extends SortKey> getSortKeys() {
return sortKeys;
}
@Override
public int getViewRowCount() {
return tableModel.getRowCount();
}
@Override
public int getModelRowCount() {
return tableModel.getRowCount();
}
// no need for any implementation
@Override public void modelStructureChanged() { }
@Override public void allRowsChanged() { }
@Override public void rowsInserted(int firstRow, int endRow) { }
@Override public void rowsDeleted(int firstRow, int endRow) { }
@Override public void rowsUpdated(int firstRow, int endRow) { }
@Override public void rowsUpdated(int firstRow, int endRow, int column) { }
}
在这种情况下,您可以尝试为JTableHeader
编写自定义TableCellRenderer
。
这是渲染器的简单示例:
private static class MyRenderer implements TableCellRenderer {
private ImageIcon icon1;
private ImageIcon icon2;
private TableCellRenderer defaultRenderer;
MyRenderer(JTable t){
defaultRenderer = t.getTableHeader().getDefaultRenderer();
icon1 = new ImageIcon(getClass().getResource("1.png"));
icon2 = new ImageIcon(getClass().getResource("2.png"));
}
@Override
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int col) {
Component c = defaultRenderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, col);
if(col%2 == 0){
((JLabel)c).setIcon(icon1);
} else {
((JLabel)c).setIcon(icon2);
}
return c;
}
}
这里icon1
和icon2
是您的排序图标。
你可以为你的JTableHeader
设置渲染JTableHeader
如下所示:
table.getTableHeader().setDefaultRenderer(new MyRenderer(table));
table
- 是您的JTable
。
排序是由表模型(实际上是一个数据库)完成的,而不是由 JTable 本身完成的。
查看DefaultRowSorter
类。 也许您使用setSortsOnUpdates(...)
和setSortKeys(...)
以便排序图标与数据库中的排序相匹配。 你可以试试:
setSortsOnUpdates(false)
;请注意,此方法假定您已经创建了带有列名且没有数据的 TableModel,并将模型添加到 JTable。 我认为您还需要使用:
table.setAutoCreateColumnsFromModel(false);
以防止在将数据加载到模型中时重新创建 TableColumnModel。
当您希望代码与其他现有 Swing 布局一起使用时,解决方案很棘手(我说的是 com.formdev .... flatlaf )。 这些 L&F 创建了一个特殊的标题渲染器。
这是一个简单的解决方案,适用于市场上的所有主要 L&F(纹身、formdev、jgoodies)。 诀窍是从 DefaultTableCellHeaderRenderer 继承子类,但也将表外观和感觉当前标题渲染器作为参数传递。
// this custom renderer will display the sorting icon for all afftected columns.
class CustomTableHeaderRenderer extends DefaultTableCellHeaderRenderer implements TableCellRenderer{
final private Icon ascIcon = UIManager.getIcon("Table.ascendingSortIcon");
final private Icon descIcon = UIManager.getIcon("Table.descendingSortIcon");
TableCellRenderer iTableCellRenderer = null;
public CustomTableHeaderRenderer(TableCellRenderer tableCellRenderer)
{
iTableCellRenderer = tableCellRenderer;
}
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
JLabel label = (JLabel) iTableCellRenderer.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column) ;
List<? extends SortKey> sortKeys = table.getRowSorter().getSortKeys();
label.setIcon(null);
for (SortKey sortKey : sortKeys) {
if (sortKey.getColumn() == table.convertColumnIndexToModel(column)){
SortOrder o = sortKey.getSortOrder();
label.setIcon(o == SortOrder.ASCENDING ? ascIcon : descIcon);
break;
}
}
return label;
}
}
yourTable.getTableHeader().setDefaultRenderer( new CustomTableHeaderRenderer( yourTable.getTableHeader().getDefaultRenderer() ));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.