getAccessibleChild() 方法的 JTable 奇怪行为导致客户端代码中出现空指针

发布于 2024-09-06 01:48:49 字数 1743 浏览 4 评论 0原文

我遇到了 JTable (JDK 1.5_22) 的奇怪行为:
在表中进行选择更改后以及在某些未知的特定情况下,JTable 将使用值参数“null”来调用单元格渲染器。
这最终将导致自定义渲染器代码上出现一个很好的“空指针异常”,而该代码尚未准备好进行此类粗鲁的调用。

这是有罪的方法(JTable.java,第 5319 行):

public Accessible getAccessibleChild(int i) {
            if (i < 0 || i >= getAccessibleChildrenCount()) {
                return null;
            } else {
                // children increase across, and then down, for tables
                // (arbitrary decision)
                int column = getAccessibleColumnAtIndex(i);
                int row = getAccessibleRowAtIndex(i);

                TableColumn aColumn = getColumnModel().getColumn(column);
                TableCellRenderer renderer = aColumn.getCellRenderer();
                if (renderer == null) {
                    Class<?> columnClass = getColumnClass(column);
                    renderer = getDefaultRenderer(columnClass);
                }
                Component component = renderer.getTableCellRendererComponent(
                                  JTable.this, null, false, false,
                                  row, column);
                return new AccessibleJTableCell(JTable.this, row, column,
                      getAccessibleIndexAt(row, column));
            }
        }

这里重点关注错误的语句:

Component component = renderer.getTableCellRendererComponent(
                                  JTable.this, null, false, false,
                                  row, column);

询问 googlewhith“JTable getAccessibleChild 5334”很有趣:我并不是唯一一个遇到这个“功能”的人。但没有得到任何答复。

最完善的问题位于官方 Sun 论坛

有人对此有线索吗?

I've encountered a strange behavior from JTable (JDK 1.5_22):
After a selection change in the table and under some unknown particular circumstances, the JTable will call the cell renderer with 'null' for the value parameter.
This will eventually lead to a nice 'Null Pointer Exception' on a custom renderer code that is not ready for such a rude call.

Here is the guilty method (JTable.java, line 5319) :

public Accessible getAccessibleChild(int i) {
            if (i < 0 || i >= getAccessibleChildrenCount()) {
                return null;
            } else {
                // children increase across, and then down, for tables
                // (arbitrary decision)
                int column = getAccessibleColumnAtIndex(i);
                int row = getAccessibleRowAtIndex(i);

                TableColumn aColumn = getColumnModel().getColumn(column);
                TableCellRenderer renderer = aColumn.getCellRenderer();
                if (renderer == null) {
                    Class<?> columnClass = getColumnClass(column);
                    renderer = getDefaultRenderer(columnClass);
                }
                Component component = renderer.getTableCellRendererComponent(
                                  JTable.this, null, false, false,
                                  row, column);
                return new AccessibleJTableCell(JTable.this, row, column,
                      getAccessibleIndexAt(row, column));
            }
        }

and here is a focus on the faulty statement:

Component component = renderer.getTableCellRendererComponent(
                                  JTable.this, null, false, false,
                                  row, column);

Asking google whith "JTable getAccessibleChild 5334" was interesting: I'm not alone to encounter this 'feature'. But there were no answer.

Most well formulated question is located on official sun forum.

Does anyone have a clue about this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

↘人皮目录ツ 2024-09-13 01:48:49

这不是同步或 EDT 问题。 JTable 中的代码使用 null 值显式调用 getTableCellRendererComponent

返回的值从未被使用过,因此,从表面上看,它看起来很像旧的调试代码。但是我怀疑它不会破坏期望在访问单元格之前调用 getTableCellRendererComponent 的代码。

Sun 之前曾就这个问题进行过咨询,他们的答案是 API 不保证 value 不为 null,因此当使用 null 调用时,getTableCellRendererComponent 必须正常失败。

It's not a synchronization or EDT issue. The code in JTable is explicitly calling getTableCellRendererComponent with a null value.

The value returned is never used, so, on the surface, it rather looks like old debugging code. However I suspect it is there to not break code that expects getTableCellRendererComponent to be called before a cell is accessed.

Sun has been called on this issue before and their answer was that the API makes no guarantees that value is non-null, so getTableCellRendererComponent must fail gracefully when called with a null.

じее 2024-09-13 01:48:49

每当我看到像这样无法解释的问题时,我都会想知道同步是否不正确。例如,

1) 未能在 事件调度上构造组件线程

2) 在其他线程上改变组件的模型。

在存在复杂初始化、具有意外延迟的模型或不同硬件的情况下,违规行为会更频繁地出现。也可能存在错误,但是这两点值得检查。

Anytime I see otherwise inexplicable problems like this, I wonder about incorrect synchronization. For example,

1) Failing to construct the component on the event dispatch thread.

2) Mutating the component's model on some other thread.

Violations manifest more frequently in the presence of complex initialization, a model with unexpected latency, or different hardware. There may also be a bug, but these two points are worth checking.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文