简体   繁体   English

将表单元素绑定到IntelliJ插件中的持久存储

[英]Binding form elements to persistent storage in IntelliJ plugin

I have just started trying to make my own IntelliJ plugin and can't figure out how to properly save persistent information on bound form components. 我刚刚开始尝试制作自己的IntelliJ插件,但无法弄清楚如何在绑定表单组件上正确保存持久性信息。

I followed the right click on form, Data Binding Wizard, and properly matched up everything that was listed. 我在窗体上单击鼠标右键,然后单击“数据绑定向导”,然后正确匹配列出的所有内容。 I then modified the generated methods to handle the objects (or in this case, one object) that could not be bound (a JSpinner). 然后,我修改了生成的方法以处理无法绑定的对象(在这种情况下为一个对象)(JSpinner)。

How am I supposed to get the persistent storage to automatically save/update when the state of a component on my form is changed? 当表单上组件的状态更改时,如何使持久性存储自动保存/更新?

Here is my PersistentStateComponent class: 这是我的PersistentStateComponent类:

import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.util.xmlb.XmlSerializerUtil;

@State(
        name = "Hastebin Configuration",
        reloadable = true,
        storages = {
                @Storage(id = "other", file = StoragePathMacros.APP_CONFIG + "/hastebin.xml")
        }
)
public class HastebinService implements PersistentStateComponent<HastebinService> {

    private String host = "hastebin.com";
    private String msgSuccess = "Share with Hastebin successful.<br>Link is waiting in your clipboard.";
    private String msgFailure = "Something went wrong.<br><br>Problem description: {error}<br><br>Please try again and it problem persists, contact the author.";
    private boolean logPastes = false;
    private int port = 80;
    private boolean useFileAssoc = true;
    private boolean useSSL = false;

    public String getHost() {
        return this.host;
    }

    public boolean getLogPastes() {
        return this.logPastes;
    }

    public String getMsgFailure() {
        return this.msgFailure;
    }

    public String getMsgSuccess() {
        return this.msgSuccess;
    }

    public int getPort() {
        return this.port;
    }

    @Override
    public HastebinService getState() {
        return this;
    }

    public boolean getUseFileAssoc() {
        return this.useFileAssoc;
    }

    public boolean getUseSSL() {
        return this.useSSL;
    }

    @Override
    public void loadState(HastebinService state) {
        XmlSerializerUtil.copyBean(state, this);
    }

    public void setHost(String host) {
        this.host = host;
        System.out.println("testing");
    }

    public void setLogPastes(boolean logPastes) {
        this.logPastes = logPastes;
    }

    public void setMsgFailure(String msgFailure) {
        this.msgFailure = msgFailure;
    }

    public void setMsgSuccess(String msgSuccess) {
        this.msgSuccess = msgSuccess;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public void setUseFileAssoc(boolean useFileAssoc) {
        this.useFileAssoc = useFileAssoc;
    }

    public void setUseSSL(boolean useSSL) {
        this.useSSL = useSSL;
    }

}

Here is my form class: 这是我的表单类:

import com.intellij.ui.components.JBScrollPane;

import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JViewport;
import javax.swing.SpinnerNumberModel;
import java.awt.Color;
import java.awt.event.ActionListener;

public class SettingsPanel {
    private JTabbedPane hasteTabConfig;
    private JCheckBox chkUseSsl;
    private JCheckBox chkFileAssoc;
    private JCheckBox chkLogHistory;
    private JTextField txtSuccess;
    private JTextField txtFailure;
    private JTextField txtDomain;
    private JLabel lblProtocol;
    private JSpinner spinPort;
    private JPanel rootPanel;
    private JScrollPane scrollPane;
    private JPanel scrollPanel;
    private JTable tblHistory;

