2012-05-01 4 views
2

Я делаю программу, связанную с графикой, поэтому мне нужно динамически создавать/удалять столбцы из JTable для имитации таблицы смежности. Я уже могу создавать столбцы по желанию, но я не могу их удалить, потому что, если я удалю столбец, а затем создаю другой столбец, предыдущие данные (из удаленного столбца) будут показаны в последнем столбце.Удалить столбец из JTable

Я читал это потому, что данные столбца не удаляются из таблицы. Я видел примеры, чтобы скрыть или показать столбцы, но мне действительно нужно их удалить, поэтому, когда я получу двумерную матрицу данных, у меня нет перекрестных ссылок или плохих данных.

Первая поправка:

private DefaultTableModel removeCol(int id){ 
     DefaultTableModel tmp = new DefaultTableModel(); 
     int columnas = modelo.getColumnCount(); 
     for(int i=0;i<columnas;i++){ 
      if(i!=id) 
       tmp.addColumn(modelo.getColumnName(i)); 
     } 
     int rows = modelo.getRowCount(); 
     String datos[] = new String[columnas-1]; 
     for(int row=0;row<rows;row++){ 
      for(int col=0,sel=0;col<columnas;col++,sel++){ 
       if(col!=id) 
        datos[sel] = (String) modelo.getValueAt(row, col); 
       else 
        sel--; 
      } 
      tmp.addRow(datos); 
     } 
     return tmp; 

    } 

При вызове:

DefaultTableModel mo = removeCol(i); 
    tblTrans = new JTable(mo); 
+3

Один из способов - предоставить новый «TableModel» с теми же данными, за исключением одного столбца меньше. Возможно, лучший способ - создать пользовательскую модель таблицы, которая позволяет настраивать видимость столбцов и настраивать столбцы columnCount и соответствующие столбцы во время выполнения. –

+0

Я попытался сделать первый вариант, но после получения исправленного TableModel (проверено с помощью отладчика, так что данные, столбцы и все в порядке) Я не могу заставить JTable показать новую модель, она показывает старую модель: S (Подробности в моем сообщении) –

+0

Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). –

ответ

4

adjacency matrix может быть более легко манипулировать в AbstractTableModel, где вы можете явно манипулировать строк игнорировать один столбец. В общих чертах,

class MatrixModel extends AbstractTableModel { 

    private int rows; 
    private int cols; 
    private Boolean[][] matrix; 

    MatrixModel(int rows, int cols) { 
     this.rows = rows; 
     this.cols = cols; 
     matrix = new Boolean[rows][cols]; 
    } 

    public void deleteColumn(int col) { 
     for (Boolean[] row : matrix) { 
      Boolean[] newRow = new Boolean[row.length - 1]; 
      // TODO: copy remaining values 
      row = newRow; 
     } 
     this.fireTableStructureChanged(); 
    } 
    ... 
} 
2

, например

import java.awt.BorderLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Stack; 
import javax.swing.JButton; 
import javax.swing.JDialog; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.table.TableColumn; 

public class MyDialog extends JDialog { 

    private static final long serialVersionUID = 1L; 
    private String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"}; 
    private Stack<TableColumn> colDeleted = new Stack<TableColumn>(); 

    public MyDialog() { 
     Object[][] data = {{"Mary", "Campione", "Snowboarding", new Integer(5), false}, 
      {"Alison", "Huml", "Rowing", new Integer(3), true}, 
      {"Kathy", "Walrath", "Knitting", new Integer(2), false}, 
      {"Sharon", "Zakhour", "Speed reading", new Integer(20), true}, 
      {"Philip", "Milne", "Pool", new Integer(10), false}}; 
     final JTable table = new javax.swing.JTable(data, columnNames); 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     add(new JScrollPane(table)); 
     final JButton button1 = new JButton("Add Col"); 
     final JButton button = new JButton("Remove Last Col"); 
     button.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent arg0) { 
       if (table.getColumnCount() > 0) { 
        TableColumn colToDelete = table.getColumnModel().getColumn(table.getColumnCount() - 1); 
        table.removeColumn(colToDelete); 
        table.validate(); 
        colDeleted.push(colToDelete); 
        button1.setEnabled(true); 
       } else { 
        button.setEnabled(false); 
       } 
      } 
     }); 
     button1.addActionListener(new ActionListener() { 

      public void actionPerformed(ActionEvent arg0) { 
       if (colDeleted.size() > 0) { 
        table.addColumn(colDeleted.pop()); 
        table.validate(); 
        button.setEnabled(true); 
       } else { 
        button1.setEnabled(false); 
       } 
      } 
     }); 
     JPanel southPanel = new JPanel(); 
     southPanel.add(button); 
     southPanel.add(button1); 
     add(southPanel, BorderLayout.SOUTH); 
     setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 
     pack(); 
     setLocation(150, 150); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     javax.swing.SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       MyDialog myDialog = new MyDialog(); 
      } 
     }); 
    } 
} 
0

Поскольку DefaultModelTable не removeColumn этот код может быть использован:

private String[] getRemainingIdentifiers(int columnIndex) { 

    String[] identifiers = new String[table.getColumnCount() - 1]; 
    int k = 0; 

    for(int i = 0; i < table.getColumnCount(); i++) { 
     if(i != columnIndex) { 
      identifiers[k++] = table.getColumnName(i); 
     } 
    } 

    return identifiers; 
} 

private void removeColumn(int columnIndex) { 

    String[][] data = new String[table.getRowCount()][table.getColumnCount() - 1]; 

    for(int i = 0; i < table.getRowCount(); i++) { 
     for(int j = 0; j < table.getColumnCount(); j++) { 

      if(j != columnIndex) { 
       if(table.getValueAt(i, j) == null) { 
        table.setValueAt("", i, j); 
       } 
       if(j < columnIndex) { 
        data[i][j] = table.getValueAt(i, j).toString(); 
       } else { 
        data[i][j - 1] = table.getValueAt(i, j).toString(); 
       } 
      } 
     } 
    } 

    modeltable = new DefaultTableModel(data, getRemainingIdentifiers(columnIndex)); 
    table.setModel(modeltable); 

} 
0

DefaultDataModel не имеет функции действительно removeColumn() , поэтому я сам написал функцию, которая может реально решить проблему.

private void removeColumn(int index, JTable myTable){ 
    int nRow= myTable.getRowCount(); 
    int nCol= myTable.getColumnCount()-1; 
    Object[][] cells= new Object[nRow][nCol]; 
    String[] names= new String[nCol]; 

    for(int j=0; j<nCol; j++){ 
     if(j<index){ 
      names[j]= myTable.getColumnName(j); 
      for(int i=0; i<nRow; i++){ 
       cells[i][j]= myTable.getValueAt(i, j); 
      } 
     }else{ 
      names[j]= myTable.getColumnName(j+1); 
      for(int i=0; i<nRow; i++){ 
       cells[i][j]= myTable.getValueAt(i, j+1); 
      } 
     } 
    } 

    DefaultTableModel newModel= new DefaultTableModel(cells, names); 
    myTable.setModel(newModel);  
} 
+0

Пожалуйста, не просто отправляйте один и тот же ответ на несколько вопросов, не приспосабливаясь, чтобы объяснить его применимость к каждому из них. –

Смежные вопросы