Re: efficiency of JList setElementAt()



Raymond Cruz wrote:
Thanks Tom.  I agree with your results when I run your program so that made
me immediately consider something that I hadn't considered important before.
My list objects are HTML strings solely for the purpose of highlighting a
few words in a different color.  This appears to make the list update about
an order of magnitude more costly!  If you modify your program to produce
strings about 3 times as long, make the strings HTML with a font color tag,
and increase the list size to about 130, I think you'll get the kind of
results I cited in my first post.  (Note: by virtue of the fact that your
program did not compile with my 1.4.2 JDK, I suspect you are using an
earlier Java version and I know that HTML support has been introduced over
time so I'm not sure if you'll be able to use HTML strings).

So I have a new question -- is there a way to produce different font colors
that is much more efficient than using HTML strings in Java?

It occurred to me that you can keep your HTML and make it go at a reasonable speed (unless you run low on memory). The Swing cell renderer design is based on assumptions that construction is expensive and updating values is cheap. Clearly, even for the humble JLabel, the second is not correct when the value is HTML. So let's cache.


The approach I have taken is to have a renderer lazily create a conventional renderer for each index. The renderers are softly referenced, in a naive manner. There are lots of variations with different trade-offs. This seems to work quite well for me. It is worth noting that the classical approach is probably going to be faster to show the initial screen. And my class name is too cute for production use.

The only necessary addition to original program is:

        list.setCellRenderer(new DaisyListCellRenderer());

I think I shall add an improved version to my weblog.

Tom Hawtin

(Usual disclaimer.)

import java.lang.ref.Reference;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.swing.*;

class DaisyListCellRenderer implements ListCellRenderer {
    private final Map<
        JList,List<Reference<ListCellRenderer>>
    > caches =
        new java.util.WeakHashMap<
            JList,List<Reference<ListCellRenderer>>
        >();
    public java.awt.Component getListCellRendererComponent(
        javax.swing.JList list,
        Object value,
        int index,
        boolean isSelected,
        boolean cellHasFocus
    ) {
        // Find cache for this list.
        List<Reference<ListCellRenderer>> cache = caches.get(list);
        if (cache == null) {
            cache =
                new java.util.ArrayList<Reference<ListCellRenderer>>();
            caches.put(list, cache);
        }

        // Cache list may need extending.
        int shortfall = index+1 - cache.size();
        if (shortfall > 0) {
            assert cache.size()+shortfall == index+1;
            cache.addAll(
                Collections.<Reference<ListCellRenderer>>nCopies(
                    shortfall, null
                )
            );
        }

        // Find renderer.
        Reference<ListCellRenderer> rendererRef = cache.get(index);
        ListCellRenderer renderer =
            rendererRef==null ? null : rendererRef.get();
        if (renderer == null) {
            renderer = createRenderer(/*...*/);
            cache.set(
                index,
                new java.lang.ref.SoftReference<ListCellRenderer>(
                    renderer
                )
            );
        }

        // Forward.
        return renderer.getListCellRendererComponent(
            list, value, index, isSelected, cellHasFocus
        );
    }
    private ListCellRenderer createRenderer(/*...*/) {
        return new javax.swing.DefaultListCellRenderer();
    }
}
class LighstSpeed {
    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    swing();
                }
        });
    }
    private static final java.util.Random random =
        new java.util.Random();
    private static void swing() {
        assert java.awt.EventQueue.isDispatchThread();
        JFrame frame = new JFrame("LighstSpeed");
        final DefaultListModel model = new DefaultListModel();
        for (int ct=0; ct<50; ++ct) {
            model.addElement("<html>some data "+new java.util.Date());
        }
        final JList list = new JList(model);
        list.setCellRenderer(new DaisyListCellRenderer());
        frame.add(list);//new JScrollPane(list));//
        frame.pack();
        frame.setVisible(true);
        new javax.swing.Timer(1000, new ActionListener() {
                private boolean set;
                public void actionPerformed(ActionEvent event) {
                    model.setElementAt(
                        "<html>new data "+new java.util.Date(),
                        random.nextInt(model.size())
                    );
                }
        }).start();
    }
}
--
Unemployed English Java programmer
http://jroller.com/page/tackline/
.



Relevant Pages

  • [Full-Disclosure] Que es mas macho, SCRIPTES o TABLESPOON?
    ... Express renders plain text messages. ... HTML, ... separate plain text renderer, but use its HTML renderer instead, by converting ... disabling the HTML encode filtering. ...
    (Full-Disclosure)
  • Re: Converting a userspecific VCL-component to an ActiveX-control
    ... I will write a standard windows desktop application. ... HTML. ... This control will be placed on a window. ... Also my approach allows (if the renderer supports it, ...
    (comp.lang.pascal.delphi.misc)
  • Re: Html Rendering in Winforms
    ... not believe you will be able to create a custom browser without a very huge ... So I wonder what is your need for developping a custom html renderer ... ... I am facing a problem with the rendering of html into a windows ...
    (microsoft.public.dotnet.framework)
  • Re: Best way to dump HTML strings to a page in ASP.Net?
    ... of HTML as strings into a string builder. ... HTML as text into a string builder. ... longer work, this only happens with a high number of strings being ...
    (microsoft.public.dotnet.framework.aspnet)
  • Re: Another Drop List question
    ... If your database field is set to not allow zero-length strings, ... > ASP code and HTML and for me, it makes it easier to line up my quotes. ...
    (microsoft.public.inetserver.asp.general)