java 从 JSON 对象填充 JTable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25418029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 08:00:16  来源:igfitidea点击:

Fill JTable from JSON object

javajsonswingrestjtable

提问by Cristine Angelena

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 JTablefrom the received JSON object. Your help really appreciate.

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

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.

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

回答by Paul Samsotha

IMO, the best way to handle this is to use a library like Hymansonfor json-to-object-mapping (or data binding) and just map your json objects to a regular java object. Then just use a custom AbstractTableModelto 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..

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

For example

例如

Userclass

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

UserTableModelclass- (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 abstracttablemodeltagged answersor just check out the tag in general).

UserTableModel- (注意,这是最简单的情况。您可能想要添加一些方法来添加行和删除行等。您需要自己添加该功能。SO 上有很多好帖子。您可能想要浏览@MadProgrammer 的个人资料并查看他的abstracttablemodel标记答案,或者只是查看一般的标记)。

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

Mainclass- which uses the ObjectMapperclass from Hymanson.

Mainclass- 使用ObjectMapperHymanson的类。

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.Hymanson.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
  • Hymanson Homepage
  • Hymanson wiki with links to tutorials
  • See the GitHubfor the Hymanson-databinddependency. If you're using maven, add this as a dependency, will grab the necessary Hymanson-coreand Hymanson-annotationdependencies also.

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

    If you aren't using maven, make sure you download the Hymanson-coreand Hymanson-annotationalso. 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 TableModelthat 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.

  • 如何使用表:创建表模型
  • Hyman逊主页
  • 带有教程链接的 Hymanson wiki
  • GitHub的Hymanson-databind依赖。如果您使用的是 maven,请将其添加为依赖项,也将获取必要的Hymanson-coreHymanson-annotation依赖项。

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

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

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



UPDATE

更新

Here is an example that adds user dynamically at run time, making use of the addUsermethod of the UserTableModel. Type in a "User json object" and hit Add User

下面是在运行时动态地添加用户,利用所述的示例addUser的方法UserTableModel。输入“用户 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.Hymanson.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"

“它将以 JSON 数组的形式返回员工列表”

If you have a json array, you can easily convert that to a Java Listwith the ObjectMapper. You can pass a CollectionTypeas the second argument to the readValue, by using TypeFactory#constructCollectionType. Something like

如果你有一个JSON数组,你可以很容易地将其转换成一个JavaListObjectMapper。您可以使用 将 aCollectionType作为第二个参数传递给readValue, TypeFactory#constructCollectionType。就像是

import java.util.List;
import javax.swing.*;
import com.fasterxml.Hymanson.databind.ObjectMapper;
import com.fasterxml.Hymanson.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

在此处输入图片说明

回答by hd1

Java8 will add JSON support to the J2SE, rendering Hymanson, GSON, et al, extraneous. This isn't to say that they won't be used (inertia is difficult to get rid of after all). For those who don't have old, bad habits or are trying to get rid of them (I fall in the latter camp), the code looks something like:

Java8 将向J2SE添加JSON 支持,使 Hymanson、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();
}