为什么RolloverRenderer使用错误的单元格上下文

时间:2012-07-12 08:23:57

标签: swingx jxtable

我遇到的问题难以复制,但我希望有人能给我一些如何解决这个问题的提示。

我写了一个ComponentProvider<JLabel>,它接受​​一个String值,如果String包含一个URL,则创建一个用图标装饰的可点击单元格。如果在String值中找不到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
        }
    }
}

看起来像这样:

enter image description here

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

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

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

我在这里做错了吗?

1 个答案:

答案 0 :(得分: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");
        }
    }
}