更新JTable数据后,如何更新JTable显示?

时间:2015-07-31 15:07:06

标签: java jtable jframe

我创建了一个带有复选框和按钮的默认JTable。我试图能够在另一个窗口关闭时更新/刷新表但是无法实现这一点(因为窗口保持静态)。 JFrame和JTable的构造函数如下:

public MedDetailsTable() {

    super("Medication Details");                                 // Container title
    setSize(1000, 350);                                              // Container size
    Container contentPane = getContentPane();                       // Used to determine layout of components

    lbl1.setText("Medication Owner: " + MedicationManager.medsowner);
    MedicationManager.meds1.deleteTableArray();                       // Remove any previous elements from array
    int medsno = MedicationManager.meds1.getMedsNumber();             // Retrieve number of medications in medications array
    MedicationManager.meds1.addArrayOutputs(medsno);                  // Create table output array
    int arraysize = MedicationManager.meds1.getTableNumber();         // Table output array size

    Object[][] rowData = new Object[medsno][9];                        // print array in rectangular form 8 columns wide with rows = meds number        
    for (r = 0; r < rowData.length; r++) {

    rowData[r][0] = MedicationManager.meds1.getTableArray((r * 6));             // Med details are retrieved from TableArray  
    rowData[r][1] = MedicationManager.meds1.getTableArray((r * 6) + 1);         // * by no of columns, plus offset for initial column
    rowData[r][2] = MedicationManager.meds1.getTableArray((r * 6) + 2);
    rowData[r][3] = MedicationManager.meds1.getTableArray((r * 6) + 3);
    rowData[r][4] = MedicationManager.meds1.getTableArray((r * 6) + 4);
    rowData[r][5] = MedicationManager.meds1.getTableArray((r * 6) + 5);
    rowData[r][6] = MedicationManager.meds1.getCheckbox(r);                    // Data for checkbox which will initialise as empty = false
    final JButton button = new JButton("Meds Info");
         button.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {                     // If button pressed
    int selectedRowIndex = MedicationManager.listTable.getSelectedRow();       // Get column 0 row x selected text
    String selectedObject = (String) MedicationManager.listTable.getModel().getValueAt(selectedRowIndex, 0);
             InternetSearch IS = new InternetSearch(selectedObject);                    // Internet search with drug name
                        }
                    });
         rowData[r][7] = button;                                                // Med details button added
    }

    MedicationManager.listTableModel = new DefaultTableModel(rowData, columnNames) {

        @Override
        public Class<?> getColumnClass(int columnIndex) // get columnClass overridden so boolean column class is returned to produce Checkbox
        {
            return columnClass[columnIndex];
        }
    };


    MedicationManager.listTable = new JTable(MedicationManager.listTableModel);
   MedicationManager.listTable = new JTable(new JTableModel()); 

    // Assign table model
    MedicationManager.listTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);                // Set up column widths
    MedicationManager.listTable.getColumnModel().getColumn(0).setPreferredWidth(180);
    MedicationManager.listTable.getColumnModel().getColumn(1).setPreferredWidth(100);
    MedicationManager.listTable.getColumnModel().getColumn(2).setPreferredWidth(100);
    MedicationManager.listTable.getColumnModel().getColumn(3).setPreferredWidth(150);
    MedicationManager.listTable.getColumnModel().getColumn(4).setPreferredWidth(110);
    MedicationManager.listTable.getColumnModel().getColumn(5).setPreferredWidth(100);
    MedicationManager.listTable.getColumnModel().getColumn(6).setPreferredWidth(50);
    MedicationManager.listTable.getColumnModel().getColumn(7).setPreferredWidth(100);
    MedicationManager.listTable.getColumnModel().getColumn(8).setPreferredWidth(100);
    JScrollPane pane2 = new JScrollPane(MedicationManager.listTable);

    pane2.setPreferredSize(new Dimension(930, 200));

    setDefaultCloseOperation(DISPOSE_ON_CLOSE);                        // Disposes on closing window

    pane2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

    pnl2.add(lbl1);
    Dimension d = new Dimension(70, 30);                                 // Set dimensions for buttons 
    add.setPreferredSize(d);
    chartb.setPreferredSize(d);
    edit.setPreferredSize(d);
    delete.setPreferredSize(d);
    b1.setPreferredSize(d);
    pnl.add(add);
    pnl.add(edit);
    pnl.add(delete);
    pnl.add(chartb);
    pnl.add(b1);
    pnl3.add(pane2);

    add(pnl2);
    add(pnl);
    add(pnl3);

    contentPane.add("North", pnl2);                                  // Set text fields at top
    contentPane.add("South", pnl);                                 // Set "OK" and "Cancel" at bottom 
    contentPane.add("Center", pnl3);

    add.addActionListener(this);
    chartb.addActionListener(this);
    edit.addActionListener(this);
    delete.addActionListener(this);
    b1.addActionListener(this);

    MedicationManager.listTable.getModel().addTableModelListener(this);

    DefaultTableCellRenderer centerRenderer = new DefaultTableCellRenderer();       // Set data to center of columns
    centerRenderer.setHorizontalAlignment(SwingConstants.CENTER);

    for (int n = 0; n < 6; n++) {                                                   // Renderer does not extend to column 7 so checkbox used instead
        MedicationManager.listTable.getColumnModel().getColumn(n).setCellRenderer(centerRenderer);
    }

    TableCellRenderer buttonRenderer = new JTableButtonRenderer();
    MedicationManager.listTable.getColumn("Information").setCellRenderer(buttonRenderer);
