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

ZK-从ItemRenderer访问GUI元素

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

    在我的ZK项目中,访问模型类之外的GUI元素时遇到问题。我有一个ListItemRenderer,当我单击列表框中的一个元素时,它会呈现数据和相应模型的位置,但当我再次访问article类时,我的实例将永久为空,并且当我第一次创建该类时(通过getFellow())连接的所有GUI元素也都是空的。这是正确的方法吗?或者,我是否可以将侦听器添加到一个变量中,如果文本框发生更改,该变量将重新加载文本框?谢谢你的每一个提示,我已经有好几个令人沮丧的小时了,希望代码片段足够了。

    ZUL公司:

    <?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" root="./winArticles"?>
    <window id="winArticles" title="Looking for Evidence" width="1100px"  height="880px" 
    border="normal" use="xxx.Articles" closable="true" sizable="false">
    ...
     <listbox id="artikel_output" width="100%" height="" multiple="true"  
              checkmark="true"   vflex="true" nonselectableTags="*">
     <listhead>
          <listheader label="Artikel"/> 
     </listhead> 
     </listbox> 
    ...
          <div   vflex="1">
                <textbox style="font-size:50px" 
                         id="tb_article_abstract"
                         multiline="true"/>
         </div>
    ...
    </window>
    

    型号:

    public class Articles extends Window implements AfterCompose, 
    IGenericDomainValueSelectorActions, IUpdateModal, IGenericListActions {
         private static Articles instance;
    
    public Articles() { }
    
    public static Articles getInstance() { 
        if (instance == null) {
            instance = new Articles();
        }
        logger.debug("Instance getInstance " + instance.getId());
        return instance;
    }
    
    @Override
    public void afterCompose() {
        instance = new Articles(); 
        tb_article_abstract = (Textbox) getFellow("tb_article_abstract");  
      ...}
    

    初始化列表框呈现器:

    public void fillListBoxWithArticles(final Listbox lb, List<Article> articles) {  
        if (articles.size() == 0) {
            lb.appendChild((Component) articles.get(0));
        } 
        lb.setItemRenderer(new ArticleItemRenderer());        
        lb.setCheckmark(true);
        lb.setMultiple(true); 
        ListModelList<Article> lml_articles = new ListModelList<Article>(articles);
        lml_articles.setMultiple(true);
        lb.setModel(lml_articles); 
        lb.focus();
    }
    

    如果已选择列表框元素,请在文本框中显示其属性,但文本框始终为空。。。

    public void setArticleToInfobox(Article selectedArticle, int selectedIndex) {
        this.selectedArticle = selectedArticle;  
        // tb_article_abstract = null 
        tb_article_abstract.setValue(selectedArticle.getAbstract_full());
        tb_article_abstract.invalidate();
    }}
    

    ItemRenderer正在获取所选项目的数据(和索引):

    public class ArticleItemRenderer implements ListitemRenderer<Article> {  
    @Override
    public void render(Listitem item, Article data, int index) throws Exception {
    
        item.appendChild(new Listcell(data.getArticletitle() + ", "  ); 
        item.addEventListener(Events.ON_CLICK, new EventListener() {
            @Override 
            public void onEvent(Event event) throws Exception {     
                EvidenceBasedArticles.getInstance().setArticleToInfobox(data, item.getIndex());
            }});}
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   chillworld    6 年前

    你在这里犯了一些严重的错误。

    public static Articles getInstance() { 
        if (instance == null) {
            instance = new Articles();
        }
        logger.debug("Instance getInstance " + instance.getId());
        return instance;
    }
    

    这永远不会奏效,您正在开发一个web应用程序。
    这意味着2个用户同时只能有1个实例,但是您的文章被分配到特定的桌面,因此1个用户将有问题。

    有什么问题:

    lb.setItemRenderer(new ArticleItemRenderer(tb_article_abstract));
    

    渲染器具有此特定类的新实例,因此它绑定到正确的桌面。
    只要不从DOM中删除该项,就不会有问题。

    推荐文章