Я достиг того, что пытаюсь сделать, но не могу не думать, что есть более эффективный способ ... позвольте мне проиллюстрировать.
Короче, вопрос, который я задаюЯ спрашиваю, есть ли способ определить, когда компонент завершил свою начальную визуализацию.
У меня есть JList, который подключается к DefaultListModel и получает нарисованный пользовательский рендерер, который расширяет DefaultListCellRenderer.
Это намерение JList - «пролистать» файл журнала, заполнив 2500 элементов каждый раз при загрузке новой страницы.На моем компьютере обычно требуется несколько секунд, чтобы полностью отобразить JList, что на самом деле не является проблемой, потому что изменение курсора на курсор ожидания будет приемлемым, поскольку это даст пользователю немедленную обратную связь.К сожалению, я не могу найти элегантный способ узнать, когда начальный рендеринг завершен.
Ниже приведен код моего рендерера, в нем вы увидите, что я считаю количество итераций в рендерере.Если это между 0 и N-20, курсор изменится на курсор ожидания.Как только N-20 достигнут, он возвращается к курсору по умолчанию.Как я уже упоминал ранее, это работает просто отлично, но решение действительно похоже на взлом.Я реализовал ListDataListener для DefaultListModel и PropertyChangeListener для JList, но ни одна из них не производит нужную мне функциональность.
/**
* Renders the MessageHistory List based on the search text and processed events
*/
public class MessageListRenderer extends DefaultListCellRenderer
{
private static final long serialVersionUID = 1L;
String lineCountWidth = Integer.toString(Integer.toString(m_MaxLineCount).length());
@Override
public Component getListCellRendererComponent(JList l, Object value, int index, boolean isSelected, boolean haveFocus)
{
JLabel retVal = (JLabel)super.getListCellRendererComponent(l, value, index, isSelected, haveFocus);
retVal.setText(formatListBoxOutput((String)value, index));
// initial rendering is beginning - change the cursor
if ((renderCounter == 0) && !renderCursorIsWait)
{
m_This.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
renderCursorIsWait = true;
}
// initial rendering is complete - change the cursor back
if ((renderCounter > (l.getModel().getSize() - 20)) && renderCursorIsWait)
{
m_This.setCursor(Cursor.getDefaultCursor());
renderCursorIsWait = false;
}
renderCounter++;
return retVal;
}
/**
* Adds font tags (marks as red) around all values which match the search criteria
*
* @param lineValue string to search in
* @param lineIndex line number being processed
* @return string containing the markup
*/
private String formatListBoxOutput(String lineValue, int lineIndex)
{
// Theoretically the count should never be zero or less, but this will avoid an exception just in case
if (m_MaxLineCount <= 0)
return lineValue;
String formattedLineNumber = String.format("%" + Integer.toString(Integer.toString(m_MaxLineCount).length()) + "s", m_CurrentPage.getStartLineNumber() + lineIndex) + ": ";
// We're not searching, simply return the line plus the added line number
if((m_lastSearchText == null) || m_lastSearchText.isEmpty())
return "<html><font color=\"#4682B4\">" + formattedLineNumber.replaceAll(" ", " ") + "</font>" + lineValue + "</html>";
// break up the search string by the search value in case there are multiple entries
String outText = "";
String[] listValues = lineValue.split(m_lastSearchText);
if(listValues.length > 1)
{
// HTML gets rid of the preceding whitespace, so change it to the HTML code
outText = "<html><font color=\"#4682B4\">" + formattedLineNumber.replaceAll(" ", " ") + "</font>";
for(int i = 0; i < listValues.length; i++)
{
outText += listValues[i];
if(i + 1 < listValues.length)
outText += "<font color=\"red\">" + m_lastSearchText + "</font>";
}
return outText + "</html>";
}
return "<html><font color=\"#4682B4\">" + formattedLineNumber.replaceAll(" ", " ") + "</font>" + lineValue + "</html>";
}
}
Все, что я делаю для заполнения модели, это:
// reset the rendering counter
this.renderCounter = 0;
// Reset the message history and add all new values
this.modelLogFileData.clear();
for (int i = 0; i < this.m_CurrentPage.getLines().size(); i++)
this.modelLogFileData.addElement(this.m_CurrentPage.getLines().elementAt(i));