代码之家  ›  专栏  ›  技术社区  ›  Tyvain

vaadin 10-推标签不会更新

  •  1
  • Tyvain  · 技术社区  · 6 年前

    @Push
    @Route
    public class MainView extends VerticalLayout {       
        InformationComponent infoComponent;
    
        public MainView(@Autowired StudentRepository studentRepo, @Autowired Job jobImportCsv, @Autowired JobLauncher jobLauncher, @Value("${file.local-tmp-file}") String inputFile) {     
        [...] // some stuffs
    
        infoComponent = new InformationComponent(studentRepo);
        add(infoComponent);
        }
    
        //update when job process is over
        private void uploadFileSuccceed() {
           infoComponent.update(myUploadComponent.getFile());
        }
    

    信息组件:

    public class InformationComponent extends HorizontalLayout {
    
        StudentRepository studentRepo;
    
        Label nbLineInFile = new Label();
    
        VerticalLayout componentLeft = new VerticalLayout();;
        VerticalLayout componentRight = new VerticalLayout();;
    
        public InformationComponent(StudentRepository studentRepo) {
        [...] // some init and style stuff
    
        addLine("Nombre de lignes dans le fichier", nbLineInFile);
        }
    
        private void addLine(String label, Label value) {
        componentLeft.add(new Label(label));
        componentRight.add(value);
        }
    
        public void update(File file) {
        try {
    
    
            long nbLines = Files.lines(file.toPath(), Charset.defaultCharset()).count();
    
            System.out.println("UPDATED! " +nbLines); // value is display in console ok!
            UI.getCurrent().access(() -> nbLineInFile.setText(nbLines)); // UI is not updated!!
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
      }
    }
    

    当我从MainView调用InformationComponent时 .

    UI.getCurrent().access(() -> nbLineInFile.setText(nbLines))
    

    也可以尝试使用@Push(PushMode.MANUAL)和ui.Push();但也不起作用。。。

    https://github.com/Tyvain/ProcessUploadedFile-Vaadin_SpringBatch/tree/push-not-working

    2 回复  |  直到 6 年前
        1
  •  4
  •   Leif Åstrand    6 年前

    我想问题是 uploadFileSuccceed() 从后台线程运行,在这种情况下 UI.getCurrent() 会回来的 null . 这会导致 NullPointerException 它要么杀死后台线程,要么捕获异常并被调用者忽略。另一个选择是 上传文件成功() 在不同的浏览器窗口中发生,因此 UI 用户界面 .

    UI.getCurrent().access(...) 通常是一种反模式,尽管不幸的是它在旧示例中被广泛使用。

    您可以通过记录 UI.getCurrent() update UI.getCurrent() InformationComponent .

    用户界面 从任何触发后台处理启动的事件开始的整个事件链的实例。您还应该注意,使用 getUI() 可用于任何 Component 子类,但该方法不是线程安全的,因此应在后台线程中避免使用。

    最后,我建议您使用 Span Text Label 在这种情况下。在Vaadin 10中 标签 <label> HTML元素,这意味着它主要用作输入组件的标签。

        2
  •  0
  •   Basil Bourque    6 年前

    根据Leif提供的信息,您应该执行如下示例所示的操作。

    在运行时,当 HorizontalLayout 子类对象附加到父类 UI 对象,其 onAttach ui . 实际上,一个 Optional<UI> 返回而不是 UI 对象,因此我们需要测试null,尽管在 奥纳塔奇

    public class InformationComponent extends HorizontalLayout {
    
        UI ui;
    
        StudentRepository studentRepo;
    
        Label nbLineInFile = new Label();
    
        VerticalLayout componentLeft = new VerticalLayout();;
        VerticalLayout componentRight = new VerticalLayout();;
    
        public InformationComponent(StudentRepository studentRepo) {
            [...] // some init and style stuff
    
            addLine("Nombre de lignes dans le fichier", nbLineInFile);
        }
    
        private void addLine(String label, Label value) {
            componentLeft.add(new Label(label));
            componentRight.add(value);
        }
    
        public void update(File file) {
        try {
            long nbLines = Files.lines(file.toPath(), Charset.defaultCharset()).count();
    
            System.out.println("UPDATED! " +nbLines); // value is display in console ok!
            this.ui.access(() -> nbLineInFile.setText(nbLines)); // UI is not updated!!
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (UIDetachedException e) {
            // Do here what is needed to do if UI is no longer attached, user has closed the browser
        }
    
        @Override  // Called when this component (this `HorizontalLayout`) is attached to a `UI` object.
        public void onAttach() {
            ui = this.getUI().orElseThrow( () -> new IllegalStateException("No UI found, which should be impossible at point of `onAttach` being called.") );
    
    }