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。
为什么在我关闭网络浏览器中的选项卡并再次返回同一 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。