java – 渲染JList时更改光标
我已经实现了我想做的事情,但我不禁想到有一种更有效的方式……让我来说明一下.
简而言之,我要问的问题是,是否有办法确定组件何时完成初始渲染. 我有一个JList,它连接到一个DefaultListModel并由自定义渲染器绘制,该渲染器扩展了DefaultListCellRenderer. JList的这个意图是通过日志文件“页面”,每次加载新页面时填充2500个元素.在我的机器上,完全呈现JList通常需要几秒钟,这实际上不是问题,因为将光标更改为等待光标是可以接受的,因为它会给用户提供即时反馈.不幸的是,我无法找到一种优雅的方式来了解初始渲染何时完成. 下面是我的渲染器的代码,在其中你会看到我正在计算渲染器上的迭代次数.如果它在0和N-20之间,则光标变为等待光标.一旦达到N-20,它将恢复为默认光标.就像我之前提到的,这很好用,但解决方案真的像一个黑客.我已经实现了DefaultListModel的ListDataListener和JList的PropertyChangeListener,但是都没有生成我正在寻找的功能. /** * 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)); 解决方法
1)您已将Cursor添加到JList,而不是在Renderer中,例如
here或
here
2)Renderer默认返回JLabel,没有特殊原因来定义它 3)Renderer可以setBackground,Font为(在这种情况下)JLabel的任何方法 编辑: 4)删除retVal.setText(formatListBoxOutput((String)value,index));创建DefaulListModel并将准备好的项目移动到Model#addItem 5)int index,可以与JList#getModel().getSize()-1进行比较;从渲染器中删除它, 6)更好的是从BackGround任务添加你的项目(@trashgod你的建议是正确的:-)并填写批次(谢谢),如果你将实现SwingWorker,那么你可以创建50个项目的批处理并添加50. ..直到完成 7)渲染器仅用于格式化输出,您的Html格式化可能是: >删除,休息见第3点.>在BackGroung Task中编写而不是在Renderer之间构建构造函数并加载Html Formating向后向渲染器的交互,在这种情况下渲染器没用,因为你可以通过使用Html来预先构造项目,然后删除渲染器 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |