呈现JList时更改光标 [英] Changing cursor when rendering a JList

查看:88
本文介绍了呈现JList时更改光标的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经实现了我想做的事情,但是我不禁想到有一种更有效的方法……让我举例说明.

I've achieved what I'm trying to do, but I can't help but to think there is a more efficient way...allow me to illustrate.

简而言之,我要问的问题是,是否有一种方法可以确定组件何时完成其初始渲染.

In short, the question I'm asking is if there's a way to determine when a component has finished it's initial rendering.

我有一个JList,它连接到DefaultListModel并由扩展DefaultListCellRenderer的自定义渲染器绘制.

I have a JList, which is hooked up to a DefaultListModel and getting painted by a custom renderer which extends the DefaultListCellRenderer.

JList的目的是通过日志文件分页",每次加载新页面时,将填充2500个元素.在我的机器上,通常需要花费几秒钟来完全呈现JList,这并不是一个真正的问题,因为将光标更改为等待光标是可以接受的,因为它将立即为用户提供反馈.不幸的是,我无法找到一种优雅的方式来知道初始渲染何时完成.

This intention of the JList is to "page" through a log file, populating 2500 elements every time a new page is loaded. On my machine it usually takes a couple seconds to fully render the JList, which is not really a problem because changing the cursor to a wait cursor would be acceptable because it would give the user immediate feedback. Unfortunately, I cannot figure out an elegant way to know when the initial rendering has completed.

下面是渲染器的代码,在其中,您将看到我正在计算渲染器上的迭代次数.如果介于0到N-20之间,则光标变为等待光标.到达N-20后,它将恢复为默认光标.就像我之前提到的那样,这很好用,但是该解决方案确实感觉像是黑客.我已经实现了DefaultListModel的ListDataListener和JList的PropertyChangeListener,但是都没有实现我想要的功能.

Below is the code of my renderer, in it you'll see I'm counting the number of iterations on the renderer. If that is between 0 and N-20, the cursor changes to a wait cursor. Once N-20 has been reached, it reverts back to a default cursor. Like I previously mentioned, this works just fine, but the solution really feels like a hack. I've implemented the ListDataListener of the DefaultListModel and the PropertyChangeListener of the JList, but neither produce the functionality I'm looking for.

/**
 * 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(" ", "&nbsp;") + "</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(" ", "&nbsp;") + "</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(" ", "&nbsp;") + "</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内部,例如此处

1) you have add Cursor to the JList, not inside Renderer, example here or here

2)默认情况下,Renderer返回JLabel,没有特殊的理由来定义

2) Renderer by default returns JLabel, there isn't special reason for defining that

3)Renderer可以setBackgroundFont(在这种情况下)JLabel

3) Renderer can setBackground, Font whatever methods for (in this case) the JLabel

4)删除retVal.setText(formatListBoxOutput((String)value, index));创建DefaulListModel并将准备好的项目移至Model#addItem

4) remove retVal.setText(formatListBoxOutput((String)value, index)); create DefaulListModel and move prepared Items to the Model#addItem

5)int index,可以与JList#getModel().getSize() -1;进行比较,将其从Renderer中删除,

5) int index, can compare with JList#getModel().getSize() -1; remove that from Renderer,

6)最好是从BackGround Task添加项目(@trashgod,您的建议是正确的:-)并填写批次(谢谢),如果您要实现SwingWorker,则可以在50个Items上创建批次并添加50 ...直到完成

6) better would be add your Items from BackGround Task (@trashgod your suggestion was right:-) and fill in batches (thank you), if you'll implemnts SwingWorker, then you can create batch at 50 Items and adding by 50... until done

7)渲染器仅用于格式化输出,您的HTML格式化可能是:

7) Renderer is only for formating output, your Html formating could be:

  • 已移除,其余请参阅第3点.
  • 是在BackGroung任务中准备的,而不是在Renderer和加载之间进行构建的构造函数,并且+ html格式+向Renderer的向后交互,在这种情况下,Renderer没用,因为您可以使用Html预先格式化项目,然后删除Renderer.

这篇关于呈现JList时更改光标的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