从JSON对象填充JTable

时间:2014-08-21 03:59:57

标签: java json swing rest jtable

我已经成功创建了REST服务并访问了MS SQL数据库,我也获得了JSON对象, 我还在NetBeans普通java应用程序中为REST客户端创建了GUI。而不是客户端访问数据库和直接获取数据,我想要的是从收到的JSON对象填充JTable。 你的帮助真的很感激。

客户端代码是这样的。这只是在控制台中打印。

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

我想在按钮点击事件后将数据加载到该jTable。 从JSON键值对,我需要以行方式显示值。

2 个答案:

答案 0 :(得分:8)

IMO,处理此问题的最佳方法是使用像Jackson这样的库来进行json到对象映射(或数据绑定),并将json对象映射到常规java对象。然后只需使用自定义AbstractTableModel来保存这些对象的列表。您可以轻松地将对象属性映射到表模型的getValueAt()方法中的表列值。

例如

User课程

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 - (注意,这是最简单的情况。您可能需要添加一些方法来添加行和删除行等。您需要添加自己的功能。这里有很多好的帖子。你可能想要查看@MadProgrammer的个人资料并查看他的abstracttablemodel tagged answers或者只查看标签。

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课程 - 使用杰克逊的ObjectMapper课程。

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

以下是一些参考资料,您可以参考以获取更多信息:

  • How to use Tables: Creating a Table Model
  • Jackson Homepage
  • Jackson wiki with links to tutorials
  • 有关jackson-databind依赖关系,请参阅the GitHub。如果您正在使用maven,将其添加为依赖项,也会获取必要的jackson-corejackson-annotation依赖项。

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.3.3</version>
    </dependency>
    

    如果您没有使用maven,请务必同时下载jackson-corejackson-annotation。他们每个人都有自己的GitHub页面,必须链接到Maven Central Repo中的下载。

  • 看看Rob Camick的BeanTableModel。它的通用TableModel允许您从许多业务对象创建表格模型,因此您不必经历创建自己的业务对象的麻烦。

    < / LI>

<强>更新

这是一个在运行时动态添加用户的示例,它使用了addUser的{​​{1}}方法。输入&#34;用户json对象&#34;并点击添加用户

UserTableModel

<强>更新

  

&#34;它会将员工列表作为JSON数组返回&#34;

如果你有一个json数组,你可以使用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(); } }); } } 轻松地将其转换为Java List。您可以使用TypeFactory#constructCollectionTypeObjectMapper作为第二个参数传递给CollectionType。像

这样的东西
readValue

enter image description here

答案 1 :(得分:0)

Java8将添加JSON support to the J2SE,渲染杰克逊,GSON等,无关紧要。这并不是说他们不会被使用(毕竟很难摆脱惯性)。对于那些没有旧习惯或坏习惯或试图摆脱它们的人(我落入后一阵营),代码看起来像是:

private SomeCollectionProvider collections;

private JsonBuilderFactory builderFactory;

public JsonArray collectionToJsonArray() {
    return collections.createACollection()
            .stream()
            .map(myObject -> myObject.id) // field is public
            .collect(
                    builderFactory::createArrayBuilder,
                    (a, s) -> a.add(s),
                    (b1, b2) -> b1.add(b2))
            .build();
}