单击JTable Header时排序错误的列 [英] Wrong column being sorted when JTable Header clicked

查看:132
本文介绍了单击JTable Header时排序错误的列的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有 RowSorterListener 的以下代码。这样做的目的是对列进行排序而不影响任何其他列。

I have the following code for a RowSorterListener. The purpose of this is to sort a column without affecting any other columns.

import javax.swing.event.RowSorterListener;
import javax.swing.event.RowSorterEvent;
import javax.swing.JTable;
import javax.swing.RowSorter.SortKey;
import java.util.List;
import java.util.Arrays;

public class UnrelateData implements RowSorterListener {
    JTable table;
    int columnSorted = -1;
    Object[][] dataStore;

    public UnrelateData(JTable table) {
        this.table = table;
    }

    @Override
    public void sorterChanged(RowSorterEvent e)
    {
        if(e.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
            List<SortKey> keys = e.getSource().getSortKeys();
            for (SortKey key : keys) {
                if (key.getColumn() == -1) {
                    columnSorted = -1;
                    break;
                } else {
                    columnSorted = key.getColumn();
                    break;
                }
            }
            dataStore = getData();
        }

        if(e.getType() == RowSorterEvent.Type.SORTED) {
            List<SortKey> keys = e.getSource().getSortKeys();
            for (SortKey key : keys) {
                if (key.getColumn() == -1) {
                    columnSorted = -1;
                    break;
                } else {
                    columnSorted = key.getColumn();
                    break;
                }
            }

            for(int i = 0; i < table.getColumnCount(); i++) {
                if(i != columnSorted && columnSorted != -1) {
                    for (int j = 0; j < table.getRowCount(); j++) {
                        table.setValueAt(dataStore[i][j], j, i);
                    }
                }
            }
        }
    }

    private Object[][] getData() {
        int columnCount = table.getColumnCount();
        int rowCount = table.getRowCount();
        Object[][] tempData = new Object[columnCount][rowCount];

        for(int i = 0; i < columnCount; i++) {
            for(int j = 0; j < rowCount; j++) {
                tempData[i][j] = table.getValueAt(j, i);
            }
        }

        return tempData;
    };
}

这很有效。但是,有一个重大故障。如果移动了一列,并且我尝试对列进行排序,则它不会对列进行正确排序。相反,它会错误地对列移动的原始位置中的列进行排序。

This works well. However, there is one major glitch. If a column is moved and I try to sort a column it doesn't correctly sort the column. Instead, it incorrectly sorts the column in the original place of the column moved.

它应该看起来像(第1列和第2列保持未分类)

Whereas it should look like (Where "Column 1" and "Column 2" remain unsorted)

有人能够解释为什么会发生这种情况以及如何解决这个问题吗?

Would someone be able to explain why this occurs and how to fix it?

注意:我不想使用 JTableHeader.reorderingAllowed(false)

修改

我将以下for循环添加到我的代码中并尝试了不同的变体,但它似乎无法正常工作

I added the following for loops into my code and tried different variations but it didn't seem to work

尝试1

if(e.getType() == RowSorterEvent.Type.SORTED) {
    int[] actualColumn = new int[table.getColumnCount()];
    for(int i = 0; i<table.getColumnCount(); i++){
        actualColumn[i] = table.convertColumnIndexToModel(i);
    }

    int[] actualRow = new int[table.getRowCount()];
    for(int i = 0; i<table.getRowCount(); i++){
        actualRow[i] = table.convertRowIndexToModel(i);
    }

    List<SortKey> keys = e.getSource().getSortKeys();
    for (SortKey key : keys) {
        if (key.getColumn() == -1) {
            columnSorted = -1;
            break;
        } else {
            columnSorted = key.getColumn();
            break;
        }
    }

    for(int i = 0; i < table.getColumnCount(); i++) {
        if(i != columnSorted && columnSorted != -1) {
            for (int j = 0; j < table.getRowCount(); j++) {
                table.setValueAt(dataStore[i][j], actualRow[j], actualColumn[i]);
            }
        }
    }
}

尝试2

private Object[][] getData() {
    int columnCount = table.getColumnCount();
    int rowCount = table.getRowCount();

    int[] actualColumn = new int[columnCount];
    for(int i = 0; i<table.getColumnCount(); i++){
        actualColumn[i] = table.convertColumnIndexToModel(i);
    }

    int[] actualRow = new int[rowCount];
    for(int i = 0; i<table.getRowCount(); i++){
        actualRow[i] = table.convertRowIndexToModel(i);
    }

    Object[][] tempData = new Object[columnCount][rowCount];

    for(int i = 0; i < columnCount; i++) {
        for(int j = 0; j < rowCount; j++) {
            tempData[i][j] = table.getValueAt(actualRow[j], actualColumn[i]);
        }
    }

    return tempData;
};

尝试3是尝试一个和两个放在一起

Attempt 3 was both attempt one and two put together

推荐答案


  • 中的代码> RowSorterListener 是指定正确返回索引(来自 RowSorterListener s event)

    • code in RowSorterListener is designatet to returns the index correctly (from RowSorterListeners event)

      默认情况下,你永远不需要知道 JTable的订购 s视图,所有这些事件都是模型事件

      by default you never need to know ordering from JTables view, all those events are models events,

      add TableColumnModelListener 如果要跟踪 columnMoved ,则以编码方式排序的所有事件都将绘制在中JTable 正确查看

      add TableColumnModelListener in the case that you want to trace columnMoved, all events from sorting programatically are painted in JTables view correctly

      1st。没有列重新排序的attemtp,

      1st. attemtp without column reordering,

      Column NO. - 0 is sorted
      Column NO. - 1 is sorted
      Column NO. - 2 is sorted
      Column NO. - 3 is sorted
      Column NO. - 4 is sorted
      
      ... and so on
      BUILD SUCCESSFUL (total time: 21 seconds)
      


      • 第二名。尝试列重新排序(通过鼠标拖动)

      Column NO. - 0 is sorted
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      Column NO. - 1 is sorted
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnSelectionChanged from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      Column NO. - 2 is sorted
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      columnMoved from ColumnModelListener
      Column NO. - 3 is sorted
      Column NO. - 4 is sorted
      Column NO. - 0 is sorted
      Column NO. - 1 is sorted
      Column NO. - 2 is sorted
      BUILD SUCCESSFUL (total time: 10 seconds)
      




      • 第三。如果没有初始化Swing Timer并且所有事件都是由用户手提出的,那么尝试相同的正确输出

        • 3rd. attempt the same correct output if Swing Timer isn't initialized and all event are made by users hand

          例如

          import java.awt.EventQueue;
          import java.awt.event.ActionEvent;
          import java.util.Arrays;
          import java.util.List;
          import java.util.Random;
          
          import javax.swing.*;
          import javax.swing.RowSorter.SortKey;
          import javax.swing.event.*;
          import javax.swing.table.*;
          
          public class SortTest1 {
          
              private JFrame frame = new JFrame(getClass().getSimpleName());
          
              private DefaultTableModel model = new DefaultTableModel(10, 5) {
                  private static final long serialVersionUID = 1L;
          
                  @Override
                  public Class<?> getColumnClass(int column) {
                      return getValueAt(0, column).getClass();
                  }
              };
              private JTable table = new JTable(model);
              private TableRowSorter<?> sorter;
              private static final Random rnd = new Random();
              private Timer timer;
              private int columnNo = 0;
          
          
              public SortTest1() {
                  for (int row = model.getRowCount(); --row >= 0;) {
                      int i = 20 + row % 20;
                      model.setValueAt(row + " " + i, row, 0);
                      model.setValueAt(i + row, row, 1);
                      model.setValueAt(rnd.nextBoolean(), row, 2);
                      model.setValueAt(rnd.nextDouble(), row, 3);
                      model.setValueAt(row + " " + i * 1, row, 4);
                  }
                  table.setAutoCreateRowSorter(true);
                  sorter = (TableRowSorter<?>) table.getRowSorter();
                  sorter.setSortsOnUpdates(true);
                  sorter.addRowSorterListener(new RowSorterListener() {
          
                      @Override
                      public void sorterChanged(RowSorterEvent rse) {
                          if (rse.getType() == RowSorterEvent.Type.SORT_ORDER_CHANGED) {
                              List<SortKey> keys = rse.getSource().getSortKeys();
                              for (SortKey key : keys) {
                                  System.out.println("Column NO. - " + key.getColumn() + " is sorted");
                                  if (key.getColumn() == 0) {
                                      break;
                                  } else {
                                      break;
                                  }
                              }
                          }
                      }
                  });
                  frame.add(new JScrollPane(table));
                  table.setPreferredScrollableViewportSize(table.getPreferredSize());
                  table.getColumnModel().addColumnModelListener(new TableColumnModelListener() {
                      // just handle columnMarginChanged to re-paint headings
                      @Override
                      public void columnMarginChanged(ChangeEvent e) {
                          System.out.println("columnMarginChanged from ColumnModelListener");
                      }
          
                      @Override
                      public void columnAdded(TableColumnModelEvent e) {
                          System.out.println("columnAdded from ColumnModelListener");
                      }
          
                      @Override
                      public void columnRemoved(TableColumnModelEvent e) {
                          System.out.println("columnRemovedfrom ColumnModelListener");
                      }
          
                      @Override
                      public void columnMoved(TableColumnModelEvent e) {
                          System.out.println("columnMoved from ColumnModelListener");
                      }
          
                      @Override
                      public void columnSelectionChanged(ListSelectionEvent e) {
                          System.out.println("columnSelectionChanged from ColumnModelListener");
                      }
                  });
                  frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  frame.pack();
                  frame.setLocationRelativeTo(null);
                  frame.setVisible(true);
                  timer = new javax.swing.Timer(1000, updateCol());
                  timer.setRepeats(true);
                  timer.start();
              }
          
              private Action updateCol() {
                  return new AbstractAction("Sort JTable") {
                      private static final long serialVersionUID = 1L;
          
                      @Override
                      public void actionPerformed(ActionEvent e) {
                          if (columnNo > 4) {
                              columnNo = 0;
                              sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(columnNo, SortOrder.ASCENDING)));              
                          } else {
                              sorter.setSortKeys(Arrays.asList(new RowSorter.SortKey(columnNo, SortOrder.ASCENDING)));
                              columnNo++;
                          }
                      }
                  };
              }
          
              public static void main(String[] args) {
                  EventQueue.invokeLater(() -> {
                      new SortTest1();
                  });
              }
          }
          

          这篇关于单击JTable Header时排序错误的列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