MedicationManager.listTable.addMouseListener(new JTableButtonMouseListener(MedicationManager.listTable));

    setLocationRelativeTo(null);                                    // Centre window in screen
    setVisible(true);                                               // Make JPanel visibleclass ButtonListener implements ActionListener {  

}

我用来更新数据的方法如下。首先删除行数据,然后将其重新填充到用于填充JTable的数组中。但我目前无法刷新数据显示。这是使用.repaint().fireTableDataChanged()。 :

public void addData(){

    MedicationManager.listTableModel = (DefaultTableModel)   MedicationManager.listTable.getModel();

    MedicationManager.listTableModel.setRowCount(0);

    int medsno = MedicationManager.meds1.getMedsNumber();             // Retrieve number of medications in medications array
    MedicationManager.meds1.addArrayOutputs(medsno);                  // Create table output array
    int arraysize = MedicationManager.meds1.getTableNumber();         // Table output array size

    Object[][] rowData = new Object[medsno][9];                        // print array in rectangular form 8 columns wide with rows = meds number        
    for (r = 0; r < rowData.length; r++) {                            
        rowData[r][0] = MedicationManager.meds1.getTableArray((r * 6));             // Med details are retrieved from TableArray  
        rowData[r][1] = MedicationManager.meds1.getTableArray((r * 6) + 1);         // * by no of columns, plus offset for initial column
        rowData[r][2] = MedicationManager.meds1.getTableArray((r * 6) + 2);
        rowData[r][3] = MedicationManager.meds1.getTableArray((r * 6) + 3);
        rowData[r][4] = MedicationManager.meds1.getTableArray((r * 6) + 4);
        rowData[r][5] = MedicationManager.meds1.getTableArray((r * 6) + 5);
        rowData[r][6] = MedicationManager.meds1.getCheckbox(r);
        final JButton button = new JButton("Meds Info");
         button.addActionListener(new ActionListener() {
                    public void actionPerformed(ActionEvent arg0) {                     // If button pressed
             int selectedRowIndex = MedicationManager.listTable.getSelectedRow();       // Get column 0 row x selected text
            String selectedObject = (String) MedicationManager.listTable.getModel().getValueAt(selectedRowIndex, 0);
             InternetSearch IS = new InternetSearch(selectedObject);                    // Internet search with drug name
                        }
                    });
         rowData[r][7] = button;                                                // Med details button added

        MedicationManager.listTableModel.addRow(rowData);
    } 

      MedicationManager.listTable.setModel(MedicationManager.listTableModel);

    MedicationManager.listTableModel.fireTableDataChanged();
    this.repaint();

}

2 个答案:

答案 0 :(得分:0)

MedicationManager.listTableModel.addRow(rowData);

The addRow(...) method is used to add a single row of data to the TableModel. The "rowData" variable is a 2Dimensional array. You should not be using a 2D array.

Instead you need to create a one dimensional array inside your for loop. Then you add data to the array. Then you add the Array to the TableModel.

Something like:

DefaultTableModel listTableModel = (DefaultTableModel)MedicationManager.listTable.getModel();
listTableModel.setRowCount(0);

for (every row)
{
    Object[] row = new Object[8];
    row[0] = ...
    row[1] = ...
    listTableModel.addRow( row );
}

So to refresh data in an existing JTable all you need is a reference to the original table:

  1. The MedicationManager references the table.
  2. You access the TableModel of the table.
  3. You remove the data from the TableModel
  4. You add one row of data back to the TableModel in each iteration of the loop

When you add the row to the TableModel, the model will notify the table of the change and the table will repaint itself.

Also, you can't just add a JButton to the TableModel. A JTable only uses renderers, to the actual button is not displayed in the table. You need to create a custom renderer and editor for the button. Check out Table Button Column for a solution.

答案 1 :(得分:0)

Since you are using the DefaultTableModel the only answer I can give is:

You should recreate your model with the new values and set it to the JTable.

And a tip: DON'T USE DEFAULTTABLEMODEL.