Dynamically updating jTable - java

My table will change the entire dataset during runtime.
My current code looks like below,
public class gui_test_form extends JFrame{
private JPanel rootpanel;
private JTable testTable;
private JScrollPane testScrollPane;
private JButton testButton;
private String[] columnNames = {"Name", "Color"};
private Object[][] data = { {"John", "Blue"}, {"Oliver", "Green"}, {"Paul", "Red"} };
public gui_test_form() {
super("GUI TEST");
setContentPane(rootpanel);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
testButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent actionEvent) { // Button Clicked
//Get new values
data[0][0] = "New Value";
//Update table
testTable.setModel(new DefaultTableModel(data, columnNames));
}
});
}
}
The code works as I expected. But I don't think making a new DefaultTableModel everytime is the best way to go. What should I be doing?
I looked briefly into fireTableChanged() method for AbstractTableModel, but couldn't make it work. I expected it would work since DefaultTableModel is inherited from AbstractTableModel.
Any help is appreciated.
-------Edit-------
Forgive me if I wasn't clearer before, but the problem is that I want to update the whole dataset. Even the Column names and the number of columns and rows are going to change.
For example, in the above code I could do this, and it would still work as you'd expect.
//Get new values
columnNames = new String[]{"Country", "Location", "Latitudes"};
data = new Object[][]{ {"John", "Blue", "1"}, {"Oliver", "Green", "4"}};
//Update table

You should be declaring a single table model at the same level where you create your JTable and making changes to that table model as required, rather than declaring it in the event handler.
private JPanel rootpanel;
private JTable testTable;
private DefaultTableModel tableModel;
private JScrollPane testScrollPane;
private JButton testButton;
tableModel = new DefaultTableModel();
testTable = new JTable(tableModel);
Take a look at the Java Tutorial. Pay attention to the section on listening for table data changes
If you come up with your own table model, you need to be sure to fully implement all overridden methods, particularly setValueAt(), and make sure you keep track of your row count properly. One of the most common mistakes involves forgetting to increment your row count after adding data and thinking that the table model is not receiving data.

Add below code in wherever you want to update the model.
model.addRow(new Object[]{txt_title.getText(), txt_name.getText()});
Before, The model and table must also be predefined globally.
DefaultTableModel model = new DefaultTableModel();

Related

Updating the current JTable model

Is there a way to update the current DefaultTableModel on a JTable? To clarify what I mean I will use some code examples below.
You might declare a JTable like this
DefaultTableModel model = new DefaultTableModel(tableData, tableHeaders)
{
private static final long serialVersionUID = 8785594035471551113L;
#Override
public boolean isCellEditable(int row, int column)
{
return false;
}
};
JTable table = new JTable(model);
panel.add(table);
I am asking if there is a way to do something similar to this
myTable.java
public class myTable extends JTable {
private static final long serialVersionUID = -5819940358496590055L;
public myTable(TableModel dM) {
setModel(dM);
}
public myTable(Object[][] tableData, Object[] columnHeaders) {
this(new DefaultTableModel(tableData, columnHeaders));
}
public void setEditable(boolean b) {
DefaultTableModel model = (DefaultTableModel) this.getModel();
//Do some code here to make the editable or uneditable
setModel(model);
}
}
someJavaFile.java
JTable table = new myTable(tableData, tableHeaders);
table.setEditable(false);
panel.add(table);
I am not asking you to do this for me but I am asking you to aid me in finding a way to update the current DefaultTableModel.
I appreciate any help
Edit for clarification
I am trying to find a way to manipulate the current DefaultTableModel on a JTable for things such as whether the table is editable or not as there are no methods which support toggling whether the table is editable after the model has been made. There is only isCellEditable().
Why would this be useful?
This would be useful if you were wanting to manipulate the way the table worked with an ActionListener on a JButton or something similar
things such as whether the table is editable or not as there are no methods which support toggling whether the table is editable after the model has been made
You will need to provide a custom TableModel. You can build this functionality into the DefaultTableModel by extending the model and adding a couple of methods.
Or you can check out the Row Table Model.
Among other features it allows you to make the entire model editable or not. You can also control whether individual columns are editable or not.

Updating JTable on button click