    public SettingsPanel() {
        this.scrollPanel.setOpaque(false);

        this.chkUseSsl.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent e) {
                updateProtocol();
            }
        });
    }

    private void createUIComponents() {
        // Scroll Pane
        this.scrollPane = new JBScrollPane();
        this.scrollPane.setBackground(new Color(230, 230, 230));
        this.scrollPane.setViewport(new CustomViewPort(this.scrollPanel));
        this.scrollPane.setOpaque(false);
        this.scrollPane.getVerticalScrollBar().setBlockIncrement(20);
        this.scrollPane.getVerticalScrollBar().setUnitIncrement(16);

        // Port Number
        this.spinPort = new JSpinner(new SpinnerNumberModel(80, 1, 65535, 1));
        JFormattedTextField textField = ((JSpinner.DefaultEditor)this.spinPort.getEditor()).getTextField();
        textField.setColumns(1);
    }

    public void getData(HastebinService data) {
        this.getUnboundData(data);
        data.setHost(this.txtDomain.getText());
        data.setUseSSL(this.chkUseSsl.isSelected());
        data.setUseFileAssoc(this.chkFileAssoc.isSelected());
        data.setLogPastes(this.chkLogHistory.isSelected());
        data.setMsgSuccess(this.txtSuccess.getText());
        data.setMsgFailure(this.txtFailure.getText());
    }

    private void getUnboundData(HastebinService data) {
        data.setPort((int)this.spinPort.getValue());
    }

    public JPanel getRootPanel() {
        return this.rootPanel;
    }

    public boolean isModified(HastebinService data) {
        if (this.isUnboundModified(data)) return true;
        if (this.txtDomain.getText() != null ? !this.txtDomain.getText().equals(data.getHost()) : data.getHost() != null)
            return true;
        if (this.chkUseSsl.isSelected() != data.getUseSSL()) return true;
        if (this.chkFileAssoc.isSelected() != data.getUseFileAssoc()) return true;
        if (this.chkLogHistory.isSelected() != data.getLogPastes()) return true;
        if (this.txtSuccess.getText() != null ? !this.txtSuccess.getText().equals(data.getMsgSuccess()) : data.getMsgSuccess() != null)
            return true;
        if (this.txtFailure.getText() != null ? !this.txtFailure.getText().equals(data.getMsgFailure()) : data.getMsgFailure() != null)
            return true;
        return false;
    }

    private boolean isUnboundModified(HastebinService data) {
        if ((int)this.spinPort.getValue() != data.getPort()) return true;
        return false;
    }

    public void setData(HastebinService data) {
        this.setUnboundData(data);
        this.txtDomain.setText(data.getHost());
        this.chkUseSsl.setSelected(data.getUseSSL());
        this.chkFileAssoc.setSelected(data.getUseFileAssoc());
        this.chkLogHistory.setSelected(data.getLogPastes());
        this.txtSuccess.setText(data.getMsgSuccess());
        this.txtFailure.setText(data.getMsgFailure());
        this.updateProtocol();
    }

    public void setUnboundData(HastebinService data) {
        this.spinPort.setValue(data.getPort());
    }

    private void updateProtocol() {
        this.lblProtocol.setText("http" + (this.chkUseSsl.isSelected() ? "s" : "") + "://");
    }

    private class CustomViewPort extends JViewport {

        public CustomViewPort(JComponent component) {
            this.setView(component);
            this.setOpaque(false);
        }
    }
}

The IntelliJ IDEA codebase does not contain any standard databinding solution for automatically updating a persistent component when a form changes. IntelliJ IDEA代码库不包含任何标准数据绑定解决方案,用于在表单更改时自动更新持久性组件。 JetBrains' own code simply copies the fields from the form to the component manually. JetBrains自己的代码只是将字段从表单手动复制到组件。

Taking yole's answer into account, I came up with a solution that automatically saves data automatically in an "ok enough" way for light plugins. 考虑到yole的回答,我想出了一个解决方案,该解决方案以“足够”的方式自动为light插件自动保存数据。

new Timer(2000, new ActionListener() { // Create 2 Second Timer
    @Override
    public void actionPerformed(ActionEvent event) {
        if (isModified()) // Any Changes?
            getData(); // Save Data
    }
}).start();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM