我遇到的问题难以复制,但我希望有人能给我一些如何解决这个问题的提示。
我写了一个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
}
}
}
看起来像这样:
第一个单元格应该是可单击的,以跟随字符串值中的链接并已从显示文本中删除。第二个单元格在文本中不包含链接,因此不应该是可点击的。
但是,在这种情况下,两个单元格都不可单击,如果我存储字符串值并从isEnabled()
方法将其打印到控制台,我看到始终打印第二个单元格中的文本,无论是否我将鼠标悬停在第一个或第二个细胞上。
这是我注意到这种行为的唯一情况。我知道一个Provider实例被重用于包含此类型的每个单元格,但由于某种原因,RolloverRenderer似乎在这种情况下没有正确地重新配置此Provider。
我在这里做错了吗?
答案 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");
}
}
}