如何在Vaadin的派生类中访问getComponent



这是我的代码。我想做以下几点。但是我在 LoginStep1 类中的 getComponent(0) 处收到异常。我应该如何解决这个问题。我是瓦丁的新人。如果我的方法错误,则需要您的指导。

public class Login extends VerticalLayout implements View {
    public static String viewName = "login";
    public void enter(ViewChangeEvent event) {
        removeAllComponents();
        CustomLayout viewScreen = new CustomLayout("screens/screen-login");
        Component step1 = new LoginStep1().getLoginStep1();
        viewScreen.addComponent(step1, "login-steps");
        addComponent(viewScreen);
    }
}
@SuppressWarnings("serial")
public class LoginStep1 extends Login {
    public Component getLoginStep1() {
        CustomLayout stepScreen = new CustomLayout("components/screens/login-step1");
        Button loginBtn = CommonComponents.getButton("Login", "btn btn-green btn-block");
        loginBtn.addClickListener(new Button.ClickListener() {
            @Override
            public void buttonClick(ClickEvent event) {
                // this line gives me exception.
                CustomLayout currentLayout = (CustomLayout) getComponent(0);
                currentLayout.addComponent(new LoginStep2().getLoginStep2(request, posInfoResponse.getBody()), "login-steps");
            }
        });
    }
    stepScreen.addComponent(loginBtn,"login-btn");
    return stepScreen;
}

它给出了以下异常

com.vaadin.server.ServerRpcManager$RpcInvocationException: Unable to invoke method click in com.vaadin.shared.ui.button.ButtonServerRpc
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:160)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:118)
    at com.vaadin.server.communication.ServerRpcHandler.handleInvocations(ServerRpcHandler.java:408)
    at com.vaadin.server.communication.ServerRpcHandler.handleRpc(ServerRpcHandler.java:273)
    at com.vaadin.server.communication.UidlRequestHandler.synchronizedHandleRequest(UidlRequestHandler.java:79)
    at com.vaadin.server.SynchronizedRequestHandler.handleRequest(SynchronizedRequestHandler.java:41)
    at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
    at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.vaadin.server.ServerRpcManager.applyInvocation(ServerRpcManager.java:158)
    ... 29 more
Caused by: com.vaadin.event.ListenerMethod$MethodException: Invocation of method buttonClick in com.herman.login.LoginStep1$1 failed.
    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:528)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:198)
    at com.vaadin.event.EventRouter.fireEvent(EventRouter.java:161)
    at com.vaadin.server.AbstractClientConnector.fireEvent(AbstractClientConnector.java:1003)
    at com.vaadin.ui.Button.fireClick(Button.java:377)
    at com.vaadin.ui.Button$1.click(Button.java:54)
    ... 34 more
Caused by: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.LinkedList.checkElementIndex(Unknown Source)
    at java.util.LinkedList.get(Unknown Source)
    at com.vaadin.ui.AbstractOrderedLayout.getComponent(AbstractOrderedLayout.java:414)
    at com.herman.login.LoginStep1$1.buttonClick(LoginStep1.java:23)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.vaadin.event.ListenerMethod.receiveEvent(ListenerMethod.java:508)
    ... 39 more

有些事情仍然不清楚,因为你还没有回答所有的评论,所以我不确定您将 3 种实现(LoginLoginStep1LoginStep2 )中的哪一种用作导航器组件导航的视图。但是,查看 Login & LoginStep1 ,我可以看到您可能希望在当前设计中重新考虑的东西:您正在创建继承类的新实例并在其上调用方法,而不是使用当前实例......

由于LoginStep2的源代码不可用,我将尝试涵盖其他 2 种情况:

1) 假设您正在导航到 Login 的实例。

  • 调用 enter 方法时,将创建一个新的 LoginStep1 实例并将其添加到 CustomLayout 内的组件列表中。

  • 单击登录按钮时,将在LoginStep1的新实例上调用getComponent(0),该实例不会继承导航中使用的Login实例,因此它包含 0 个导致异常的组件

2) 假设您正在导航到 LoginStep1 的实例,该实例扩展了Login

  • 当触发 enter 事件并执行从超类继承的 enter 方法时,将创建一个新的 LoginStep1 实例并将其添加到 CustomLayout 内的组件列表中。

  • 当您单击登录按钮时,将在LoginStep1的新实例上调用getComponent(0),该实例与导航中使用的当前LoginView1实例无关,因此它包含 0 个导致异常的组件


总之,这更有可能与基本的Java继承概念有关,而不是与Vaadin有关,主要问题可能是Component step1 = new LoginStep1().getLoginStep1(); // <= why create a new instance?

public class Login extends VerticalLayout implements View {
    public static String viewName = "login";
    public void enter(ViewChangeEvent event) {
        removeAllComponents();
        CustomLayout viewScreen = new CustomLayout("screens/screen-login");
        Component step1 = new LoginStep1().getLoginStep1(); // <= why create a new instance?
        viewScreen.addComponent(step1, "login-steps");
        addComponent(viewScreen);
    }
}

最新更新