I am working with a JTable with a Custom Table Model found here. I have updated my code with the suggestions provided in that post and have run into a new problem. The change I have made to my code was to inject an ArrayList<CompletedPlayer> into my JTable to avoid issues with threads. After doing that, the code to update my table by pressing a button has stopped working.
The code used to initialize the JTable is the following:
TableModel model = new PlayerTableModel(FileHandler.getCompletedPlayers());
JTable table = new JTable(model);
The code I used to update the JTable is the following:
JButton btnRefreshAllPlayers = new JButton("Refresh");
btnRefreshAllPlayers.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
PlayerTableModel model = (PlayerTableModel) table.getModel();
model.fireTableDataChanged();
}
});
I have also tried using repaint() but this does not work either. As of right now, the only way to get the JTable to update is to close and reopen the program. FileHandler has the ArrayList I am using for the JTable which increases in size as the user adds more players.
Why doesn't fireTableDataChanged() detect any changes?
I have searched on stackoverflow and a couple of people have said to use that method.
No, you should not call any fireTableXxx methods outside of the context of the TableModel itself, people suggesting otherwise are simply wrong and it will cause you issues in the future. From the looks of your code, nothing has changed. If you've updated the TableModel according to the answer provided in your previous question, then there is no relationship with the data in the model to the external source. You need to manually reload the data from the external source, create a new TableModel and apply it to the table
For example...
JButton btnRefreshAllPlayers = new JButton("Refresh");
btnRefreshAllPlayers.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
TableModel model = new PlayerTableModel(FileHandler.getCompletedPlayers());
table.setModel(model);
}
});
I have also tried setting a new model with the updated ArrayList and it worked but did not keep the table row widths I previously set.
This is a reasonable thing for the table to do, because it has no idea if the new model has the same properties/columns as the old, so it resets them.
You could walk the ColumnModel, storing the column widths in a List or Map before you apply the model and reapply the widths
Is there a proper way to update the JTable?
You could provide your TableModel with a refresh method, which could load the data itself and trigger a tableDataChanged event
public class PlayerTableModel extends AbstractTableModel {
private final List<PlayerSummary.Player> summaries;
public PlayerTableModel(List<PlayerSummary.Player> summaries) {
this.summaries = new ArrayList<PlayerSummary.Player>(summaries);
}
// Other TabelModel methods...
public void refresh() {
summaries = new ArrayList<>(FileHandler.getCompletedPlayers());
fireTableDataChanged();
}
}
Then you would need to call this method in your ActionListener...
PlayerTableModel model = (PlayerTableModel)table.getMode();
model.refresh();

Refreshing the java Jtable to show updated data

I am trying to refresh my Jtable shown in the UI whenever I query the mysql database. The idea was to show whatever new data updated in the UI JTable.
The UI class is below.
public class DBView {
private JFrame frame = new JFrame();
private JScrollPane tableScrollPane = new JScrollPane();
private DefaultTableModel dbTable = new DefaultTableModel();
public void setDbTable(DefaultTableModel dbTable) {
this.dbTable = dbTable;
//this.dbTable.repaint();
paintDBTable();
}
public DefaultTableModel getDbTable() {
return dbTable;
}
public DBView() {
initializeFrame();
paintDBTable();
}
private void paintDBTable() {
tableScrollPane.setBounds(20, 350, 400, 80);
frame.getContentPane().add(tableScrollPane);
JTable DBTable = new JTable(dbTable);
tableScrollPane.add(DBTable);
DBTable.setFillsViewportHeight(true);
tableScrollPane.setViewportView(DBTable);
}
/**
* Initialize the contents of the frame.
*/
private void initializeFrame() {
frame.setVisible(true);
frame.setBounds(100, 100, 451, 525);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.setTitle("MySQL Database");
}
From another Model class I am calling the setDbTable() method. I input a new Jtable object to the setDbTable() method with data read from the database input into the new Jtable object.
The issue is inside the setDbTable() method, I am using paintDBTable() method again.
I tried using dbTable.fireTableDataChanged() method to refresh the view, didnt work.
The way it is now, it is working. But using the setDbTable() method to refresh seems like a very inefficient way to do it.
Question is Do you see anyway I could use another method defined for use of refreshing Jtables?
P.S. I am very new to java and programming in general. Sorry if the code is messy and the question is unclear. I can give all the code if its helpful. I removed most of the methods and other classes in the original code to make the question clearer.
tableScrollPane.add(DBTable);
JScrollPane isn't designated as container, you have to add child to JViewport
there are two options
a) tableScrollPane = new JScrollPane(myTable);
b) tableScrollPane.setViewportView(myTable);
DefaultTableModel dbTable = new DefaultTableModel();
DefaultTableModel is model that hold value for presentations layer for the JTable
rename this local variable (that make the sence) to dbTableModel instead of dbTable
you have to create a JTables view, f.e. two basics options
a) JTable myTable = new JTable(dbTableModel)
b) myTable.setModel(dbTableModel)
dbTable.fireTableDataChanged() is implemented in DefaultTableModel and correctly, not reason to call this method, nor outside of models definition (class, void, interface that returns XxxTableModel)
more informations in linked Oracle tutorials, ... for working code examples in SSCCE / MCVE form too
refresh data for JTable by
removing all rows in dbTableModel.setRowsCount(0);, then add a new row(s) to dbTableModel.addXxx
re_creating dbTableModel, note then must be added back to JTable e.g. myTable.setModel(dbTableModel)
It is not so confusing to refresh the JTable data and refreshing the UI after that, because:
Swing components implemented MVC and Observer in a very fantastic way. That means whenever you change the data in TableModel, the UI will be notified and repainted as you wanted.
So you should change you code in a way that you keep the JTable variable not the TableModel variable in your class. After that in setDbTable call the setModel method of the JTable, it means:
public class DBView {
private JTable jtable = new JTable();
public void setDbTable(DefaultTableModel dbTable) {
this.jtable.setModel(dbTable);
//this.dbTable.repaint();
//paintDBTable();
}
.
.
.
}
Hope this would be helpful,
Good Luck.

