java.lang.IllegalStateException: 无法将节点从一个状态树移动到另一个 - Vaadin

java.lang.IllegalStateException: Can't move a node from one state tree to another - Vaadin

为什么在我关闭网络浏览器中的选项卡并再次返回同一 URL 页面时出现此错误?

错误:

java.lang.IllegalStateException: Can't move a node from one state tree to another. If this is intentional, first remove the node from its current state tree by calling removeFromTree

原因:

在这种情况下,我使用 AppLayout class 来设置其组件,这是关于 Vaadin 14。

    HorizontalLayout firstRow = new HorizontalLayout(loggerId, calibration, alarm, showSamples, samplingTime);
    HorizontalLayout secondRow = new HorizontalLayout(do0SliderLayout, do1SliderLayout, do2SliderLayout, do3SliderLayout);
    HorizontalLayout thirdRow = new HorizontalLayout(updatePlot, loggingActivate);
    thirdRow.setAlignItems(Alignment.CENTER);
    VerticalLayout layout = new VerticalLayout(firstRow, secondRow, thirdRow, apexChart);
    setContent(layout);

建议:

我想我需要清理一下内容才能重新设置布局?

问题:

你知道如何将节点从状态树移除到另一个吗?

如何重现错误:

将此复制到您的 IDE 和 运行 使用 Vaadin 14 的代码。访问路线,然后关闭您的网络浏览器。再次打开您的网络浏览器并再次访问该路线。此代码是一个最小示例。我已经删除了很多。

您将遇到此错误:

@Route("")
@CssImport("./styles/shared-styles.css")
@CssImport(value = "./styles/vaadin-text-field-styles.css", themeFor = "vaadin-text-field")
@Push
@PreserveOnRefresh
public class MainView extends AppLayout {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;


    public static final String START_LOGGING = "Start logging";
    public static final String STOP_LOGGING = "Stop logging";

    static public Boolean selectedUpdatePlot = false;

    static public Integer selectedShowSamples = 10; // Minimum

    static public Integer selectedSamplingTime = 0;

    static public Long selectedAID = 0L;

    static public Long selectedCID = 0L;

    static public Long selectedLoggerId = 0L;

    static public ApexCharts apexChart;

    static public PaperSlider do0Slider;

    static public PaperSlider do1Slider;

    static public PaperSlider do2Slider;

    static public PaperSlider do3Slider;

    static public AtomicBoolean loggingNow;

    static public ControlThread control;

    @PostConstruct
    public void init() {
        // Set the top and the tabs
        Top top = new Top();
        top.setTopAppLayout(this);

        // Set the chart
        if(apexChart == null)
            apexChart = new Graf().getApexChart();

        // Create layout for slider 0
        if(do0Slider == null) {
            do0Slider = new PaperSlider(4095);
        }

        // Create layout for slider 1
        if(do1Slider == null) {
            do1Slider = new PaperSlider(4095);
        }

        // Create layout for slider 2
        if(do2Slider == null) {
            do2Slider = new PaperSlider(4095);
        }

        // Create layout for slider 3
        if(do3Slider == null) {
            do3Slider = new PaperSlider(4095);
        }

        // This variable controls the logging thread
        if(loggingNow == null) {
            loggingNow = new AtomicBoolean();
        }

        // Create control panel
        updateControlPanel();

        // Start the tread
        if(control == null) {
           control = new ControlThread(UI.getCurrent());
           control.start();
        }

    }

