【问题标题】:How to make a columns in JTable Invisible for Swing Java如何使 JTable 中的列对 Swing Java 不可见
【发布时间】:2010-12-02 07:25:15
【问题描述】:

我设计了一个 GUI,我在其中使用了一个 JTable,我必须从中使 2 列不可见。我该怎么做?

【问题讨论】:

    标签: java swing jtable invisible


    【解决方案1】:

    将最小、最大和“正常”宽度设置为 0:

    jTable.getColumn("ABC").setMinWidth(0); // Must be set before maxWidth!!
    jTable.getColumn("ABC").setMaxWidth(0);
    jTable.getColumn("ABC").setWidth(0);
    

    注意:由于不能设置maxWidthminWidth,需要先更改minWidth,(javadoc)。 width 也是如此。

    第二种方法是扩展 TableColumnModel 并覆盖所有方法以创建模型没有这两列的错觉(对于 JTable)。

    所以当你隐藏一列时,当表格要求列数时,你必须返回一个,当它要求列X时,你可能要在列索引上加1(取决于它是否是隐藏列的左侧或右侧)等。

    让您的新表模型将所有方法调用(使用更正的索引等)转发到实际的列模型,并在 JTable 中使用新表模型。

    【讨论】:

    • 您还必须设置最小和最大宽度。
    • 为什么顺序很重要,我先试过了,我没有使用相同的顺序,所以它不起作用,oec我使用了相同的顺序(宽度,最小,最大)它有效,所以为什么?
    • @MohammedHousseynTaleb 很有趣。似乎那些不是简单的二传手。我的猜测是安装侦听器是为了更新布局,而 Swing 中的布局有时通常令人惊讶。
    • @MohammedHousseynTaleb ty 发表评论。我也按错误的顺序做,现在看一下代码: this.maxWidth = Math.max(minWidth, maxWidth);现在应该很清楚了。如果 minWidth 设置为 10 并且您想将 maxWidth 设置为 0 则需要 minWidth ...实际上它也在 javadoc 中提到(但我也没有阅读)
    【解决方案2】:

    如果您从JTable 中删除该列,则该列仍存在于TableModel 中。

    例如删除第一个 ID 列:

    TableColumnModel tcm = table.getColumnModel();
    tcm.removeColumn(tcm.getColumn(0));
    

    如果你想访问被移除列的值,你必须通过TableModelgetValueAt函数来访问它,而不是JTable。但是你必须将模型中的rowIndex转换回rowIndex。

    例如,如果您想访问所选行的第一列:

    int modelRow = table.convertRowIndexToModel(table.getSelectedRow());
    int value = (Integer)table.getModel().getValueAt(modelRow,0);
    

    【讨论】:

      【解决方案3】:

      TableColumnModel 中删除TableColumn

      TableColumnModel tcm = table.getColumnModel();
      tcm.removeColumn( tcm.getColumn(...) );
      

      如果您需要访问数据,请使用table.getModel().getValueAt(...)

      对于允许用户根据需要隐藏/显示列的更复杂的解决方案,请查看Table Column Manager

      【讨论】:

      • 这是真正正确的方法 - 将宽度设置为 0 有点假。这样你的模型中仍然有数据;你只是隐藏了视图的一部分。
      • 即使采用上述方法,数据仍然存在于模型中,这就是您可以如上所示访问它的原因。这就是 MVC 的工作原理。我们所做的只是改变观点。当您将宽度设置为 0 时,尝试使用制表符,当您点击隐藏列时焦点会消失,直到您再次制表符。这会让用户感到困惑。
      • 这行得通,除了使这种方法无用的一件事。当您想知道哪个是您选择的列时,您将得到该列的错误(移位)索引。换句话说,做 table.getColumnModel().getSelectedColumns() 会给你一个错误的列。
      • 其实我错了...做 column.getModelIndex() 在模型中给出正确的位置。只是不要使用 table.getSelectedColumn() - 这会给出错误的索引。
      • @Dima 您需要了解viewmodel 之间的区别。表方法总是引用视图。 JTable API 有一堆convertXXX 可以使用的方法。所以你可以使用convertColumnIndexToModel(...)
      【解决方案4】:

      我遇到了同样的问题,因为我使用的是 TableColumnModel removColumn(); 对我没有帮助,所以我使用了这个

      table.getColumnModel().getColumn(0).setWidth(0);
      table.getColumnModel().getColumn(0).setMinWidth(0);
      table.getColumnModel().getColumn(0).setMaxWidth(0); 
      

      对我来说工作得很好,它隐藏了第 0 列,我仍然可以从中获得价值

      【讨论】:

        【解决方案5】:

        首先从视图中移除列

         table.removeColumn(table.getColumnModel().getColumn(4));
        

        然后从模型中检索数据。

        table.getModel().getValueAt(table.getSelectedRow(),4);
        

        需要注意的是,在检索数据时,必须从模型中检索,而不是从表中检索。

        【讨论】:

        • 如何从模型中删除?
        【解决方案6】:

        我都试过了:它们没有帮助。最好的方法是创建一个没有要删除的列的新表模型。这就是你的做法:

        table = (DefaultTableModel) <table name>.getModel();
        DefaultTableModel table1 = new DefaultTableModel();
        Vector v = table.getDataVector();
        Vector v1 = newvector(v,<column index you want to delete>);
        
        Vector newvector(Vector v,int j){
            Vector v1= new Vector();
            try{
                Vector v2;
                Object[] o = v.toArray();
                int i =0;
                while(i<o.length){
                    v2 = (Vector) o[i];
                    v2.remove(j);
                    v1.add(v2);
                    i++;
                }
            }
            catch(Exception e){
                JOptionPane.showMessageDialog(null,"Error in newvector \n"+e);
            }
            return v1;
        }
        
        Vector getColumnIdentifiers(int i) {
            Vector columnIdentifiers = new Vector();
            int j=0;
            while(j<i){
                columnIdentifiers.add(("c"+(j+1)));
                j++;
            }
            return columnIdentifiers;
        }
        table1.setDataVector(v1,getColumnIdentifiers((<column count>-1)));
        <table name>.setModel(table1);
        

        【讨论】:

          【解决方案7】:

          我尝试了两种可行的解决方案,但第一种解决方案出现了一些问题。

             table.removeColumn(table.getColumnModel().getColumn(4));
          

             table.getColumnModel().getColumn(4).setMinWidth(0);
             table.getColumnModel().getColumn(4).setMaxWidth(0);
             table.getColumnModel().getColumn(4).setWidth(0);
          

          在我最近的案例中,我更喜欢第二种解决方案,因为我添加了一个 TableRowSorter

             TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
             table.setRowSorter(sorter);
          

          使用table.removeColumn(table.getColumnModel().getColumn(4)) 时,它会从视图/表中物理删除列,因此您不能使用table.getValueAt(row, 4) - 它返回ArrayIndexOutOfBounds。获取已删除列的值的唯一方法是调用table.getModel().getValueAt(table.getSelectedRow(),4)。由于 TableRowSorter 只对表中的内容进行排序,而不是对 DefaultTableModel 对象中的数据进行排序,因此问题是当您在对记录进行排序之后获得值 after - 它将从 DefaultModelObject 中检索数据,该数据未排序。

          所以我使用了第二种解决方案,然后使用了table.getValueAt(table.getSelectedRow(),4);

          @camickr 提到了我在第二种方法中看到的唯一问题:“当您将宽度设置为 0 时,请尝试使用制表符,当您点击隐藏列时焦点会消失,直到您再次制表符。这会让用户感到困惑。”

          【讨论】:

          • 使用`table.getModel().getValueAt(table.convertRowIndexToModel(row), 4)。
          【解决方案8】:

          您可以创建模型的子类,并按如下方式覆盖TableModel.getColumnCount

          int getColumnCount() {
              return super.getColumnCount()-2;
          }
          

          最后两列将不会显示在JTable 中。

          【讨论】:

          • 但是我可以从他们那里得到数据吗?
          • 您只是在制造列不存在的错觉,但列仍然存在,因此应该能够获取数据
          • 但是我应该如何从 GUI 中隐藏它们。
          • 不确定我理解你的意思。您的意思是您的应用程序的用户应该能够隐藏或显示?
          • 嘿,我通过使用以下代码解决了这个问题 jtable.removeColumn(jtable.getColumnModel().getColumn());列从 GUI 中隐藏,我们也可以从中获取存储的值。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-01-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多