0

我遇到的问题很难重现,但我希望这里有人可以给我一个关于如何解决这个问题的提示。

我编写了一个ComponentProvider<JLabel>接受字符串值的方法,如果字符串包含 URL,则创建一个装饰有图标的可点击单元格。如果在字符串值中未找到 URL,则没有为标签设置图标并且单元格不应是可点击的。

这是代码:

public class ExternalLinkProvider extends ComponentProvider<JLabel> implements RolloverRenderer {

    private String url = null;

    @Override
    protected void format(CellContext context) {}

    @Override
    protected void configureState(CellContext context) {
        if (context.getValue() instanceof String) {
            String stringValue = (String) context.getValue();
            WwwLink link = new WwwLink(stringValue);

            // If this contains a valid Url, set a link icon.   
            if (link.isValid()) {
                rendererComponent.setIcon(ExternalLink.WWW_LINK_ICON);
                url = link.getUrl();
            } else {
                rendererComponent.setIcon(null);
                url = null;
            }
            rendererComponent.setText(link.getString());
        }
    }

    @Override
    protected JLabel createRendererComponent() {
        return new JRendererLabel();
    }

    @Override
    public boolean isEnabled() {
        return url != null;
    }

    @Override
    public void doClick() {
        if (url != null) {
              // Follow the url
        }
    }
}

它看起来像这样:

在此处输入图像描述

第一个单元格应该可以点击以跟随字符串值中的链接并已从显示文本中删除。第二个单元格不包含文本中的链接,因此不应该是可点击的。

但是,在这种情况下,两个单元格都不可点击,如果我存储字符串值并将其从该方法打印到控制台,isEnabled()我看到无论我将鼠标悬停在第一个还是第二个单元格上,总是会打印第二个单元格中的文本细胞。

这是我注意到这种行为的唯一情况。我知道每个包含此类型的单元格都会重用一个 Provider 实例,但由于某种原因,RolloverRenderer 在这种情况下似乎没有正确重新配置此 Provider。

我在这里做错了吗?

4

1 回答 1

1

玩了一会儿:你可能在这里遇到了问题——我们所有的例子都是可以点击的。基本上,在提供程序中保持与单元相关的状态是很脆弱的,因为它可能经常被调用并且对于其他单元。

RolloverRenderer 的 api 还不够丰富:该机制依赖于在单击发生之前配置的渲染器(因此“旧”状态仍然存在),对于您的用例来说还不够好 :-) 您可以考虑提交一个swingx 问题跟踪器中的错误报告,所以我们不要忘记查看它。谢谢。

可以使用的片段,基本上演示了在自定义提供程序中覆盖哪些方法(但不能解决手头的问题 - 除了用户不友好的 kludge 始终启用翻转......):

public class ExternalLinkProvider extends LabelProvider implements RolloverRenderer {

    private URL url = null;

    /**
     * Overridden to check for valid URL.
     */
    @Override
    protected void configureContent(CellContext context) {
        url = convertValueToUrl(context.getValue());
        super.configureContent(context);
    }

    private URL convertValueToUrl(Object result) {
        if (!(result instanceof String)) return null;
        URL url = null;

        try {
            url = new URL(result.toString());
        } catch (Exception e) {
            // TODO: handle exception
        }
        return url;

    }

    @Override
    protected Icon getValueAsIcon(CellContext context) {
        return url != null ? XTestUtils.loadDefaultIcon() : null;
    }

    /**
     * conditional enabled isn't reliably supported. Returning true 
     * uncondionally probably isn't option, as the cursor is changed ...
     */
    @Override
    public boolean isEnabled() {
        return true; //url != null;
    }

    @Override
    public void doClick() {
        if (url != null) {
              // Follow the url
            System.out.println("clicking");
        }
    }
}
于 2012-07-13T13:04:55.497 回答