    private void updateControlPanel() {
        // Set the logger ids
        List<UserLogg> userLoggers = new ArrayList<Long>();
        Select<Long> loggerId = new Select<>();
        ArrayList<Long> loggerIds = new ArrayList<Long>();
        loggerIds.add(selectedLoggerId);
        for(int i = 0; i < userLoggers.size(); i++) {
            loggerIds.add(userLoggers.get(i).getLoggerId());
        }
        loggerId.setItems(loggerIds);
        loggerId.setValue(selectedLoggerId);
        loggerId.addValueChangeListener(e -> {
            selectedLoggerId = loggerId.getValue();
        });

        // Set the calibration id
        List<CalibrationLogg> calibrationsLoggers = new ArrayList<Long>();
        Select<Long> calibration = new Select<>();
        ArrayList<Long> CIDs = new ArrayList<Long>();
        CIDs.add(selectedCID);
        for(int i = 0; i < calibrationsLoggers.size(); i++) {
            CIDs.add(calibrationsLoggers.get(i).getCID());
        }
        calibration.setItems(CIDs);
        calibration.setValue(selectedCID);
        calibration.addValueChangeListener(e -> {
            selectedCID = calibration.getValue();
        });

        // Set the alarm id
        List<AlarmLogg> alarmsLoggers = new ArrayList<Long>();
        Select<Long> alarm = new Select<>();
        ArrayList<Long> AIDs = new ArrayList<Long>();
        AIDs.add(selectedAID);
        for(int i = 0; i < alarmsLoggers.size(); i++) {
            AIDs.add(alarmsLoggers.get(i).getAID());
        }
        alarm.setItems(AIDs);
        alarm.setValue(selectedAID);
        alarm.addValueChangeListener(e -> {
            selectedAID = alarm.getValue();
        });

        // Slider 0
        VerticalLayout do0SliderLayout = new VerticalLayout(new Label("DO0"), do0Slider);
        do0SliderLayout.setAlignItems(Alignment.CENTER);
        do0Slider.setEnabled(false);

        // Slider 1
        VerticalLayout do1SliderLayout = new VerticalLayout(new Label("DO1"), do1Slider);
        do1SliderLayout.setAlignItems(Alignment.CENTER);
        do1Slider.setEnabled(false);

        // Slider 2
        VerticalLayout do2SliderLayout = new VerticalLayout(new Label("DO2"), do2Slider);
        do2SliderLayout.setAlignItems(Alignment.CENTER);
        do2Slider.setEnabled(false);

        // Slider 3
        VerticalLayout do3SliderLayout = new VerticalLayout(new Label("DO3"), do3Slider);
        do3SliderLayout.setAlignItems(Alignment.CENTER);
        do3Slider.setEnabled(false);

        // Sampling time for the thread
        IntegerField samplingTime = new IntegerField();
        samplingTime.setValue(selectedSamplingTime);
        samplingTime.addValueChangeListener(e -> {
            if(e.getValue() < 10) {
                samplingTime.setValue(10);
                selectedSamplingTime = 10;
            }
            selectedSamplingTime = samplingTime.getValue();
        });

        // Show amount of samples at the plot
        Select<Integer> showSamples = new Select<Integer>();
        showSamples.setItems(new Integer[] {10, 20, 30, 40, 50});
        showSamples.setValue(selectedShowSamples);
        showSamples.addValueChangeListener(e -> {
            selectedShowSamples = showSamples.getValue();
        });

        // Check box if we want to show the plot or not
        Checkbox updatePlot = new Checkbox();
        updatePlot.setLabel("Plot");
        updatePlot.setValue(selectedUpdatePlot);
        updatePlot.addValueChangeListener(e -> {
            selectedUpdatePlot = updatePlot.getValue();
        });

        // Start and stop button for logging
        Button loggingActivate = new Button(START_LOGGING);
        if(loggingNow.get() == true)
            loggingActivate.setText(STOP_LOGGING);
        loggingActivate.addClickListener(e -> {
            if(loggingNow.get() == false) {
                loggingActivate.setText(STOP_LOGGING);
                calibration.setEnabled(false);
                alarm.setEnabled(false);
                loggerId.setEnabled(false);
                do0Slider.setEnabled(true);
                do1Slider.setEnabled(true);
                do2Slider.setEnabled(true);
                do3Slider.setEnabled(true);
                samplingTime.setEnabled(false);
                showSamples.setEnabled(false);
                updatePlot.setEnabled(false);
                loggingNow.set(true);
            }else{
                loggingActivate.setText(START_LOGGING);
                calibration.setEnabled(true);
                alarm.setEnabled(true);
                loggerId.setEnabled(true);
                do0Slider.setEnabled(false);
                do1Slider.setEnabled(false);
                do2Slider.setEnabled(false);
                do3Slider.setEnabled(false);
                samplingTime.setEnabled(true);
                showSamples.setEnabled(true);
                updatePlot.setEnabled(true);
                loggingNow.set(false);
                do0Slider.setValue(0);
                do1Slider.setValue(0);
                do2Slider.setValue(0);
                do3Slider.setValue(0);
            }
        });

        // Layout
        HorizontalLayout firstRow = new HorizontalLayout(loggerId, calibration, alarm, showSamples, samplingTime);
        HorizontalLayout secondRow = new HorizontalLayout(do0SliderLayout, do1SliderLayout, do2SliderLayout, do3SliderLayout);
        HorizontalLayout thirdRow = new HorizontalLayout(updatePlot, loggingActivate);
        thirdRow.setAlignItems(Alignment.CENTER);
        VerticalLayout layout = new VerticalLayout(firstRow, secondRow, thirdRow, apexChart);
        setContent(layout);
    }
}

