Jtable动态固定列问题

Jtable dynamical fixed columns problems

我创建了一个可以动态锁定和解锁列的 class。 在我的程序中,我创建了两个具有相同 table 模型的 table。 一个在滚动窗格的 Jviewport 中,另一个在 RowHeaderView 中。 问题是当您解锁所有锁定的列时 而你想重新开始锁定,是行不通的。没有错误,但好像事件没有响应。

产生问题的步骤:

  1. 尝试代码,
  2. 将所有列固定在 table、
  3. 然后右键双击解锁,
  4. 然后重新开始锁定,解锁

执行此过程,您可以看到鼠标事件不再响应

public class Prova extends JFrame{

private JTable mainTable,fixedTable;
private JScrollPane scrollPane;
private JTableHeader mainTableHeader;
private TableColumnModel originalColumnModel,mainColumnModel,fixedColumnModel;
private TableColumn[] columns;
private int ncols,counter;

public Prova(){

    counter = 0;
    TableModel mainTableModel = new DefaultTableModel(5, 10);
    scrollPane = new JScrollPane();
    mainTable = new JTable(mainTableModel);
    mainColumnModel = mainTable.getColumnModel();

    fixedTable = new JTable();
    fixedTable.setAutoCreateColumnsFromModel(false);
    fixedTable.setModel(mainTable.getModel() );

    ncols = mainTableModel.getColumnCount();
    columns = new TableColumn[ncols];
    for (int i=0;i<ncols;i++){
        columns[i] = mainColumnModel.getColumn(i);
    }

    mainColumnModel = mainTable.getColumnModel();
    fixedColumnModel = fixedTable.getColumnModel();
    mainTableHeader = mainTable.getTableHeader();

    mainTableHeader.addMouseListener( new MouseAdapter(){
    @Override
        public void mouseClicked(MouseEvent me){
            if (SwingUtilities.isRightMouseButton(me)){
                if (ncols - counter>1){
                    counter ++;
                    int col = mainTable.columnAtPoint(me.getPoint());
                    TableColumn column = mainColumnModel.getColumn(col);
                    mainColumnModel.removeColumn(column);
                    fixedTable.getColumnModel().addColumn(column);
                    scrollPane.setRowHeaderView(fixedTable);
                    scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());
                }
            }
        }
    });

    fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {
    @Override
        public void mouseClicked(MouseEvent me){
            if (SwingUtilities.isRightMouseButton(me) && me.getClickCount()== 2 ){

                while (mainColumnModel.getColumnCount() > 0){
                    mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
                }

                while (fixedColumnModel.getColumnCount() > 0){
                    fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
                }

                for(int i=0;i<ncols;i++){
                    mainColumnModel.addColumn(columns[i]);
                }

                scrollPane.setRowHeaderView(null); 
            }

        }
    });

    scrollPane.setViewportView(mainTable);
    add(scrollPane, BorderLayout.CENTER);
    pack();
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
@Override
        public void run() {
    new Prova().setVisible(true);
        }
});
}
}

发布 SSCCE 时的一些提示:

for (int i=0;i<ncols;i++){

不要害怕在您的代码中使用空格来分隔 for 语句的 3 个语句以使其更具可读性。

for (int i = 0; i < ncols; i++){

保持代码简单并与问题直接相关:

TableModel mainTableModel = new EmployeeTableModel(listEmployees);

您的问题是关于 "moving columns",而不是关于 table 中的数据,因此不需要特殊的 TableModel 和 Employee class。只需使用 DefaultTableModel:

TableModel mainTableModel = new DefaultTableModel(5, 10);

您当前的代码无法编译,因为您没有包含 Employee class。通过使用 JDK classes,代码更小且更易于阅读。

The problem is when you unlock all the locked columns and you want to start to lock again, doesnt work

你的循环代码是错误的。我懒得去弄清楚哪里出了问题。相反,我使代码更简单:

//for(int i=0;i<(ncols-counter);i++){
while (mainColumnModel.getColumnCount() > 0)
{
    mainColumnModel.removeColumn(mainColumnModel.getColumn(0));
}

//for(int i=0;i<counter;i++){
while (fixedColumnModel.getColumnCount() > 0)
{
    fixedColumnModel.removeColumn(fixedColumnModel.getColumn(0));
}

另一个问题是你的固定 table 没有 header 所以你不知道列是什么。这是通过使用修复的:

scrollPane.setRowHeaderView(fixedTable);
scrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, fixedTable.getTableHeader());

现在您有了 header,您需要将 MouseListener 添加到 header,而不是滚动窗格:

//scrollPane.addMouseListener(new MouseAdapter() {
fixedTable.getTableHeader().addMouseListener(new MouseAdapter() {

编辑:

您遇到的问题与我上面解决的问题类似。那就是当您可以使用组件本身时,不要继续使用变量来跟踪值。

if (ncols - counter>1){

您永远不会重置计数器的值,因此 if 条件不会第二次为真。

正如我在上面所做的那样,只使用列模型中的值:

//if (ncols - counter>1){
if (mainColumnModel.getColumnCount() > 1) {

这只是基本的问题解决。在代码块中放一条显示语句,看你遇到问题时是否执行。