IMO, the best way to handle this is to use a library like Jackson for json-to-object-mapping (or data binding) and just map your json objects to a regular java object. Then just use a custom AbstractTableModel
to hold a list of the those object. You can easily map the object attributes to table column values in the getValueAt()
method of your table model..
For example
User
class
public class User {
private String firstName;
private String lastName;
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
public void setLastName(String lastName) { this.lastName = lastName; }
}
UserTableModel
class - (Note, this is the simplest of cases. You may want to add some methods to add rows and remove rows and such. You will need to add that functionality your self. There are many good posts here on SO. You may want to go through @MadProgrammer's profile and check out his abstracttablemodel
tagged answers or just check out the tag in general).
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class UserTableModel extends AbstractTableModel {
private List<User> userData = new ArrayList<User>();
private String[] columnNames = {"First Name", "Last Name"};
public UserTableModel() {}
public UserTableModel(List<User> userData) {
this.userData = userData;
}
@Override
public String getColumnName(int column) {
return columnNames[column];
}
@Override
public int getColumnCount() {
return columnNames.length;
}
@Override
public int getRowCount() {
return userData.size();
}
@Override
public Object getValueAt(int row, int column) {
Object userAttribute = null;
User userObject = userData.get(row);
switch(column) {
case 0: userAttribute = userObject.getFirstName(); break;
case 1: userAttribute = userObject.getLastName(); break;
default: break;
}
return userAttribute;
}
public void addUser(User user) {
userData.add(user);
fireTableDataChanged();
}
}
Main
class - which uses the ObjectMapper
class from Jackson.
import java.awt.Dimension;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MainJsonToObjectDemo {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable(){
public void run() {
String jsonUser1 = "{ \"firstName\": \"Stack\", \"lastName\": \"Overflow\"}";
String jsonUser2 = "{ \"firstName\": \"Pee\", \"lastName\": \"Skillet\"}";
ObjectMapper mapper = new ObjectMapper();
User user1 = null;
User user2 = null;
try {
user1 = mapper.readValue(jsonUser1, User.class);
user2 = mapper.readValue(jsonUser2, User.class);
} catch (IOException e) {
e.printStackTrace();
}
List<User> users = new ArrayList<User>();
users.add(user1);
users.add(user2);
UserTableModel model = new UserTableModel(users);
JTable table = new JTable(model) {
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(300, 100);
}
};
JOptionPane.showMessageDialog(null, new JScrollPane(table));
}
});
}
}

Here are some references you can go to for more information:
- How to use Tables: Creating a Table Model
- Jackson Homepage
- Jackson wiki with links to tutorials
See the GitHub for the jackson-databind
dependency. If you're using maven, add this as a dependency, will grab the necessary jackson-core
and jackson-annotation
dependencies also.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.3</version>
</dependency>
If you aren't using maven, make sure you download the jackson-core
and jackson-annotation
also. They each have their own GitHub page that has to link to the download in the Maven Central Repo.
Have a look at Rob Camick's BeanTableModel
. It's generic TableModel
that will allow you to create a table model from many of your business objects, so you don't have to go through the hassle of creating your own.
UPDATE
Here is an example that adds user dynamically at run time, making use of the addUser
method of the UserTableModel
. Type in a "User json object" and hit Add User
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import com.fasterxml.jackson.databind.ObjectMapper;
public class MainJsonToObjectDemo {
private JTextArea areaToWriteJson = new JTextArea(6, 30);
private ObjectMapper objectMapper = new ObjectMapper();
private JButton addUserButton = getAddUserButton();
private JTable userTable = getUserTable(300, 150);
private JFrame frame = new JFrame("Json Objects JTable Demo");
public MainJsonToObjectDemo() {
initTableData();
frame.add(new JScrollPane(areaToWriteJson), BorderLayout.PAGE_START);
frame.add(addUserButton, BorderLayout.CENTER);
frame.add(new JScrollPane(userTable), BorderLayout.PAGE_END);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JTable getUserTable(final int width, final int height) {
UserTableModel model = new UserTableModel();
JTable table = new JTable(model) {
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(width, height);
}
};
return table;
}
private JButton getAddUserButton() {
JButton button = new JButton("Add User");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String json = areaToWriteJson.getText();
if (!json.isEmpty()) {
addUser(json);
}
}
});
return button;
}
private void addUser(String jsonString) {
User user = null;
try {
user = objectMapper.readValue(jsonString, User.class);
((UserTableModel) userTable.getModel()).addUser(user);
areaToWriteJson.setText("");
} catch (Exception e) {
JOptionPane.showMessageDialog(frame,
"Could not map text to User object. Check your formatting: \n"
+ "{\n"
+ " \"firstName\": \"<First>\",\n"
+ " \"lastName\": \"<Last>\"\n"
+ "}", "Error Mapping",
JOptionPane.ERROR_MESSAGE);
}
}
private void initTableData() {
String jsonUser1 = "{ \"firstName\": \"Stack\", \"lastName\": \"Overflow\"}";
String jsonUser2 = "{ \"firstName\": \"Pee\", \"lastName\": \"Skillet\"}";
addUser(jsonUser1);
addUser(jsonUser2);
}
public static void main(String[] args) throws Exception {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new MainJsonToObjectDemo();
}
});
}
}
UPDATE
"there it will return Employee List as a JSON Array"
If you have a json array, you can easily convert that to a Java List
with the ObjectMapper
. You can pass a CollectionType
as the second argument to the readValue
, by using TypeFactory#constructCollectionType
. Something like
import java.util.List;
import javax.swing.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.TypeFactory;
public class UserListDemo {
public static void main(String[] args) throws Exception {
String jsonUsers =
"["
+ "{ \"firstName\": \"Stack\", \"lastName\": \"Overflow\" },"
+ "{ \"firstName\": \"Pee\", \"lastName\": \"Skillet\" }"
+"]";
ObjectMapper mapper = new ObjectMapper();
List<User> users = mapper.readValue(
jsonUsers,
TypeFactory.defaultInstance().constructCollectionType(
List.class, User.class));
UserTableModel model = new UserTableModel(users);
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JOptionPane.showMessageDialog(null, new JScrollPane(table));
}
}
