Fill JTable from JSON object

13,034

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));
            }
        });
    }
}

enter image description here

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));
    }
}

enter image description here

Share:
13,034
Cristine Angelena
Author by

Cristine Angelena

Updated on June 13, 2022

Comments

  • Cristine Angelena
    Cristine Angelena almost 2 years

    I have created the REST service successfully with accessing to the MS SQL database, and I am getting the JSON object as well, and also I have created the GUI for REST client in NetBeans normal java Application. Rather than client accessing to database and fetching data directly, what I want is to fill the JTable from the received JSON object. Your help really appreciate.

    client code is this. this is just to print it in console.

    public void getJSONEmployees() {
        try {
            Client cl = Client.create();
            WebResource webResource = cl
                    .resource("http://localhost:8080/rest_server/rest/jersey/dbAccess/getDBVal");
            ClientResponse response = webResource.accept("application/json")
                    .get(ClientResponse.class);
    
            if (response.getStatus() != 200) {
                System.out.println("no out put");
                throw new RuntimeException("Failed : HTTP error code : "
                        + response.getStatus());
            }
    
            String output = response.getEntity(String.class);
            // String[] output = response.getEntity(String.);
            System.out.println("\n -------");
            System.out.println(output);
    
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

    I want to load data in to that jTable after the button click event. From JSON key value pair, values i need to display in row wise.