java - 在 JTable header 中显示排序图标而不使用内置排序机制

标签 java swing sorting jtable jtableheader

有人知道在 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) { }

}

最佳答案

在这种情况下,您可以尝试编写自定义 TableCellRenderer对于JTableHeader

这是渲染器的简单示例:

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;
    }
}

这里 icon1icon2 是您的排序图标。

您可以为 JTableHeader 设置渲染器,如下所示:

table.getTableHeader().setDefaultRenderer(new MyRenderer(table));

table - 是您的JTable

关于java - 在 JTable header 中显示排序图标而不使用内置排序机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21090368/

相关文章:

java - 如果用户不验证电子邮件,会发生什么?

java - 是否有必要在DefaultTreeModel中调用nodesWereInserted()和类似方法?

java - JButton 不起作用?

java - 按自定义顺序对 Arraylist 进行排序

java - 安全 - 阻止人们未经授权使用我的程序

java - 在 Spring Boot 应用程序中未针对 hibernate 和 spring 过滤 Log4j2 日志级别

java - 从数据库检索值并将其返回给调用方法

java - 使用空布局将 JPanel 添加到 JApplet

sorting - 如何按日期对 SVN LS -R 输出进行排序

java - 对对象数组进行排序会引发 long[] 错误