【问题标题】:Functionality of Swing ListCellRendererSwing ListCellRenderer 的功能
【发布时间】:2013-07-26 12:33:04
【问题描述】:

关于JavaDoc for javax.swing.ListCellRenderer 中示例代码的快速问题:

我有点惊讶,在示例中,ListCellRenderer 是由扩展 JLabel 的类实现的,而 getListCellRendererComponent(...) 方法仅返回 this。看起来当时只有一个 JLabel 的实例,即使对于包含多个元素的列表也是如此。

通常,我希望当setText(...) 方法在getListCellRendererComponent(...) 内为列表中的第二项调用时,它会更改列表中已经存在的第一项的标签。或者,实际上,列表甚至不可能使用相同的JLabel-instance 两次(或多次),列表中的每个项目一次。

现在,我想出了两种可能的方法来解决这个问题,并且想知道哪一种(如果有的话)实际发生了:

  • JList 是否以某种方式为每个列表项创建所提供ListCellRenderer 的新实例?
  • 还是它使用getListCellRendererComponent(...) 返回的组件只是在列表的画布上调用其paint(...) 方法,而不是实际将此组件添加到某个面板?

【问题讨论】:

  • ListCellRenderer 负责将虚拟绘画装饰到JList,JComboBox,从所有鼠标和按键事件中调用渲染器,具体API中实现的通知器Q:Does JList somehow ... --->是但答案不是@ 987654336@---> - 是的,仅将虚拟 JComponents 作为 Item 绘制到 JLists 矩形中
  • @mKorbel:现在我很困惑。 ;) “仅将虚拟 JComponents 作为项目绘制到 JLists 矩形中”是我在“或者它是否使用...”中的意思。但是在你写之前的句子中,那个是错误的。 :)

标签: java swing jlist listcellrenderer


【解决方案1】:

JList 呈现自己时,它会向ListModel 询问它应该显示的元素。 对于每个元素,它调用javax.swing.ListCellRenderer 来提供一个渲染组件。然后它绘制组件。就这样。渲染组件不绑定到它渲染的元素状态。

ListCellRenderer 的 javadoc 说:

标识可用作“橡皮图章”的组件 在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);
}

【讨论】:

  • 所以它实际上并没有将 ListCellRenderer 返回的组件添加到某个面板。它只使用它的paint方法?
  • 是的。我更新了答案。 BasicListUI 扩展了 ListUI,它是 JList ( JList.getUI() ) 的 UI。
  • 也许添加CellRendererPane 源代码的摘录也很有用,表明rendererPane.paintComponent(...) 只调用rendererComponent.paint(...),但从函数的名称和参数来看,技术上已经很明显了。 :) 谢谢! +1,v'
猜你喜欢
  • 1970-01-01
  • 2017-02-22
  • 1970-01-01
  • 2014-04-04
  • 2012-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多