java.lang.IllegalStateException: невозможно переместить узел из одного дерева состояний в другое - 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
Причина:
В данном случае речь идет о Vaadin 14, где я использую AppLayout
класс для установки его компонентов.
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);
}
}
С сюжетом классно. Я знаю, что 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();
}
}