Как вставить новую строку в JTable, используя пользовательскую модель таблицы?

Я работаю над небольшим проектом, который включает в себя JTable который требует от пользователя нажать кнопку и добавить строку в таблицу (я назвал кнопку как addrow). Я использовал пользовательскую модель таблицы (Mytablemodel), которая расширяет модель таблицы по умолчанию. Моя таблица состоит из пяти строк и четырех столбцов, где пользователь может нажать addrow кнопка, чтобы добавить больше строк

Все в моем коде работает нормально, кроме addrow кнопка, которая ничего не делает. Я буду признателен за любую помощь.

public class AddingNewRows extends JFrame {
JTable mytable;
JButton addrow;
String[] columns={"Admission number","Name","School","Year"};
TableColumn tc;
int defaultrows=5;
int rows=new Mytablemodel().getRowCount(),columnscount=new Mytablemodel().getColumnCount();
List data=new ArrayList();
Mytablemodel mytbm;
//
public AddingNewRows(){
super("adding rows");
for(int initialrows=0; initialrows<5; initialrows++){
   String[] items={"1","2","3","4"};
 data.add(items);
}
mytbm=new Mytablemodel();
mytable=new JTable(mytbm);

JScrollPane scroll=new JScrollPane(mytable);
addrow=new JButton("ADD ROW");
//
JPanel buttonpanel=new JPanel();
buttonpanel.setLayout(new BoxLayout(buttonpanel,BoxLayout.X_AXIS));
buttonpanel.setAlignmentX(Component.RIGHT_ALIGNMENT);
buttonpanel.add(addrow);

//
add(scroll,BorderLayout.CENTER);
add(buttonpanel,BorderLayout.SOUTH);

addrow.addActionListener(new Myactions());

}
public class Mytablemodel extends DefaultTableModel{

@Override
public String getColumnName(int column) {
    return columns[column];
}
@Override
public Object getValueAt(int row, int col){
 return ((String[])data.get(row))[col]; 
}
@Override
public boolean isCellEditable(int row, int col){
  return true;
}
@Override
public void setValueAt(Object value,int row, int col){
  ((Object[])data.get(row))[col]=value;
  fireTableCellUpdated(row,col);

}
@Override
public Class getColumnClass(int column){
  return getValueAt(0,column).getClass();
}  
@Override
public int getColumnCount(){
  return columns.length;
}

@Override
public int getRowCount(){
  return increaserows; 
}

@Override
public void addRow(Object[] mynewdata){
  int rownum=data.size();
  System.out.println(rownum);
  data.add(madata);
fireTableRowsInserted(rownum,rownum);
}

}
//
private class Myactions implements ActionListener{

@Override
public void actionPerformed(ActionEvent event){
 if(event.getSource()==addrow){ 
   Object[]newdata={"","","",""};
    mytbm.addRow(newdata);  
 } 
} 
}
public static void main(String[] args) {

 AddingNewRows frame=new AddingNewRows();
 frame.setVisible(true);
    frame.setSize(400,400);
    frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);

}

}

2 ответа

Некоторые заметки о вашем коде:

  • Вы никогда не должны звонить ни одному из fireXxx() методы явно извне. Они предназначены для внутреннего вызова AbstractTableModel подклассы при необходимости. Примечание: ИМХО те должны быть protected и не public, чтобы не использовать их неправильно. Но по какой-то причине они сделали их публичными.

  • Ваш addrow Кнопка, кажется, создает новую табличную модель, которая не привязана ни к одному JTable, так что это не имеет смысла. Ваша модель стола должна обеспечивать addRow(...) метод для того, чтобы добавить новую строку к нему. Скорее всего, вам придется увеличивать двумерный массив, который является базовой структурой данных модели таблицы, каждый раз, когда добавляется строка.

  • Как уже предположил @AndrewThompson, DefaultTableModel, кажется, хорошо подходит для того, что делает ваша табличная модель.

  • Проверьте rows а также columnscount инициализация свойств. Это не кажется мне правильным.

С другой стороны, вы говорите в комментарии:

У меня проблемы с пониманием fireTableRowsInserted(int,int) метод. сами параметры и где или когда вызывать метод

Этот метод должен вызываться в addRow(...) что я предложил вам создать во втором пункте. Этот метод должен расширить структуру данных и уведомить TableModelListeners что новая строка / ы были / были вставлены. Параметры - это первый и последний индексы соответственно. Как правило, когда вы добавляете новую единственную строку в конец табличной модели, то первый и последний индексы совпадают, а новый размер - 1 базовой структуры данных. Конечно, несколько строк могут быть вставлены и не обязательно в конце табличной модели, поэтому вы должны выяснить соответствующие индексы. Смотрите пример, показанный здесь, который использует List пользовательских объектов как структура данных.

Согласно вашему вопросу, вы хотите добавлять новые строки каждый раз, когда пользователь нажимает addrow кнопка. Достигните своей цели, используя DefaultTableModel, не создавая свой собственный или переопределяя addrow метод. в моем примере ниже параметры в конструкторе DefaultTableModel представляют начальные строки (5) и столбцы (4), которые будут в таблице, где после выполнения пользователь может добавить дополнительные строки, нажав addrow кнопка.

public class AddingNewRows extends JFrame {
 DefaultTableModel def;
JTable mytable;
JButton addrow;
//
public AddingNewRows(){
super("adding rows");

def=new DefaultTableModel(5,4);
mytable=new JTable(def);

JScrollPane scroll=new JScrollPane(mytable);
addrow=new JButton("ADD ROW");
//
JPanel buttonpanel=new JPanel();
buttonpanel.setLayout(new BoxLayout(buttonpanel,BoxLayout.X_AXIS));
buttonpanel.add(addrow);

//
add(scroll,BorderLayout.CENTER);
add(buttonpanel,BorderLayout.SOUTH);

addrow.addActionListener(new Myactions());

}

private class Myactions implements ActionListener{

@Override
public void actionPerformed(ActionEvent event){
if(event.getSource()==addrow){ 
Object[]newdata={"","","",""};
def.addRow(newdata);
} 
} 
}
public static void main(String[] args) {
AddingNewRows frame=new AddingNewRows();
frame.setVisible(true);
frame.setSize(400,400);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);

}

}
Другие вопросы по тегам