I have created a JTable
with some information about formula 1 racing car drivers. The below code is for the JTable
import java.awt.LayoutManager;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import java.awt.event.*;
public class Test1 extends JFrame implements ActionListener {
JButton button;
Test1() {
//setBounds(100, 100, 500, 400);
JFrame frame = new JFrame();
button = new JButton();
//button.setBounds(50, 50, 20, 10);s
button.setText("Random Race");
button.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTable table = new JTable(new Model1Data());
frame.setBounds(100, 100, 500, 400);
JPanel panel = new JPanel();
frame.add(panel);
panel.add(new JScrollPane(table));
panel.add(button);
//add(new J
frame.setVisible(true);
//this.add(button);
pack();
}
@Override
public void actionPerformed(ActionEvent e) {
Formula1ChampionsManager d= new Formula1ChampionsManager();
d.button();
}
}
This is the code for the Model1Data
. This is the code for the table to update its cells.
import javax.swing.table.AbstractTableModel;
public class Model1Data extends AbstractTableModel implements ChampionsManager {
String colNames[] = { "Name", "Team", "No of first Places", "Total Points" };
Class<?> colClasses[] = { String.class, String.class, Integer.class, Integer.class };
public int getRowCount() {
return myDrivers.size();
}
public int getColumnCount() {
return colNames.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0) {
return myDrivers.get(rowIndex).getName();
}
if (columnIndex == 1) {
return myDrivers.get(rowIndex).getTeam();
}
if (columnIndex == 2) {
return myDrivers.get(rowIndex).getfirstPlace();
}
if (columnIndex == 3) {
return myDrivers.get(rowIndex).totalPoints();
}
return null;
}
public String getColumnName(int columnIndex) {
return colNames[columnIndex];
}
public Class<?> getColumnClass(int columnIndex) {
return colClasses[columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex == 0) {
myDrivers.get(rowIndex).setName((String) aValue);
}
if (columnIndex == 1) {
myDrivers.get(rowIndex).setTeam((String) aValue);
}
if (columnIndex == 2) {
myDrivers.get(rowIndex).setfirstPlace((Integer) aValue);
}
if (columnIndex == 3) {
myDrivers.get(rowIndex).settotalPoints((Integer) aValue);
}
//fireTableCellUpdated(rowIndex, columnIndex);
}
}
This what the table GUI looks like Table GUI. When I click the button the values for No of first places and Total Points are changed randomly. But the table doesn't get updated with the values. If I pull on the side of the frame it gets updated. How do I get it to update when I click the button?
CodePudding user response:
Looking at the docs ,
I think table.updateUI();
would work suitably to your requirements.
CodePudding user response:
The JTable
listens for changes in the TableModel
. Hence class AbstractTableModel
has methods such as fireTableCellUpdated(rowIndex, columnIndex)
(which you commented out in your code - why?). If you override method setValueAt
then you need to call that method, otherwise the JTable
will not update when its data is changed. I'm guessing that changing the size of the JFrame
causes a repaint of the JTable
which causes the JTable
to reload the data from its model (but I could be wrong).
Your class Model1Data
should extend DefaultTableModel, rather than AbstractTableModel
, since that class already contains all the functionality you require. The only method that class Model1Data
needs to override is getColumnClass (which it already does). You also need to override at least one constructor. Since you didn't post a minimal, reproducible example, I'm guessing that this constructor may be appropriate. Hence the code for class Model1Data
should be:
public class Model1Data extends javax.swing.table.DefaultTableModel {
Class<?> colClasses[] = { String.class, String.class, Integer.class, Integer.class };
public Model1Data(Object[] columnNames, int rowCount) {
super(columnNames, rowCount);
}
public Class<?> getColumnClass(int columnIndex) {
return colClasses[columnIndex];
}
}
And in class Test1
(which does not need to extend JFrame
, by the way) you can create the JTable like so:
JTable table = new JTable(new Model1Data(new String[]{ "Name", "Team", "No of first Places", "Total Points" }, 0));