2013-07-26 2 views
2

Быстрый вопрос о примере кода в JavaDoc for javax.swing.ListCellRenderer:Функциональность свинг ListCellRenderer

Я немного удивлен, что в этом примере ListCellRenderer реализуется классом, который простирается JLabel и что getListCellRendererComponent(...) -метода просто возвращает this. Похоже, что тогда есть только один экземпляр JLabel, даже для списка, содержащего более одного элемента.

Обычно я ожидал, что когда метод setText(...) вызывается внутри getListCellRendererComponent(...) для второго элемента в списке, он меняет метку уже существующего первого элемента в списке. Или, на самом деле, вероятно, не должно быть даже возможным, чтобы список использовал один и тот же код JLabel - в два раза (или более раз) один раз для каждого элемента в списке.

Теперь, я пришел с двумя возможными способами, чтобы решить эту проблему, и было интересно, какой из них (если таковые имеются), на самом деле происходит:

  • ли JList каким-то образом создать новые экземпляры предоставленному ListCellRenderer для каждого списка пункт?
  • Или он использует компонент, возвращаемый getListCellRendererComponent(...), только для вызова метода paint(...) на холсте списка, а не добавления этого компонента в какую-либо панель?
+0

ListCellRenderer отвечает за декорирования виртуальной картины JList, JComboBox, визуализатор вызываются из всех мышей и ключевых событий, оповещатели, реализованные в конкретных API Q: 'как-то JList ... '---> да, но ответ не« Или он использует ... »---> - да окраска только виртуальных JComponents как элемент в прямоугольники JLists – mKorbel

+0

@mKorbel: Теперь я смущен. ;) «рисование только виртуальных JComponents как элементов в прямоугольниках JLists» - это то, что я имел в виду в «Или он использует ...». Но в предложении, прежде чем вы напишите, что это неверный. :) –

ответ

3

Когда JList делает сам, он запрашивает ListModel для элементов, которые он должен отображать. Для каждого элемента он вызывает javax.swing.ListCellRenderer для предоставления компонента рендеринга. Затем он окрашивает компонент. Это все. Компонент render не привязан к состоянию элемента, которое он отображает.

Javadoc из ListCellRenderer говорит:

Определяет компоненты, которые могут быть использованы в качестве «резиновых штампов» красить клетки в 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); 
} 
+0

Поэтому он фактически не добавляет компонент, возвращаемый ListCellRenderer, на какую-то панель. Он использует только метод рисования? –

+0

Да, да. Я обновил ответ. BasicListUI расширяет ListUI, который является пользовательским интерфейсом для JList (JList.getUI()). –

+0

Возможно, полезно добавить выдержку из источника «CellRendererPane», показывая, что 'rendererPane.paintComponent (...)' только вызывает 'rendererComponent.paint (...)', но из имени и аргументов функции, это технически уже очевидно. :) Благодаря! +1, v' –

Смежные вопросы