Java 如何使用自定义表模型将新行插入JTable?

Java 如何使用自定义表模型将新行插入JTable?,java,swing,jtable,tablemodel,abstracttablemodel,Java,Swing,Jtable,Tablemodel,Abstracttablemodel,我正在做一个小项目,涉及JTable,它要求用户单击一个按钮并向表中添加一行(我将该按钮命名为addrow)。我使用了一个自定义表模型(Mytablemodel),它扩展了默认表模型。 我的表首先由五行和四列组成,之后用户可以单击addrow按钮添加更多行 我的代码中的所有内容都可以正常工作,除了addrow按钮什么都不做。我将感谢任何帮助 public class AddingNewRows extends JFrame { JTable mytable; JButton addrow; St

我正在做一个小项目,涉及
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);

}

}
public类AddingNewRows扩展JFrame{
JTable-mytable;
JButton-addrow;
String[]列={“入学编号”、“姓名”、“学校”、“年份”};
表列tc;
int defaultrows=5;
int rows=new Mytablemodel().getRowCount(),columnscount=new Mytablemodel().getColumnCount();
列表数据=新的ArrayList();
mytbm模型;
//
公共添加新行(){
超级(“添加行”);

对于(int initialrows=0;initialrows关于代码的一些注释:

  • 您永远不应该从 外部。这些将由内部调用
    AbstractTableModel
    子类(如果需要)。注意:这些子类应该是什么 受到
    保护
    而不是
    公开
    ,以避免错误地使用它们。但是 出于某种原因,他们把它们公之于众

  • 您的
    addrow
    按钮似乎创建了一个新的表模型,但该模型不可用 附加到任何JTable,因此它没有任何意义。您的表模型应该 提供一个
    addRow(…)
    方法,以便向其中添加新行。大多数 很可能您必须放大二维数组,该数组是 每当添加一行时,表模型的underlyinig数据结构

  • 正如@AndrewThompson已经指出的那样,似乎 很适合做您的表格模型所做的工作

  • 检查
    属性初始化。它不会 对我来说似乎是对的

另一方面,你在评论中说:

我无法理解
fireTableRowsInserted(int,int)
方法。参数本身和 在何处或何时调用该方法


应该在
addRow(…)中调用此方法
我建议您在第二点中创建的。此方法应扩大数据结构,并通知
TableModelListeners
已插入新行。参数分别是第一个索引和最后一个索引。特别是在将新行附加到表模型末尾时,第一行和第二行nd last索引相同,并且基础数据结构的新大小为-1。当然,可以插入几行,但不一定在表模型的末尾,因此您必须找出适当的索引。请参见所示示例,该示例使用自定义对象的列表作为数据结构。

,您希望在用户每次单击
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);

}

}

所有小写字母输入的单词都很难阅读,就像试图听别人喃喃自语一样。请在句子开头使用大写字母作为单词I,并使用诸如
ArrayList
或Oracle之类的专有名称。
Mytablemodel扩展了AbstractTableModel{
帮你自己一个忙,改为扩展
DefaultTableModel
。它可以为你做这类事情。但是为了更快地获得更好的帮助,请发布一个(最小完整的可验证示例)或(简短、自含、正确的示例)。嗯,发布一个MCVE。。硬编码一些数据以替换数据库。@gikarasojokinene`我认为我不能使用DefaultTableModel将数据保存到数据库中。`你为什么这么认为?模型只存储数据。你的模型没有任何数据库专用代码。你的模型只有一个getValueAt(…)方法,该方法也可以在任何TableModel中找到。`I在理解fireTableRowsInserted(int,int)时遇到问题方法`并且DefaultTableModel已经为您执行了此操作,因此您无需执行任何操作。因此,也无需基于当前模型的功能创建自定义TableModel。您缺少使用DefaultTableModel的要点。它已经实现了一个
addRow(…)
method。您无需创建自己的方法。它还实现了getColumnNames()、getValueAt()和setValueAt()等方法因此也不需要实现这些方法。只需使用默认功能,仅在需要更改默认行为时覆盖方法。19当您谈到第一个和最后一个索引时,您的确切意思是什么?例如,我有5行,当我要添加第6行时,我会说fireTableRowsUpdated(6,6)?在这种情况下,您应该调用
fireTableRowsInserted(5,5)
,因为Java中的索引从0开始计数(索引5是第6行)。注意,我已通知插入的行(未更新)因为您实际上想添加一个新行。@gikarasojokinenetherefore第一个索引表示插入的行,第二个索引表示该行应具有的列。对吗?不对,两个索引分别表示第一行和最后一行(您可以添加多行)。例如,假设您有5行,添加了3行。假设您将所有新行追加到数据结构的末尾,则必须调用
fireTableRowsInserted(5,7)
,因为添加的第一行是第6行(索引==5),最后一行是第8行(索引==7)。请务必仔细阅读以了解更多详细信息。@gikarasojokinethis