Vaadin,通过setContent()切换内容未显示

Vaadin,通过setContent()切换内容未显示,vaadin,vaadin7,Vaadin,Vaadin7,瓦丁7.6.2 以以下为例: import com.vaadin.ui.Button; import com.vaadin.ui.Button.ClickListener; import com.vaadin.ui.HorizontalLayout; import com.vaadin.ui.Panel; import com.vaadin.ui.TextField; import com.vaadin.ui.VerticalLayout; public class MyClass exten

瓦丁7.6.2

以以下为例:

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class MyClass extends Panel {

    TextField        myField  = new TextField();
    HorizontalLayout hLayout  = new HorizontalLayout( myField );
    VerticalLayout   vLayout  = new VerticalLayout( myField );    
    Button           button   = new Button( "Press Me" );

    public MyClass() {
        super();
        applySettings();
    }

    private void applySettings() {
        button.addClickListener(new ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                setContent( hLayout );
            }
        });

        vLayout.addComponent( button );


        this.setContent( vLayout );
    }
}
单击按钮时,vLayout消失,但hLayout(带
myField
)不显示。我错过了哪一步?或者,有没有其他方法可以做到这一点

如果我添加一个辅助文本字段,如下所示:

TextField        myField  = new TextField();
TextField        myField2 = new TextField();  // tf2
HorizontalLayout hLayout  = new HorizontalLayout( myField );
VerticalLayout   vLayout  = new VerticalLayout( myField2 );  // tf2

这似乎是可行的,但我试图实现的是使用切换出的布局中的字段(及其数据)动态切换布局的能力。

看来我可能已经解决了这个问题

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class MyClass extends Panel {

    TextField        myField  = new TextField();
    HorizontalLayout hLayout  = new HorizontalLayout();
    VerticalLayout   vLayout  = new VerticalLayout();    
    Button           button   = new Button( "Press Me" );

    public MyClass() {
        super();
        applySettings();
    }

    private void applySettings() {
        button.addClickListener(new ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                vLayout.removeAllComponents();   // this is optional
                hLayout.addComponent( myField );
                setContent( hLayout );
            }
        });

        vLayout.addComponents( myField, button );

        this.setContent( vLayout );
    }
}
如果我不在布局构造函数中添加
myField
,而是稍后在代码中添加,那么它似乎可以工作

更新


经过更多的测试,对于给定的字段,无论最后调用哪个布局
addComponent()
,该布局都会获得该字段的句柄。这种行为似乎很奇怪,如果有人能解释为什么会这样?那会很有启发性。

看来我可能已经解决了

import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;

public class MyClass extends Panel {

    TextField        myField  = new TextField();
    HorizontalLayout hLayout  = new HorizontalLayout();
    VerticalLayout   vLayout  = new VerticalLayout();    
    Button           button   = new Button( "Press Me" );

    public MyClass() {
        super();
        applySettings();
    }

    private void applySettings() {
        button.addClickListener(new ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                vLayout.removeAllComponents();   // this is optional
                hLayout.addComponent( myField );
                setContent( hLayout );
            }
        });

        vLayout.addComponents( myField, button );

        this.setContent( vLayout );
    }
}
如果我不在布局构造函数中添加
myField
,而是稍后在代码中添加,那么它似乎可以工作

更新


经过更多的测试,对于给定的字段,无论最后调用哪个布局
addComponent()
,该布局都会获得该字段的句柄。这种行为似乎很奇怪,如果有人能解释为什么会这样?这很有启发性。

一个组件不能同时有两个父组件(
hLayout
&
vLayout
),因此,如果它已经有一个父组件,Vaadin将从以前的父组件中删除它,并将其作为子组件添加到当前父组件中。这是从以下继承的
addComponent
方法:

/**
*这仅实现事件和组件父调用。延伸
*类必须实现组件列表维护并调用此方法
*在部件清单维护之后。
* 
*@see com.vaadin.ui.ComponentContainer#addComponent(Component)
*/
@凌驾
公共组件(组件c){
//确保我们没有将组件添加到它自己的内容中
if(isOrHasAncestor(c)){
抛出新的IllegalArgumentException(
“不能在其自身内容中添加组件”);
}
如果(c.getParent()!=null){
//如果组件已具有父级,请尝试将其删除
AbstractSingleComponentContainer.removeFromParent(c);
}
c、 setParent(本);
防火组件附件(c);
markAsDirty();
}
如果您在中,您可以在浏览器中通过向URL添加
?debug
,在某种程度上看到合成树的图像,如


一个组件不能同时有两个父组件(
hLayout
&
vLayout
),因此,如果它已经有一个父组件,Vaadin将从上一个父组件中删除它,并将其作为子组件添加到当前父组件中。这是从以下继承的
addComponent
方法:

/**
*这仅实现事件和组件父调用。延伸
*类必须实现组件列表维护并调用此方法
*在部件清单维护之后。
* 
*@see com.vaadin.ui.ComponentContainer#addComponent(Component)
*/
@凌驾
公共组件(组件c){
//确保我们没有将组件添加到它自己的内容中
if(isOrHasAncestor(c)){
抛出新的IllegalArgumentException(
“不能在其自身内容中添加组件”);
}
如果(c.getParent()!=null){
//如果组件已具有父级,请尝试将其删除
AbstractSingleComponentContainer.removeFromParent(c);
}
c、 setParent(本);
防火组件附件(c);
markAsDirty();
}
如果您在中,您可以在浏览器中通过向URL添加
?debug
,在某种程度上看到合成树的图像,如


您能否发布一个完整的示例,也称为?@Morfic更新了该示例。您能否发布一个完整的示例,也称为?@Morfic更新了该示例。您是正确的,将组件分配给多个父级时,Vaadin从一个父级转移到另一个父级,因为一个组件在任何时候最多只能有一个父级(刚构建时可能没有)。它就像一个树结构。请参阅我的答案以获得更详细的解释。无论如何+1用于自己解决:-)只是一个小更新,因为当你有时间时,我不知道你是否知道,所以我用一些细节和一个小屏幕截图更新了答案。您说得对,将组件分配给多个父级时,Vaadin会从一个父级转移到另一个父级,因为组件在任何时候最多只能有一个父级(刚构建时可能没有父级)。就像一棵树一样。有关更详细的解释,请参见我的答案。总之+1是为了自己弄清楚:-)只是一个小更新,当你有时间的时候,我不知道你是否知道,所以我用一些细节和一个小屏幕截图更新了答案。干杯