What is the variable name of my JTable's model in NetBeans

Using the example TableFilterDemo, I'm trying to create a RowFilter in NetBeans, but I can't. I tried the code in JCreator; I need help.
I understand that I do not need to create class MyTableModel extends AbstractTableModel because I already manually did this in NetBeans GUI tools. Now, I face a problem in defining the model with RowSorter.
MyTableModel model = new MyTableModel();
sorter = new TableRowSorter<MyTableModel>(model);
table = new JTable(model);
table.setRowSorter(sorter);
table.setPreferredScrollableViewportSize(new Dimension(500, 70));
table.setFillsViewportHeight(true);
Above is the example, and I change it to this:
private TableRowSorter<javax.swing.table.DefaultTableModel> sorter;
/** Creates new form NewJFrame */
public NewJFrame() {
initComponents();
javax.swing.table.DefaultTableModel model = new DefaultTableModel();
sorter = new TableRowSorter<javax.swing.table.DefaultTableModel>(model);
JTable jTable = new JTable(model);
jTable.setRowSorter(sorter);
Is it correct? I can't get this to work. I suspect is the sorter is not added into the table. Which maybe because of defining model part. Please give advice.
I think it is not nessesary to you create your abstract table model .
you just use defaultModel and use following code
voterTable.getColumnModel().getColumn(0).setPreferredWidth(65);
I supposed you create the JTable in the GUI Builder. You have too add the model to this table and not to a new one you create.
Replace the method with :
public NewJFrame() {
javax.swing.table.DefaultTableModel model = new DefaultTableModel();
sorter = new TableRowSorter<javax.swing.table.DefaultTableModel>(model);
initComponents();
}
And add the rowsorter from the GUI Builder (will be added in initComponent()):
Right click on the JTable -> Properties -> Pane "Code"
In Custom Creation code write -> new JTable(model);
In Variable name you will see the variable name ([table_name] in following point)
In Post Creation Code write -> [table_name].setRowSorter(sorter);

How to display a 2D array in jTable?

I have a static 2D array called Status.Data[][] and a Column header called Status.Columns[].
I am using net beans and I want to be able to have the arrays populate the table.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jTable1.setColumnModel(new DefaultColumnModel(Status.Data, Status.Columns));
}
This throws an error that it is expecting a TableColumnModel.
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
jTable1.setColumnModel(new TableColumnModel(Status.Data, Status.Columns));
}
This says java.swing.table.TableColumnModel is abstract and cannot be instantiated.
I would even be happy if I could figure out how to make it display when the window is opened.
How do I populate my table?
You can create the table model and then pass it to the table constructor:
TableModel model = new DefaultTableModel(Status.Data, Status.Columns);
JTable table = new JTable(model);
use javax.swing.table.DefaultTableModel
DefaultTableModel(Object[][] data, Object[] columnNames)

Categories