Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JTable无法正确返回所选行_Java_User Interface_Jtable_Selection - Fatal编程技术网

Java JTable无法正确返回所选行

Java JTable无法正确返回所选行,java,user-interface,jtable,selection,Java,User Interface,Jtable,Selection,我正在使用DefaultTableModel的扩展,如下所示: 这是更新后的新AchievementAttableModel,以反映一些答案的输入 public AchievementTableModel(Object[][] c, Object[] co) { super(c,co); } public boolean isCellEditable(int r, int c) {return false;} public void replace(Object[][] c, Objec

我正在使用DefaultTableModel的扩展,如下所示:

这是更新后的新AchievementAttableModel,以反映一些答案的输入

public AchievementTableModel(Object[][] c, Object[] co) {
    super(c,co);
}
public boolean isCellEditable(int r, int c) {return false;}
public void replace(Object[][] c, Object[] co) {
    setDataVector(convertToVector(c), convertToVector(co));
    fireTableDataChanged();
}
我的GUI是一个JTable,具有以下属性:

if(table==null)
    table = new JTable(model);
else
    table.setModel(model);
table.setFillsViewportHeight(true);
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
table.getTableHeader().setReorderingAllowed(false);
table.getTableHeader().setResizingAllowed(false);
table.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
table.getColumnModel().setColumnSelectionAllowed(false);
我有一个JComboBox,用于选择要显示的数据。通过调用model.replace(单元格)更新TableModel,然后再次运行上述表格创建代码

在GUI JTable中选择一行并打印table.getSelectedRow()值时,在使用model.replace(cells)调用从第一个选择更改表数据后,我总是得到-1,即使我重新选择了第一个JComboBox选项。有什么我不知道的原因吗?我应该更改一些代码吗

编辑:在试图回答这个问题的过程中,代码发生了很大的变化,下面是更新后的代码。新的成就问题模型如上图所示

这将设置要在滚动窗格中正确查看和显示的模型和表格

if(model==null)
    model = new AchievementTableModel(cells, columns);
else
    model.replace(cells, columns);
if(table==null) {
    table = new JTable(model);
    table.setFillsViewportHeight(true);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.getTableHeader().setReorderingAllowed(false);
    table.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
    table.getColumnModel().setColumnSelectionAllowed(false);
    table.getTableHeader().setResizingAllowed(false);
} else
    table.setModel(model);

column = table.getColumn(columns[0]);
column.setPreferredWidth(25);
column = table.getColumn(columns[1]);
column.setPreferredWidth(225);
column = table.getColumn(columns[2]);
column.setPreferredWidth(40);
table.doLayout();

add(new JScrollPane(table), BorderLayout.CENTER);

重新排序JTable时,需要跟踪TableModel中数据的原始索引,而不是JTable上的当前索引。从视觉上看,表可能已经移动,但基础数据模型没有移动。

重新排序JTable时,需要跟踪TableModel中数据的原始索引,而不是JTable上的当前索引。从视觉上看,表可能已经移动,但基础数据模型没有移动。

当它交换数据并删除选择时(因为索引现在不同),您需要重新计算选择并以编程方式进行设置


我要指出的是,根据我的经验,这就是为什么我倾向于扩展
AbstractTableModel
,或者直接实现我自己的
TableModel
接口的原因。在这里修改备份数据引用总是会导致大量问题。

当它交换数据并删除选择时(因为索引现在不同),您需要重新计算选择并以编程方式进行设置


我要指出的是,根据我的经验,这就是为什么我倾向于扩展
AbstractTableModel
,或者直接实现我自己的
TableModel
接口的原因。在这里修改备份数据引用总是会导致大量问题。

听起来像是更改选择丢失了

在“更改模型”之前,“getSelectedRow()”是否返回任何内容

如果是这样,则保持该索引,更改模型,然后再次设置该索引


可能您需要使用一个自定义设置,当更改选择丢失时听起来像是这样

在“更改模型”之前,“getSelectedRow()”是否返回任何内容

如果是这样,则保持该索引,更改模型,然后再次设置该索引


可能您需要为此使用自定义表

在调用replace之后,不应使用新的JTable重新初始化表。fireTableDataChanged()方法将提醒您的现有表应该重新绘制。发生的情况是,您正在查看放入面板中的表,但您正在将变量更改为JTable的另一个实例。当您查询新的但不可见的表时,所选行数的值将为-1。如果您编辑您的帖子以显示代码中该区域的情况,这可能会有所帮助

第二次编辑:

与此相反:

  if(model==null)
    model = new AchievementTableModel(cells, columns);
  else
    model.replace(cells, columns);
  if(table==null) {
    table = new JTable(model);
    table.setFillsViewportHeight(true);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.getTableHeader().setReorderingAllowed(false);
    table.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
    table.getColumnModel().setColumnSelectionAllowed(false);
    table.getTableHeader().setResizingAllowed(false);
  } else
    table.setModel(model);

  column = table.getColumn(columns[0]);
  column.setPreferredWidth(25);
  column = table.getColumn(columns[1]);
  column.setPreferredWidth(225);
  column = table.getColumn(columns[2]);
  column.setPreferredWidth(40);
  table.doLayout();

  add(new JScrollPane(table), BorderLayout.CENTER);
改为这样做:

 if(model==null) {
    model = new AchievementTableModel(cells, columns);
 } else {
    model.setDataVector(cells, columns);
 }
 if(table==null) {
    table = new JTable(model);
    table.setFillsViewportHeight(true);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.getTableHeader().setReorderingAllowed(false);
    table.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
    table.getColumnModel().setColumnSelectionAllowed(false);
    table.getTableHeader().setResizingAllowed(false);

    column = table.getColumn(columns[0]);
    column.setPreferredWidth(25);
    column = table.getColumn(columns[1]);
    column.setPreferredWidth(225);
    column = table.getColumn(columns[2]);
    column.setPreferredWidth(40);
    table.doLayout();

    add(new JScrollPane(table), BorderLayout.CENTER);
   } else {
    table.setModel(model);
   }

您无需将表格添加到新的滚动窗格中,并在每次型号更改时将其重新添加到面板中。

在调用“替换”后,您不应使用新的JTable重新初始化表格。fireTableDataChanged()方法将提醒您的现有表应该重新绘制。发生的情况是,您正在查看放入面板中的表,但您正在将变量更改为JTable的另一个实例。当您查询新的但不可见的表时,所选行数的值将为-1。如果您编辑您的帖子以显示代码中该区域的情况,这可能会有所帮助

第二次编辑:

与此相反:

  if(model==null)
    model = new AchievementTableModel(cells, columns);
  else
    model.replace(cells, columns);
  if(table==null) {
    table = new JTable(model);
    table.setFillsViewportHeight(true);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.getTableHeader().setReorderingAllowed(false);
    table.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
    table.getColumnModel().setColumnSelectionAllowed(false);
    table.getTableHeader().setResizingAllowed(false);
  } else
    table.setModel(model);

  column = table.getColumn(columns[0]);
  column.setPreferredWidth(25);
  column = table.getColumn(columns[1]);
  column.setPreferredWidth(225);
  column = table.getColumn(columns[2]);
  column.setPreferredWidth(40);
  table.doLayout();

  add(new JScrollPane(table), BorderLayout.CENTER);
改为这样做:

 if(model==null) {
    model = new AchievementTableModel(cells, columns);
 } else {
    model.setDataVector(cells, columns);
 }
 if(table==null) {
    table = new JTable(model);
    table.setFillsViewportHeight(true);
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.getTableHeader().setReorderingAllowed(false);
    table.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
    table.getColumnModel().setColumnSelectionAllowed(false);
    table.getTableHeader().setResizingAllowed(false);

    column = table.getColumn(columns[0]);
    column.setPreferredWidth(25);
    column = table.getColumn(columns[1]);
    column.setPreferredWidth(225);
    column = table.getColumn(columns[2]);
    column.setPreferredWidth(40);
    table.doLayout();

    add(new JScrollPane(table), BorderLayout.CENTER);
   } else {
    table.setModel(model);
   }
您不需要将表格添加到新的滚动窗格中,并在每次型号更改时将其重新添加到面板中。

可以尝试使用

super.setDataVector(Vector dataVector,Vector ColumnNames)

来自JavaDoc

替换当前数据向量 使用新向量的实例变量 行,数据向量。每行都是 在数据向量中表示为向量 对象值的定义。列标识符 是新列的名称。这个 列标识符中的第一个名称是 映射到dataVector中的列0。每个 调整dataVector中的行以匹配 中的列数 列标识符可以通过截断 向量太长,或 如果太短,则添加空值。 请注意,为 dataVector导致未指定的错误 行为,可能是一个例外。 参数:dataVector-新数据 向量列标识符-名称 列的

也许可以尝试使用

super.setDataVector(Vector dataVector,Vector ColumnNames)

来自JavaDoc

替换当前数据向量 使用新向量的实例变量 行,数据向量。每行都是 在数据向量中表示为向量 对象值的定义。列标识符 是新列的名称。这个 列标识符中的第一个名称是 映射到dataVector中的列0。每个 调整dataVector中的行以匹配 中的列数 列标识符可以通过截断 向量太长,或 如果太短,则添加空值。 请注意,为 dataVector导致未指定的错误 行为,可能是一个例外。 参数:dataVector-新数据 向量列标识符-名称 列的


我想到的另一件事,
class AchievementTableModel extends DefaultTableModel {

    public AchievementTableModel(Object[][] c, Object[] co) {
        super.dataVector = super.convertToVector(c);
        super.columnIdentifiers = super.convertToVector(co);
    }
    public int getColumnCount() {return super.columnIdentifiers.size();}
    public int getRowCount() {return super.dataVector.size();}
    public String getColumnName(int c) {return (String)super.columnIdentifiers.get(c);}
    @SuppressWarnings("unchecked")
    public Object getValueAt(int r, int c) {return ((Vector<Object>)super.dataVector.get(r)).get(c);}
    public boolean isCellEditable(int r, int c) {return false;}
    public void replace(Object[][] c) {
        super.dataVector = super.convertToVector(c);
        super.fireTableDataChanged();
    }
}
final int selectedRowIndex = table.rowAtPoint(mouseEvent.getPoint());
final int modelRowIndex = table.convertRowIndexToModel(selectedRowIndex);