Why does I get this error when I close the tab in my web browser and go back to the same URL page again?
Error:
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
Cause:
In this case, it's about Vaadin 14 where I'm using the AppLayout class to set its components.
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);
Suggestion:
I think I need to clean up the content before I can set the layout again?
Question:
Do you know how to remove the node from state tree to another?
How to reproduce the error:
Copy over this to your IDE and run the code with Vaadin 14. Access the route, then close your web browser. Open your web browser again and access the route again. This code is a minimal example. I have removed so much I can.
The you will have this error:
#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);
}
}
And a thread
public class ControlThread extends Thread{
private UI ui;
public ControlThread(UI ui) {
this.ui = ui;
}
#Override
public void run() {
while(true) {
}
}
}
Update:
Here is a very minimal code example.
I'm using Vaadin 14.2.1 with 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);
}
}
And the paper-slider from Vaadin dev team.
#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);
}
}
Notice that if I use this test example:
#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);
}
}
With the plot class. I know that Apex Chart's is a third library for Vaadin. But it gives the same error as 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();
}
}
One bug related to this was fixed in Vaadin 14.2.1.
I have started making a program in JavaFX where i have ListView with added functionality like editing, adding new items and deleting.I have managed to do most of the work but there is still a little more to do. So far i have added the deleting and editing functionality successfully but i have got a small problem with the adding functionality. I can still add new items to the ListView but i can't make it possible to edit the newly added item, because i need the ListCell the new item represents to start editing it. So my question is how can i get the ListCell of the new item in the ListView.
For this purpose here is my code:
private TextField textField;
ListCell<String> cell = this;
int i = 0;
boolean manually_selected = false;
public LanguageListCell(ListView<String> languages)
{
ContextMenu contextMenu = new ContextMenu();
cell.setEditable(true);
MenuItem editItem = new MenuItem();
editItem.textProperty().bind(Bindings.format("Edit \"%s\"", cell.itemProperty()));
editItem.setOnAction(event -> {
// The LanguageListCell class i want to put here...
cell.startEdit();
});
MenuItem addItem = new MenuItem("Add language");
addItem.setOnAction(new EventHandler<ActionEvent> () {
#Override
public void handle(ActionEvent ev)
{
i++;
String lang = "New Language " + i;
languages.getItems().add(lang);
if(i == 10)
{
addItem.setDisable(true);
}
languages.getSelectionModel().clearSelection();
languages.getSelectionModel().select(languages.getItems().size() - 1);
cell.setItem(languages.getSelectionModel().getSelectedItem());
manually_selected = true;
}
});
MenuItem deleteItem = new MenuItem();
deleteItem.textProperty().bind(Bindings.format("Delete \"%s\"", cell.itemProperty()));
deleteItem.setOnAction(new EventHandler<ActionEvent> () {
#Override
public void handle(ActionEvent ev)
{
if(languages.getSelectionModel().getSelectedItems().size() - 1 > 0)
{
if(i > 0)
{
i = (languages.getItems().size() - languages.getSelectionModel().getSelectedItems().size()) - 1;
}
/*for(String lang: languages.getSelectionModel().getSelectedItems())
{
languages.getItems().remove(lang);
}*/
ArrayList<String> delete_data = new ArrayList<String>(languages.getSelectionModel().getSelectedItems());
languages.getItems().removeAll(delete_data);
}
languages.getItems().remove(cell.getItem());
if(i > 0) i = 0;
}
});
contextMenu.setOnShowing(new EventHandler<WindowEvent>() {
#Override
public void handle(WindowEvent e) {
if(languages.getSelectionModel().getSelectedItems().size() - 1 > 0)
{
editItem.setDisable(true);
addItem.setDisable(true);
}
}
});
contextMenu.getItems().addAll(addItem, editItem, deleteItem);
cell.textProperty().bind(cell.itemProperty());
cell.emptyProperty().addListener((obs, wasEmpty, isNowEmpty) -> {
if (isNowEmpty) {
cell.setContextMenu(null);
} else {
cell.setContextMenu(contextMenu);
}
});
}
I'm trying to implement a search filter in my Container which contains a set of buttons.
Here's my code:
public void listMenu() {
Dialog loading = new InfiniteProgress().showInifiniteBlocking();
loading.show();
final Form listMenu = new Form("List Menu");
listMenu.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
Container list = new Container();
list.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
list.removeAll();
Button back = new Button("Back to Main Menu");
ParseQuery<ParseObject> query = ParseQuery.getQuery("mylist");
query.whereExists("Title");
List<ParseObject> results = null;
try {
Button btn = null;
results = query.find();
if(!results.isEmpty()) {
int index = 0;
int size = results.size();
for(;index < size;++index) {
list.add(btn = new Button(results.get(index).getString("Title")));
addListener(btn);
}
}
} catch (com.parse4cn1.ParseException e) {
Dialog.show("Err", "Server is not responding.", "OK", null);
}
listMenu.add(list);
listMenu.add(back);
listMenu.show();
loading.dispose();
back.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ev)
{
new StateMachine("/theme");
}
});
}
This code basically is querying data from the Database then setting its results into buttons then added to a Container. My question is how to implement a search filter to my Container? I've seen FilterProxyListModel<T> but not sure if ListModel<T> is compatible with Container. I'd appreciate to see an example of search filter implementation in my code.
FilterProxyListModel is for List which we don't recommend anymore. There is a full sample of searching a container here. It uses MultiButton but using Button would work just as well:
hi.getToolbar().addSearchCommand(e -> {
String text = (String)e.getSource();
if(text == null || text.length() == 0) {
// clear search
for(Component cmp : hi.getContentPane()) {
cmp.setHidden(false);
cmp.setVisible(true);
}
hi.getContentPane().animateLayout(150);
} else {
text = text.toLowerCase();
for(Component cmp : hi.getContentPane()) {
Button mb = (Button)cmp;
String line1 = mb.getText();
boolean show = line1 != null && line1.toLowerCase().indexOf(text) > -1;
mb.setHidden(!show);
mb.setVisible(show);
}
hi.getContentPane().animateLayout(150);
}
}, 4);
Theme layering: I have followed the step given what would be the problem but the layering is not working. I have changed the purenativetheme constant as false.
private Form current;
private Resources theme;
public void init(Object context) {
theme = UIManager.initFirstTheme("/theme");
UIManager.getInstance().addThemeProps(theme.getTheme("Theme"));
// Enable Toolbar on all Forms by default
Toolbar.setGlobalToolbar(true);
// Pro only feature, uncomment if you have a pro subscription
// Log.bindCrashProtection(true);
}
public void start() {
if(current != null){
current.show();
return;
}
Form hi = new Form("Welcome", new BorderLayout(BorderLayout.CENTER_BEHAVIOR_CENTER_ABSOLUTE));
final Label apple = new Label(theme.getImage("apple-icon.png"));
final Label android = new Label(theme.getImage("android-icon.png"));
final Label windows = new Label(theme.getImage("windows-icon.png"));
Button getStarted = new Button("Let's Get Started!");
getStarted.setUIID("Button");
FontImage.setMaterialIcon(getStarted, FontImage.MATERIAL_LINK);
getStarted.setUIID("GetStarted");
hi.addComponent(BorderLayout.CENTER,
LayeredLayout.encloseIn(
BoxLayout.encloseY(
new Label(theme.getImage("duke-no-logos.png")),
getStarted
),
FlowLayout.encloseRightMiddle(apple)
)
);
getStarted.addActionListener((e) -> {
Display.getInstance().execute("https://www.codenameone.com/developers.html");
});
new UITimer(() -> {
if(apple.getParent() != null) {
apple.getParent().replace(apple, android, CommonTransitions.createFade(500));
} else {
if(android.getParent() != null) {
android.getParent().replace(android, windows, CommonTransitions.createFade(500));
} else {
windows.getParent().replace(windows, apple, CommonTransitions.createFade(500));
}
}
}).schedule(2200, true, hi);
hi.show();
}
I have created javaFX tree with custom Objects (SystemNode).
Tree Items has graphics: check-box and image icon which I have set through updateItems() method.
Whenever I expand or collapse Item in tree ,twice or thrice I get JAVA HEAP MEMORY OUT OF SPACE and whole UI hangs UP.
PS: updateItems() method is invoked every time I expand or collapse tree node
I have tried adding event handlers but they didn't work.
Can anyone give some solutions.
Here is how I set cellFactory :
treeView_technicalAreas.setCellFactory(Util.getTreeCellFactory());
Here is code for cell factory:
public static Callback<TreeView<SystemNode>, TreeCell<SystemNode>> getTreeCellFactory() {
Callback<TreeView<SystemNode>, TreeCell<SystemNode>> callback = new Callback<TreeView<SystemNode>, TreeCell<SystemNode>>() {
#Override
public TreeCell<SystemNode> call(TreeView<SystemNode> p) {
TreeCell<SystemNode> cell = new TreeCell<SystemNode>() {
#Override
protected void updateItem(SystemNode t, boolean isEmpty) {
super.updateItem(t, isEmpty); //To change body of generated methods, choose Tools | Templates.
if (!isEmpty) {
System.out.println("util call back : " + t.getSystem().getName());
setText(t.getSystem().getName());
HBox hBox = new HBox();
CheckBox checkBox = new CheckBox();
checkBox.setSelected(t.getSelected());
checkBox.selectedProperty().bindBidirectional(t.getSelectedProperty());
hBox.setSpacing(SPACING_BETWEEN_ICON_AND_CHECKBOX);
ImageView imageView_icon = null;
if (t.getSystem().getType() == TYPE.BAREA) {
imageView_icon = new ImageView(Constant.Image_AREAS);
} else if (t.getSystem().getType() == TYPE.AREA) {
imageView_icon = new ImageView(Constant.Image_AREAS);
} else if (t.getSystem().getType() == TYPE.DOCUMENT) {
imageView_icon = new ImageView(Constant.Image_DOCUMENTS);
} else if (t.getSystem().getType() == TYPE.NOUN_NAME) {
imageView_icon = new ImageView(Constant.Image_NOUN_NAME);
} else if (t.getSystem().getType() == TYPE.CHANGE) {
imageView_icon = new ImageView(Constant.Image_DCC);
} else if (t.getSystem().getType() == TYPE.TASK) {
imageView_icon = new ImageView(Constant.Image_TASK);
}
hBox.getChildren().addAll(checkBox, imageView_icon);
setGraphic(hBox);
}
}
};
return cell;
}
};
return callback;
}