I'm writing an app that reads a series of strings from a virtual COM port and then displays those strings in a table so the user can edit them and export back out the COM port. I am using Swing with JTable and DefaultTableModel. I can initialize the table OK and display dummy data, but am unable to use fireTableDataChanged() to update the table data with the values read from the serial port.
public class SwingMain extends JFrame {
...
private JScrollPane lensListScroller;
private JPanel listPane;
private static JTable workListTable;
private static DefaultTableModel workListModel;
private static String[] columnNames = {"Manufacturer", "Series", "Focal Length", "Status"};
static Object[][] lensTableData;
...
public SwingMain() {
...
// dummy data to populate the table at the beginning
Object[][] lensTableData = {{"Angenieux", "Optimo", "24-290mm", "Calibrated: F | Mylist: A"}};
DefaultTableModel workListModel = new DefaultTableModel(lensTableData, columnNames);
JTable workListTable = new JTable(workListModel);
// Scroll pane for Lens Work List
JScrollPane lensListScroller = new JScrollPane(workListTable);
JPanel listPane = new JPanel();
listPane.setLayout(new BoxLayout(listPane, BoxLayout.PAGE_AXIS));
JLabel label = new JLabel("Work List");
}
...
}
That all works fine for showing the table initially. I run into problems when I try to add the imported data to the DefaultTableModel workListModel
:
public class SwingMain extends JFrame {
...
private static void receiveLensData(String text) throws SerialPortException {
System.out.println("receiveLensData: " + text);
if (!isConnected) {
if (text.contains("Hand")) {
System.out.println("Hand detected");
timer.cancel();
}
}
else {
if (transfer) {
if (!startLensRx) {
...
lensTableData = new Object[numLenses][4];
} else {
if (text.contains(EOTStr)) {
System.out.println("EOT detected");
serialPort.writeBytes(ACK_SYN);
transfer = false;
startLensRx = false;
currentLens = 0;
progressBar.setVisible(false);
addLensesToWorkList(); // <-- calling the function to populate the table
} else {
System.out.println("Lens " + currentLens + " of " + numLenses + ": " + text);
lensArray.add(text);
progressBar.setValue(currentLens);
currentLens += 1;
serialPort.writeBytes(ACK);
}
}
}
}
}
private static void addLensesToWorkList() {
for (int i=0; i < lensArray.size(); i++) {
// add the imported string to the Object[][] that the table model was declared with
lensTableData[i] = parseLensLine(lensArray.get(i));
}
// after updating lensTableData, I want to tell the table model that the dataset has changed.
// But workListModel and workListTable always are null:
SwingUtilities.invokeLater(new Runnable(){public void run(){
workListModel.fireTableDataChanged(); // <-NullPointerException here
}});
}
}
I can tell that the Object[][] lensTableData
is getting populated correctly, but I'm unable to reference the table (workListTable
) or its model (workListModel
) since they always return null
when I try to reference them from within addLensesToWorkList()
method.
I imagine I'm just missing something in the initial declaration of the table and/or model. Or do I need to create a new table/model after importing the data and then add that table to my JScrollPane
? I'm new to Java dev for desktop. Thanks in advance for any advice :)