关于JavaDoc for javax.swing.ListCellRenderer
中的示例代码的一个简单问题:
我有点惊讶,在示例中,ListCellRenderer
是由扩展 JLabel
的类实现的,并且 getListCellRendererComponent(... )
-方法简单地返回this
。看起来当时只有一个 JLabel
实例,即使对于包含多个元素的列表也是如此。
通常,我会期望当在 getListCellRendererComponent(...)
中调用列表中第二项的 setText(...)
方法时,它更改列表中已存在的第一项的标签。或者,实际上,列表甚至不可能两次(或多次)使用相同的 JLabel
实例,即列表中的每个项目一次。
现在,我想出了两种可能的方法来解决这个问题,并且想知道哪一种(如果有)实际上正在发生:
JList
是否以某种方式为每个列表项创建所提供的ListCellRenderer
的新实例?- 或者它是否仅使用
getListCellRendererComponent(...)
返回的组件来调用列表 Canvas 上的paint(...)
方法,而不是实际添加这个组件到某个面板?
最佳答案
当JList
呈现自身时,它会向ListModel
询问它应该显示的元素。
对于每个元素,它调用 javax.swing.ListCellRenderer 来提供呈现组件。然后它绘制组件。就这样。渲染组件不绑定(bind)到它渲染的元素的状态。
ListCellRenderer
的 javadoc 说:
Identifies components that can be used as "rubber stamps" to paint the cells in a
JList
.
所以你的第二个假设是正确的。
看看javax.swing.plaf.BasicListUI
就知道了:
protected void paintCell(Graphics g, int row, Rectangle rowBounds,
ListCellRenderer cellRenderer, ListModel dataModel,
ListSelectionModel selModel, int leadIndex) {
Object value = dataModel.getElementAt(row);
boolean cellHasFocus = list.hasFocus() && (row == leadIndex);
boolean isSelected = selModel.isSelectedIndex(row);
Component rendererComponent = cellRenderer
.getListCellRendererComponent(list, value, row, isSelected,
cellHasFocus);
int cx = rowBounds.x;
int cy = rowBounds.y;
int cw = rowBounds.width;
int ch = rowBounds.height;
if (isFileList) {
// Shrink renderer to preferred size. This is mostly used on Windows
// where selection is only shown around the file name, instead of
// across the whole list cell.
int w = Math
.min(cw, rendererComponent.getPreferredSize().width + 4);
if (!isLeftToRight) {
cx += (cw - w);
}
cw = w;
}
rendererPane.paintComponent(g, rendererComponent, list, cx, cy, cw, ch,
true);
}
关于java - Swing ListCellRenderer 的功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17881421/