2

我可能不明白 fireTableStructureChanged() 方法的工作原理。我假设如果我调用该方法,则会调用实现的方法 getColumnCount()、getRows() 和 getValueAt(int row, int col),以便我的具有指定模型的表发生变化。

这是我的表模型

public class MyTableModel extends AbstractTableModel{
JComboBox box;
public MyTableModel(JComboBox choice){
    super();
    box = choice;
}

public void updateTable(){
    this.fireTableStructureChanged();
}

@Override
public int getColumnCount() {
    //implemented
}

@Override
public int getRowCount() {
    //implemented
}

@Override
public Object getValueAt(int row, int col) {
    //implemented
}

choice5 是一个 JComboBox

    table1 = new JTable(new MyTableModel(choice5));

当您从choice5中选择一个项目时

    ((MyTableModel)table1.getModel()).updateTable();

被调用(编辑:对于我可以选择的每个项目,我可能有一个不同的 jtable 我想显示)

会发生什么:我检查了 getColumnCount() 和 getRowCount() 确实被调用,但 getValueAt(...) 不是。尽管两种方法都返回(即)值 1,但 JTable 表 1(由于 0 行和 0 列而未显示)仍未显示。

我想要发生的事情:显然,我希望 table1 以正确的值显示(即一列一行)(由 getValueAt(...) 返回)。

为什么没有调用 getValueAt(...) 方法,因此(我相信)表格没有显示?一般来说,fireTableStructureChanged() 是如何工作的?

提前致谢。

编辑(SSCCE):

import java.awt.BorderLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTable;

public class TestTableModel extends JFrame {
 static JComboBox<String> choice5 = new JComboBox<String>(new String[]{"","1","2","3"});
 static JTable table1 = new JTable(new MyTableModel(choice5));
 static JFrame frame = new JFrame();

 public static void main(String[] args) {
    frame.setLayout(new BorderLayout());
    choice5.addItemListener(new ItemListener(){
        @Override
        public void itemStateChanged(ItemEvent e) {
            if(e.getStateChange() == ItemEvent.SELECTED) {
                ((MyTableModel)table1.getModel()).updateTable();
                frame.pack();
            }}});
    frame.add(BorderLayout.SOUTH, choice5);
    frame.add(BorderLayout.CENTER, table1);
    frame.pack();
    frame.setVisible(true);
    frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
}

我的表模型

import javax.swing.JComboBox;
import javax.swing.table.AbstractTableModel;
public class MyTableModel extends AbstractTableModel{
 JComboBox box;

public MyTableModel(JComboBox choice){
    super();
    box = choice;
}
public void updateTable(){this.fireTableStructureChanged();}

@Override
public int getColumnCount() {return box.getSelectedIndex();}
@Override
public int getRowCount() { return box.getSelectedIndex();}
@Override
public Object getValueAt(int row, int col) {return box.getSelectedItem();}
}
4

1 回答 1

0

表结构是行、列和列标题。 表格数据显示在单元格中。

  1. 尝试使用fireTableRowsUpdated

     public void updateTable(){this.fireTableRowsUpdated(0, this.getRowCount() - 1);}
    
  2. 尝试使用setModel并使用EventQueue确保您的代码在 UI 线程上执行:

     choice5.addItemListener(new ItemListener(){
         @Override
         public void itemStateChanged(ItemEvent e) {
             if(e.getStateChange() == ItemEvent.SELECTED) {
                 EventQueue.invokeLater(() -> {
                     table1.setModel(new MyTableModel(choice5));
                     frame.pack();
                 });
             }}});
    
  3. 试试你JTableJScrollPane。它们之间有魔法,就像巧克力花生酱

     frame.add(BorderLayout.SOUTH, choice5);
     frame.add(BorderLayout.CENTER, new JScrollPane(table1));
    

fireTableRowsUpdated

public void fireTableRowsUpdated(int firstRow, int lastRow)

通知所有侦听器 [firstRow, lastRow] 范围内的行(含)已更新。

参数:

  • firstRow - 第一行
  • lastRow - 最后一行

另请参阅 TableModelEventEventListenerList

资料来源: 甲骨文


fireTableStructureChanged

public void fireTableStructureChanged()

通知所有侦听器表的结构已更改。表中的列数,以及新列的名称和类型可能与之前的状态不同。如果 JTable 接收到这个事件并且它的 autoCreateColumnsFromModel 标志被设置,它会丢弃它拥有的所有表列,并按照它们在模型中出现的顺序重新分配默认列。这与在 JTable 上调用 setModel(TableModel) 相同。

另请参阅 TableModelEventEventListenerList

资料来源: 甲骨文

于 2020-08-25T06:18:21.193 回答