You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Vaadin框架为DAO类的JSON文本字段创建视图绑定器

Creating a Vaadin View Binder for Your JsonObject DAO Field

Alright, let's work through building a view binder that connects your DAO's JSON-storing field (backed by that JsonObject class) to Vaadin UI components. We'll cover both displaying the JSON data and setting up editable bindings, since Vaadin's data system works great for both use cases.

1. Build a Custom Component to Render JsonObject

Since your JsonObject can hold different data types (objects, arrays, strings, numbers, etc.), we'll make a reusable component that dynamically renders the right UI based on which field is populated.

import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.listbox.ListBox;
import java.util.Map;

public class JsonDisplayComponent extends VerticalLayout {
    public JsonDisplayComponent() {
        setSpacing(true);
        setPadding(true);
    }

    public void setJsonObject(JsonObject jsonObject) {
        // Clear existing components first
        removeAll();

        // Show raw JSON if available
        if (jsonObject.getOriginal() != null) {
            TextField originalField = new TextField("Raw JSON");
            originalField.setValue(jsonObject.getOriginal());
            originalField.setReadOnly(true);
            originalField.setWidthFull();
            add(originalField);
        }

        // Render based on the non-null field
        if (jsonObject.getJsonString() != null) {
            add(createLabeledField("String Value", jsonObject.getJsonString()));
        } else if (jsonObject.getJsonNumber() != null) {
            add(createLabeledField("Number Value", jsonObject.getJsonNumber().toString()));
        } else if (jsonObject.getJsonFloat() != null) {
            add(createLabeledField("Float Value", jsonObject.getJsonFloat().toString()));
        } else if (jsonObject.getJsonBoolean() != null) {
            add(createLabeledField("Boolean Value", jsonObject.getJsonBoolean().toString()));
        } else if (jsonObject.getJsonArray() != null) {
            ListBox<String> arrayList = new ListBox<>();
            arrayList.setItems(jsonObject.getJsonArray().stream()
                    .map(obj -> obj.getOriginal() != null ? obj.getOriginal() : obj.toString())
                    .toList());
            add(new TextField("JSON Array").setReadOnly(true), arrayList);
        } else if (jsonObject.getJsonObjects() != null) {
            VerticalLayout objectLayout = new VerticalLayout();
            objectLayout.add(new TextField("JSON Object").setReadOnly(true));
            for (Map.Entry<String, JsonObject> entry : jsonObject.getJsonObjects().entrySet()) {
                TextField keyField = new TextField("Key");
                keyField.setValue(entry.getKey());
                keyField.setReadOnly(true);
                JsonDisplayComponent valueComponent = new JsonDisplayComponent();
                valueComponent.setJsonObject(entry.getValue());
                objectLayout.add(keyField, valueComponent);
            }
            add(objectLayout);
        }
    }

    private TextField createLabeledField(String label, String value) {
        TextField field = new TextField(label);
        field.setValue(value);
        field.setReadOnly(true);
        field.setWidthFull();
        return field;
    }
}

2. Set Up the Binder with Data Binding

To connect your DAO's JsonObject field to Vaadin's Binder, we'll use either a simple value provider for display-only cases or a converter for editable scenarios.

Display-Only Binding

If you just need to show the JSON data without editing:

import com.vaadin.flow.data.binder.Binder;

// Assume your DAO class looks like this
public class MyDao {
    private JsonObject jsonData;
    
    // Getters and setters
    public JsonObject getJsonData() { return jsonData; }
    public void setJsonData(JsonObject jsonData) { this.jsonData = jsonData; }
}

// In your View class
public class MyDaoView extends VerticalLayout {
    private Binder<MyDao> binder = new Binder<>(MyDao.class);
    private JsonDisplayComponent jsonDisplay = new JsonDisplayComponent();

    public MyDaoView() {
        add(jsonDisplay);

        // Bind the JsonObject field to our custom component
        binder.forField(jsonDisplay)
                .withNullRepresentation(new JsonObject("{}")) // Default empty JSON
                .bind(MyDao::getJsonData, (dao, json) -> jsonDisplay.setJsonObject(json));

        // Load your DAO data (replace with your actual data fetch logic)
        MyDao dao = loadDaoFromDatabase();
        binder.readBean(dao);
    }
}

Editable Binding (With Raw JSON Input)

If you want users to edit the JSON via a raw text input, add a TextArea and use a converter to handle the string-to-JsonObject conversion:

import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.data.converter.Converter;
import com.vaadin.flow.data.binder.Result;
import com.vaadin.flow.data.binder.ValueContext;

public class MyEditableDaoView extends VerticalLayout {
    private Binder<MyDao> binder = new Binder<>(MyDao.class);
    private TextArea rawJsonInput = new TextArea("Edit Raw JSON");

    public MyEditableDaoView() {
        rawJsonInput.setWidthFull();
        rawJsonInput.setHeight("300px");
        add(rawJsonInput);

        // Create a converter between raw JSON string and JsonObject
        Converter<String, JsonObject> jsonConverter = new Converter<>() {
            @Override
            public Result<JsonObject> convertToModel(String value, ValueContext context) {
                if (value == null || value.isBlank()) {
                    return Result.ok(new JsonObject("{}"));
                }
                try {
                    return Result.ok(new JsonObject(value));
                } catch (Exception e) {
                    return Result.error("Invalid JSON format - please check your input");
                }
            }

            @Override
            public String convertToPresentation(JsonObject value, ValueContext context) {
                return value != null ? value.getOriginal() : "{}";
            }
        };

        // Bind the TextArea to the DAO's JsonObject field
        binder.forField(rawJsonInput)
                .withConverter(jsonConverter)
                .bind(MyDao::getJsonData, MyDao::setJsonData);

        // Load data and add save functionality
        MyDao dao = loadDaoFromDatabase();
        binder.readBean(dao);

        Button saveBtn = new Button("Save", click -> {
            if (binder.writeBeanIfValid(dao)) {
                saveDaoToDatabase(dao); // Replace with your save logic
                Notification.show("JSON saved successfully!");
            }
        });
        add(saveBtn);
    }
}

3. Leverage the VIEW Callback for Auto-Updates

Your JsonObject has a name(VIEW v) method to set a view reference. To make the UI automatically update when the JsonObject changes programmatically, modify the class to trigger notifications:

public class JsonObject { 
    // ... existing fields and constructor ...
    private VIEW view; 

    // Notify the view when data changes
    private void notifyViewChanged() {
        if (view != null) {
            // Cast to our custom component and refresh
            ((JsonDisplayComponent) view).setJsonObject(this);
        }
    }

    // Override setters to trigger notifications
    public void setJsonString(String jsonString) {
        this.jsonString = jsonString;
        notifyViewChanged();
    }

    // Repeat this pattern for other setters (jsonNumber, jsonBoolean, etc.)
    // ... existing getters and setters ...
}

Now whenever you update the JsonObject's data, the UI will refresh automatically without extra code.

内容的提问来源于stack exchange,提问作者Yerbol

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:18:18