如何在Codenameone上删除表单中的所有组件?
How to delete all components in a form on Codenameone?
我正在用 Codenameone 编写一个程序,它将从 url 中提取一系列产品并将它们显示在列表中。我想在每次按下按钮时重新加载页面,所以我编写了一个名为 reload 的方法,该方法应删除表单中的所有内容,然后将其全部替换为新拉出的列表。
public void reload(Form list){
list.removeAll();
list.repaint();
list.add(lpanelf);
pull();
for(int i=0; i<(products.size());i++){
System.out.println(products.get(i));
}
for(int i = 0; i<(products.size()/2);i++){
list.add(createWidget(products.get(i*2),products.get(i*2+1),i));
}
list.addComponent(lpanelb);
}
而 createWidget 是:
public SwipeableContainer createWidget(String product, String amount,int i) {
MultiButton button = new MultiButton(product);
Button buttonb = new Button("DELETE");
deleteb.add(button);
slide.add(buttonb);
button.setLayout(new GridLayout(1,2));
button.add(amount);
return new SwipeableContainer(slide.get(i),deleteb.get(i));
}
第一次重新加载后,抛出:
java.lang.IllegalArgumentException: Component is already contained in
Container: Container[x=0 y=0 width=1125 height=165 name=null, layout =
BorderLayout, scrollableX = false, scrollableY = false, components =
[Button]].
我认为问题是 removeAll 实际上并没有删除所有可滑动的容器,所以它不会让我在它们的位置创建新的容器,但我不太确定。任何帮助将不胜感激。
removeAll()
不递归。由于 GC 通常会删除整棵树,因此这样做会很昂贵并且通常是多余的。
通常这些问题很容易解决。有两种方法:
停止缓存组件并在每次重新加载时重新创建它。这将意味着它永远不会“已经在”某物中
在添加有问题的组件之前,只需执行:problematicComponent.remove()
。这会将它从其父项中删除(或者如果它没有父项则什么都不做)
在你的情况下,你似乎是这样做的:
return new SwipeableContainer(slide.get(i),deleteb.get(i));
完成链接后:
slide.add(buttonb);
因此您将 buttonb
添加到 slide
。这意味着 buttonb.getParent() == slide
。然后你创建一个新的 SwipableContainer
并尝试向其中添加一个已经存在的组件。
我猜是因为你没有说明是哪一行引发了异常,但在那一行你会发现有问题的组件。
这一行也有问题:button.add(amount);
您依赖于 MultiButton
继承自 Container
这一事实,但这是脆弱的行为。您应该使用其中一种设置文本行的方法。
我正在用 Codenameone 编写一个程序,它将从 url 中提取一系列产品并将它们显示在列表中。我想在每次按下按钮时重新加载页面,所以我编写了一个名为 reload 的方法,该方法应删除表单中的所有内容,然后将其全部替换为新拉出的列表。
public void reload(Form list){
list.removeAll();
list.repaint();
list.add(lpanelf);
pull();
for(int i=0; i<(products.size());i++){
System.out.println(products.get(i));
}
for(int i = 0; i<(products.size()/2);i++){
list.add(createWidget(products.get(i*2),products.get(i*2+1),i));
}
list.addComponent(lpanelb);
}
而 createWidget 是:
public SwipeableContainer createWidget(String product, String amount,int i) {
MultiButton button = new MultiButton(product);
Button buttonb = new Button("DELETE");
deleteb.add(button);
slide.add(buttonb);
button.setLayout(new GridLayout(1,2));
button.add(amount);
return new SwipeableContainer(slide.get(i),deleteb.get(i));
}
第一次重新加载后,抛出:
java.lang.IllegalArgumentException: Component is already contained in Container: Container[x=0 y=0 width=1125 height=165 name=null, layout = BorderLayout, scrollableX = false, scrollableY = false, components = [Button]].
我认为问题是 removeAll 实际上并没有删除所有可滑动的容器,所以它不会让我在它们的位置创建新的容器,但我不太确定。任何帮助将不胜感激。
removeAll()
不递归。由于 GC 通常会删除整棵树,因此这样做会很昂贵并且通常是多余的。
通常这些问题很容易解决。有两种方法:
停止缓存组件并在每次重新加载时重新创建它。这将意味着它永远不会“已经在”某物中
在添加有问题的组件之前,只需执行:
problematicComponent.remove()
。这会将它从其父项中删除(或者如果它没有父项则什么都不做)
在你的情况下,你似乎是这样做的:
return new SwipeableContainer(slide.get(i),deleteb.get(i));
完成链接后:
slide.add(buttonb);
因此您将 buttonb
添加到 slide
。这意味着 buttonb.getParent() == slide
。然后你创建一个新的 SwipableContainer
并尝试向其中添加一个已经存在的组件。
我猜是因为你没有说明是哪一行引发了异常,但在那一行你会发现有问题的组件。
这一行也有问题:button.add(amount);
您依赖于 MultiButton
继承自 Container
这一事实,但这是脆弱的行为。您应该使用其中一种设置文本行的方法。