Java 如何创建提供自己标记的链接?

Java 如何创建提供自己标记的链接?,java,wicket,Java,Wicket,我正在尝试创建一个链接,该链接将隐藏或显示我页面的一部分。该链接应可重用,并根据状态显示两个图像中的一个 在我使用链接的每个页面上添加两个子组件有点笨重,所以我想创建一个组件,在自动添加其内容时,其行为类似于链接 这是链接组件: public class ToggleVisibilityLink extends AjaxFallbackLink<Boolean> { public ToggleVisibilityLink(final String id, final IModel

我正在尝试创建一个链接,该链接将隐藏或显示我页面的一部分。该链接应可重用,并根据状态显示两个图像中的一个

在我使用链接的每个页面上添加两个子组件有点笨重,所以我想创建一个组件,在自动添加其内容时,其行为类似于链接

这是链接组件:

public class ToggleVisibilityLink extends AjaxFallbackLink<Boolean>
{
  public ToggleVisibilityLink(final String id, final IModel<Boolean> model)
  {
    super(id, model);

    setOutputMarkupId(true);

    add(new Image("collapseImage")
    {
      @Override
      public boolean isVisible()
      {
        return !getModelObject();
      }
    });
    add(new Image("expandImage")
    {
      @Override
      public boolean isVisible()
      {
        return getModelObject();
      }
    });
  }

  @Override
  public void onClick(final AjaxRequestTarget target)
  {
    setModelObject(!getModelObject());
    if (target != null)
    {
      target.add(this);
      send(this.getParent(), Broadcast.EXACT, target);
    }
  }
}
但我希望能够跳过链接中的主体,因为人们必须了解ToggleVisibilityLink的内部结构。 我尝试使用IMarkupResourceStreamProvider作为起点。通过谷歌搜索,我发现了另一个例子,海报只有在工作时才能起作用,我也能做到这一点。但我真的希望保留链接,而不是将其打包到面板中,因为我无法在标记中设置链接的样式


我也愿意使用其他方法来封装链接及其主体。

我能够使用setBody()来实现这一点,尽管我试图严重破坏自己(我有重复的库、我自己不兼容的jQuery库导入和自定义资源版本控制策略)

以下是当前的ToggleVisibilityLink:

public class ToggleVisibilityLink extends AjaxFallbackLink<Boolean>
{
  static {
    Application.get().getSharedResources().add("ToggleVisibilityLinkCollapse",
                                               new MyPackageResource(ToggleVisibilityLink.class, "collapse.png"));
    Application.get().getSharedResources().add("ToggleVisibilityLinkExpand",
                                               new MyPackageResource(ToggleVisibilityLink.class, "expand.png"));
  }

  public ToggleVisibilityLink(final String id, final IModel<Boolean> model)
  {
    super(id, model);

    setOutputMarkupId(true);
    setEscapeModelStrings(false);

    setBody(new BodyModel(model));
  }

  @Override
  public void onClick(final AjaxRequestTarget target)
  {
    setModelObject(!getModelObject());
    if (target != null)
    {
      target.add(this);
      send(this.getParent(), Broadcast.EXACT, target);
    }
  }

  private static final class BodyModel extends AbstractReadOnlyModel<String>
  {
    private final IModel<Boolean> model;

    private BodyModel(final IModel<Boolean> model)
    {
      this.model = model;
    }

    @Override
    public String getObject()
    {
      return this.model.getObject() ?
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkExpand"), null)
            + "\" class=\"collapseExpandImage expand\">"
              :
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkCollapse"), null)
            + "\" class=\"collapseExpandImage collapse\">";
    }
  }
}



并在单击链接时通过事件得到通知。

我能够使用setBody()实现这一点,尽管我试图严重破坏自己(我有重复的库、我自己不兼容的jQuery库导入和自定义资源版本控制策略)

以下是当前的ToggleVisibilityLink:

public class ToggleVisibilityLink extends AjaxFallbackLink<Boolean>
{
  static {
    Application.get().getSharedResources().add("ToggleVisibilityLinkCollapse",
                                               new MyPackageResource(ToggleVisibilityLink.class, "collapse.png"));
    Application.get().getSharedResources().add("ToggleVisibilityLinkExpand",
                                               new MyPackageResource(ToggleVisibilityLink.class, "expand.png"));
  }

  public ToggleVisibilityLink(final String id, final IModel<Boolean> model)
  {
    super(id, model);

    setOutputMarkupId(true);
    setEscapeModelStrings(false);

    setBody(new BodyModel(model));
  }

  @Override
  public void onClick(final AjaxRequestTarget target)
  {
    setModelObject(!getModelObject());
    if (target != null)
    {
      target.add(this);
      send(this.getParent(), Broadcast.EXACT, target);
    }
  }

  private static final class BodyModel extends AbstractReadOnlyModel<String>
  {
    private final IModel<Boolean> model;

    private BodyModel(final IModel<Boolean> model)
    {
      this.model = model;
    }

    @Override
    public String getObject()
    {
      return this.model.getObject() ?
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkExpand"), null)
            + "\" class=\"collapseExpandImage expand\">"
              :
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkCollapse"), null)
            + "\" class=\"collapseExpandImage collapse\">";
    }
  }
}



单击链接时通过事件获得通知。

您是否尝试过覆盖
onComponentTagBody()
?您可以通过创建面板来创建带有标记的可重用组件。我考虑过这一点(现在使用
setBody()
,因为链接已经实现了
onComponentTagBody()
来启用/禁用链接),但是我该如何渲染这些图像呢?具体来说,我该如何获取图像的URL?因为我可以使用此方法动态呈现HTML标记(考虑要显示的图像),但我需要一个
src
属性。我曾考虑将它们作为一种资源挂载,但为了完全封装组件,我希望避免这种情况。@ChristophLeiter:但我不能简单地将其用作链接,因为我必须将其放入某种容器中或使用
setRenderBodyOnly(true)
。它们都有各自的问题,例如附加CSS类和需要实现onClick()机制。@biziclop:我找到了
urlFor(resourceReference,pageParameters)
方法来检索图像的URL。不过,我还得稍微修改一下,因为提供的URL不太正确。它在名称后面附加一个-ver-0_0_1,前面有一个冗余的/wicket。。。谢谢你的提示!:)您是否尝试过覆盖
onComponentTagBody()
?您可以通过创建一个面板来创建一个带有标记的可重用组件。我考虑过这一点(现在使用
setBody()
,尝试过它,因为Link已经实现了
onComponentTagBody()
来启用/禁用链接),但我该如何呈现图像呢?具体来说,我该如何获取图像的URL?因为我可以使用此方法动态呈现HTML标记(考虑要显示的图像),但我需要一个
src
属性。我曾考虑将它们作为一种资源挂载,但为了完全封装组件,我希望避免这种情况。@ChristophLeiter:但我不能简单地将其用作链接,因为我必须将其放入某种容器中或使用
setRenderBodyOnly(true)
。它们都有各自的问题,例如附加CSS类和需要实现onClick()机制。@biziclop:我找到了
urlFor(resourceReference,pageParameters)
方法来检索图像的URL。不过,我还得稍微修改一下,因为提供的URL不太正确。它在名称后面附加一个-ver-0_0_1,前面有一个冗余的/wicket。。。谢谢你的提示!:)
public class ToggleVisibilityLink extends AjaxFallbackLink<Boolean>
{
  static {
    Application.get().getSharedResources().add("ToggleVisibilityLinkCollapse",
                                               new MyPackageResource(ToggleVisibilityLink.class, "collapse.png"));
    Application.get().getSharedResources().add("ToggleVisibilityLinkExpand",
                                               new MyPackageResource(ToggleVisibilityLink.class, "expand.png"));
  }

  public ToggleVisibilityLink(final String id, final IModel<Boolean> model)
  {
    super(id, model);

    setOutputMarkupId(true);
    setEscapeModelStrings(false);

    setBody(new BodyModel(model));
  }

  @Override
  public void onClick(final AjaxRequestTarget target)
  {
    setModelObject(!getModelObject());
    if (target != null)
    {
      target.add(this);
      send(this.getParent(), Broadcast.EXACT, target);
    }
  }

  private static final class BodyModel extends AbstractReadOnlyModel<String>
  {
    private final IModel<Boolean> model;

    private BodyModel(final IModel<Boolean> model)
    {
      this.model = model;
    }

    @Override
    public String getObject()
    {
      return this.model.getObject() ?
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkExpand"), null)
            + "\" class=\"collapseExpandImage expand\">"
              :
              "<img src=\""
            + RequestCycle.get().urlFor(new SharedResourceReference("ToggleVisibilityLinkCollapse"), null)
            + "\" class=\"collapseExpandImage collapse\">";
    }
  }
}
super.add(new ToggleVisibilityLink("collapseExpandLink", new PropertyModel(this, "hidden")));
<a wicket:id="collapseExpandLink" class="collapseExpandLink"></a>