还有一个线程

       public class ControlThread extends Thread{

        private UI ui;

        public ControlThread(UI ui) {
            this.ui = ui;

        }
        @Override
        public void run() {
            while(true) {   
            }
        }
}

更新:

这是一个非常简单的代码示例。 我将 Vaadin 14.2.1 与 OpenJDK 11

一起使用
@Route("test")
@CssImport("./styles/shared-styles.css")
@CssImport(value = "./styles/vaadin-text-field-styles.css", themeFor = "vaadin-text-field")
public class TestView extends AppLayout {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    static public PaperSlider do0Slider;

    @PostConstruct
    public void init() {

        // Set the slider
        if(do0Slider == null) {
            do0Slider = new PaperSlider(4095);
        }

        setContent(do0Slider);

    }
}

还有来自 Vaadin 开发团队的纸滑块。

@Tag("paper-slider")
@NpmPackage(value = "@polymer/paper-slider",
            version = "3.0.1")
@JsModule("@polymer/paper-slider/paper-slider.js")
public class PaperSlider extends AbstractSinglePropertyField<PaperSlider, Integer> {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public PaperSlider(int max) {
        super("value", 0, false);
        this.getElement().setProperty("max", max);
        this.getElement().setProperty("pin", true);
    }

}

请注意,如果我使用此测试示例:

@Route("test")
@CssImport("./styles/shared-styles.css")
@CssImport(value = "./styles/vaadin-text-field-styles.css", themeFor = "vaadin-text-field")
public class TestView extends AppLayout {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    static public ApexCharts apexChart;

    @PostConstruct
    public void init() {

        // Set the chart
        if(apexChart == null)
            apexChart = new Graf().getApexChart();

        setContent(apexChart);

    }
}

配合剧情class。我知道 Apex Chart 是 Vaadin 的第三个库。但它给出了与 Paper-Slider 相同的错误。

@Data
public class Graf {

    private ApexCharts apexChart;
    private XAxis xAxis;

    public Graf() {
        apexChart = ApexChartsBuilder.get()
                .withChart(ChartBuilder.get()
                        .withType(Type.line)
                        .withZoom(ZoomBuilder.get()
                                .withEnabled(true)
                                .build())
                        .withToolbar(ToolbarBuilder.get()
                                .withShow(true)
                                .build())
                        .withAnimations(AnimationsBuilder.get()
                                .withEnabled(false)
                                .build())
                        .build())
                .withLegend(LegendBuilder.get()
                        .withShow(true)
                        .build())
                .withDataLabels(DataLabelsBuilder.get()
                        .withEnabled(false)
                        .build())
                .withColors("#48912c", "#13ebd5", "#215ed9", "#e6c222", "#a524e0", "#633326") // PWM1, PWM2, PMW4, Temp1, Temp2
                .withTooltip(TooltipBuilder.get()
                        .withEnabled(false)
                        .build())
                .withStroke(StrokeBuilder.get()
                        .withCurve(Curve.straight)
                        .build())
                .withTitle(TitleSubtitleBuilder.get()
                        .withText("MySQL")
                        .withAlign(Align.left)
                        .build())
                .withGrid(GridBuilder.get()
                        .withRow(RowBuilder.get()
                                .withColors("#f3f3f3", "transparent")
                                .withOpacity(0.5)
                                .build())
                        .build())
                .withYaxis(YAxisBuilder.get()
                        .withTitle(TitleBuilder.get()
                                .withText("Measurements")
                                .build())
                        .build())
                .withXaxis(XAxisBuilder.get()
                        .withTitle(com.github.appreciated.apexcharts.config.xaxis.builder.TitleBuilder.get()
                                .withText("Time")
                                .build())
                        .withCategories("")
                        .build())
                .withSeries(new Series<>("desktop", 1, 2, 3))
                .build();
            apexChart.setWidthFull();
    }
}

Vaadin 14.2.1 中修复了一个 bug related to this